Панель расширенного текстового журнала Java для большого вывода

Mathematica поставляется с простой java-программой, которая позволяет проверять связь между интерфейсом и ядром. Он назывался LinkSnooper, и в целом он работает довольно хорошо. Похоже на это

enter image description here

Я думаю, что я могу улучшить поведение и удобство использования программы в некоторой степени, но для этого мне нужно переопределить некоторые части. Одна фундаментальная часть, которая мне нужна, - это текстовая панель, которая обладает следующими свойствами:

  • он может получать много данных, и, вероятно, он должен использовать быстрый кольцевой буфер, так что первые строки журнала удаляются, когда данные растут слишком сильно. Другая возможность заключается в том, что он автоматически начинает записывать данные на диск и, возможно, перезагружает его, когда пользователь прокручивается, чтобы увидеть первые записи.
  • он должен иметь возможность обрабатывать цветной текст. Я планирую использовать простой маркер (данные журнала - фактически реальный синтаксис Mathematica) на каждой прибывающей строке, чтобы упростить чтение.
  • он не должен быть доступен для записи. Это нормально, если текстовое окно доступно только для чтения.

Вопрос: Что-то вроде этого уже существует? В настоящее время LinkSnooper использует JTextArea под ним, и перед тем, как я начну писать свою собственную версию, я хотел спросить, сделал ли это уже это.

Edit:

То, что я планировал сделать, это использовать некоторую платформу Logger, потому что мне кажется естественным, что эти библиотеки должны иметь возможность обрабатывать множество данных. Кроме того, они часто предоставляют интерфейсы для форматирования сообщений, и вы можете определить разные обработчики, которые могут выполнять различные сообщения. Я надеялся, что кто-то уже объединил это с аккуратно рабочим текстовым окном, которое может обрабатывать большой вывод.

Ответ 1

Как отметил Саймон, я бы предложил использовать JavaFX для этой задачи.

Если вам просто нужно отображать большие объемы данных журнала без расширенной подсветки (подсветка диапазона подстроки), ListView является для вас компонентом.

Он использует виртуализированный контейнер макета, поэтому на самом деле отображаются только те ячейки, которые находятся в видимой области видового экрана. Это позволяет использовать ленивую загрузку, переработку клеток и т.д. ListView использует ObservableList как свою DataStructure. Подобно EMF EList, ObservableList автоматически уведомляет ListView об изменениях содержащихся в нем данных.

Существует несколько методов factory для создания ObservableList через FXCollections, даже позволяя обернуть существующий List (например, RingBuffer).

Если вам нужна расширенная подсветка, RichTextFX, вероятно, это решение, поскольку оно позволяет детализировать стиль содержащегося в нем текста. RichTextFX также использует виртуализованный макет.


Изменить # 2

Том написал об этом в своем блоге: http://tomsondev.bestsolution.at/2014/12/27/displaying-and-editing-large-styled-texts/


Изменить # 1 Пример ListView

JavaFX отлично справляется с тем, чтобы отделить модель от представления, поэтому мы стараемся не смешивать это и создавать две вещи:

  • Класс данных (модель)
  • A 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);
            }
        }
    }
}

Это не совсем рабочий пример, осталось несколько TODO, но, надеюсь, вы получите эту идею.

Если вы хотите добавить подсветку поиска, я описал аналогичный подход для элемента управления TableView: Таблица JavaFX с выделенным текстом (ярлыки) с низкой производительностью