用于大输出的Java高级文本日志记录窗格

hal*_*tan 12 java logging textbox wolfram-mathematica

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

在此输入图像描述

我想我可以在一定程度上改进程序的行为和可用性,但为了做到这一点,我需要重新实现一些部分.我需要的一个基本部分是文本窗格,它具有以下属性:

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

问题:这样的事情已经存在吗?目前,LinkSnooper使用底层JTextArea,在我开始编写我自己的版本之前,我想问一下是否有人已经这样做了.

编辑:

我打算做的是使用一些Logger框架,因为我觉得这些库应该能够处理大量数据.此外,它们通常提供格式化消息的接口,您可以定义可以处理不同消息的不同处理程序.我所希望的是,有人已经将它与一个可以处理大量输出的整洁工作文本窗口相结合.

eck*_*kig 6

正如西蒙指出的那样,我建议使用JavaFX来完成这项任务.

如果您"只是"需要显示大量的日志数据而没有高级突出显示(子字符串范围突出显示),ListView那么该组件就是您的选择.

它使用虚拟化布局容器,因此实际只渲染视口可见区域中的单元格.这允许延迟加载,单元回收等.ListView使用an ObservableList作为其DataStructure.与EMF类似EList,它会ObservableList自动通知ListView其包含数据中的更改.

有几种工厂方法FXCollections甚至允许包装现有的List(例如RingBuffer)来创建ObservableList .

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


编辑#2

汤姆在他的博客中写到了这一点:http://tomsondev.bestsolution.at/2014/12/27/displaying-and-editing-large-styled-texts/


编辑#1 ListView示例

JavaFX在将模型与视图分离方面做得非常出色,所以我们尽量不要混淆它,需要创建两件事:

  1. 数据类(模型)
  2. 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

现在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);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这不是一个完全有效的例子,还有几个TODO,但希望你能得到这个想法.

如果你想添加搜索突出显示,我在这里描述了一个类似于TableView控件元素的方法:带有突出显示文本(标签)的JavaFX表,性能不佳