java - 用于大输出的 Java 高级文本记录 Pane

标签 java logging textbox wolfram-mathematica

Mathematica 带有一个简单的 java 程序,可以检查前端和内核之间的通信。它叫做LinkSnooper总的来说效果很好。看起来像这样

enter image description here

我认为我可以在一定程度上改进程序的行为和可用性,但为此,我需要重新实现某些部分。我需要的一个基本部分是文本 Pane ,它具有以下属性:

  • 它可以接收大量数据,它可能应该使用快速环形缓冲区,以便在数据增长过多时删除最开始的日志行。另一种可能性是它会自动开始将数据写入磁盘,并可能在用户向上滚动以查看第一个条目时重新加载数据
  • 它应该能够处理彩色文本。我计划在每个到达的行上使用一个简单的荧光笔(日志数据实际上是真正的 Mathematica 语法)以使阅读更容易
  • 它不需要是可写的。如果文本 Pane 是只读的,那也没关系。

问题:这样的东西是否已经存在?目前,LinkSnooper 在下面使用了一个 JTextArea,在我开始编写自己的版本之前,我想问问是否有人已经这样做了。

编辑:

我计划做的是使用一些 Logger 框架,因为对我来说这些库应该能够处理大量数据是很自然的。此外,它们通常提供接口(interface)来格式化消息,您可以定义不同的处理程序来处理不同的消息。我所希望的是有人已经将它与可以处理大量输出的整洁工作的文本窗口结合起来。

最佳答案

正如 Simon 所指出的,我建议使用 JavaFX 来完成这项任务。

如果您“只是”需要显示大量日志数据而无需高级突出显示(子字符串范围突出显示),ListView是适合您的组件。

它使用了一个虚拟化的布局容器,所以实际上只有在视口(viewport)可见区域的单元格才会被渲染。这允许延迟加载、单元格回收等。 ListView 使用 ObservableList作为它的数据结构。与 EMF EList 类似,ObservableList 会自动通知 ListView 其包含的数据发生变化。

有几种工厂方法可以通过FXCollections 创建一个ObservableList。甚至允许包装现有的 List(例如 RingBuffer)。

如果您需要高级突出显示,RichTextFX可能是要寻求的解决方案,因为它允许对其包含的文本进行详细的样式设置。 RichTextFX 也使用虚拟化布局。


编辑 #2

Tom 在他的博客中写过:http://tomsondev.bestsolution.at/2014/12/27/displaying-and-editing-large-styled-texts/


编辑 #1 ListView 示例

JavaFX 在将模型与 View 分离方面做得非常好,因此我们尽量不要将其混淆,并且需要创建两件事:

  1. 一个数据类(模型)
  2. 该数据类( View )的 Cell 渲染器。

首先是数据类:

public class LogData {

    private final String logMessage;
    private List<String> highlightedFragments = null;

    public LogData(String pLogMessage) {
        logMessage = pLogMessage;
    }

    public String getLogMessage() {
        return logMessage;
    }

    public List<String> getHighlightedFragments() {
        if (highlightedFragments == null) {
            doHighlight();
        }
        return highlightedFragments;
    }

    private void doHighlight() {
        List<String> highlightedParts = Collections.emptyList(); // TODO lexer
        highlightedFragments = highlightedParts;
    }
}

有趣的是,突出显示是按需完成的,而不是在初始化时完成的。或者换句话说:词法分析器仅在单元格渲染器请求数据时执行其工作。

现在 Cell 渲染器:

ListView<LogData> listView = new ListView<>();
listView.setCellFactory(cb -> new LogDataCell(){});

public class LogDataCell extends ListCell<LogData>
{
    @Override
    protected void updateItem(LogData item, boolean empty) {
        super.updateItem(item, empty);

        if(empty || item == null) {
            setText(null);
            setGraphic(null);
        }
        else {
            List<String> fragments = item.getHighlightedFragments();
            if(fragments == null || fragments.isEmpty()) {
                setText(item.getLogMessage());
                setGraphic(null);
            }
            else {
                TextFlow textFlow = null; //TODO
                setText(null);
                setGraphic(textFlow);
            }
        }
    }
}

这不是一个完整的示例,还有几个待办事项,但希望您能理解。

如果你想添加搜索突出显示,我在此处描述了 TableView 控件元素的类似方法:JavaFX Table with highlighted text (Labels) with poor performance

关于java - 用于大输出的 Java 高级文本记录 Pane ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27414689/

相关文章:

java - 如何使用 Log4j 和 Storm Framework 将日志写入文件?

ruby-on-rails - 如何使 Rails.logger.debug 打印哈希更具可读性

java - Spring 启动: Set hibernate sequence globally

java - 如何在 fragment 内创建自定义 ListView

Java - 需要一个日志包来记录堆栈跟踪

c# - WPF 中文本框的依赖于焦点的文本更改

asp.net - 将所有文本框(输入字段)的背景颜色设置为透明

c# - 为什么我无法在文本框中按 CTRL+A 或 CTRL+Backspace?

java - 使用同名类的类

java - Java 中的代码注入(inject)/程序集内联?