Ответ 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 с выделенным текстом (ярлыки) с низкой производительностью