带有突出显示文本的JavaFX TableView [英] JavaFX TableView with highlighted text
问题描述
我想要突出显示 JavaFX
TableView
中显示的文本部分。直到现在我在 TextFlow
对象中使用 Text
对象。要突出显示文本中的特定部分,我使用标签剪切部分文本( javafx.scene.text
对象)以突出显示或不突出显示以下代码。
I want to highlight parts of text displayed in a JavaFX
TableView
. Till now i'm using Text
objects in TextFlow
objects. To highlight specific parts in a text i am using tags to cut the text in parts (javafx.scene.text
objects) to highlight or not to highlight with the following code.
col3.setCellValueFactory(new PropertyValueFactory<RegexMatch, String>("text"));
col3.setCellFactory(new Callback<TableColumn, TableCell>() {
@Override
public TableCell call(TableColumn param) {
TableCell cell = new TableCell() {
@Override
protected void updateItem(Object text, boolean empty) {
if (text != null && text instanceof String) {
String str = (String) text;
TextFlow flow = new TextFlow();
if (txtSearchField.getText().length() > 3 && str.contains(HIGHLIGHT_START)) {
// Something to highlight
flow.getChildren().clear();
while (str.contains(HIGHLIGHT_START)) {
// First part
Text starttext = new Text(str.substring(0, str.indexOf(HIGHLIGHT_START)));
starttext.setWrappingWidth(Double.MAX_VALUE);
flow.getChildren().add(starttext);
str = str.substring(str.indexOf(HIGHLIGHT_START) + HIGHLIGHT_START.length(), str.length());
// Part to highlight
Text highlightedText = new Text(str.substring(0, str.indexOf(HIGHLIGHT_END)));
highlightedText.setStyle("-fx-text-background-color: yellow;");
highlightedText.setFill(Color.BLUE);
highlightedText.setWrappingWidth(Double.MAX_VALUE);
flow.getChildren().add(highlightedText);
// Last part
str = str.substring(str.indexOf(HIGHLIGHT_END) + HIGHLIGHT_END.length(), str.length());
if (!str.contains(HIGHLIGHT_START)) {
Text endtext = new Text(str);
endtext.setWrappingWidth(Double.MAX_VALUE);
flow.getChildren().add(endtext);
}
}
}else if (txtSearchField.getText().length() < 1) {
// Remove former highlightings and show simple text
str = str.replaceAll(HIGHLIGHT_START, "");
str = str.replaceAll(HIGHLIGHT_END, "");
flow.getChildren().clear();
Text textModule = new Text(str);
textModule.setWrappingWidth(Double.MAX_VALUE);
flow.getChildren().add(textModule);
} else {
// show simple text
flow.getChildren().clear();
Text textModule = new Text(str);
textModule.setWrappingWidth(Double.MAX_VALUE);
flow.getChildren().add(textModule);
}
flow.setPrefHeight(bigIcons ? BIG_SIZE : SMALL_SIZE);
setGraphic(flow);
}
}
};
return cell;
}
});
不幸的是背景突出显示不起作用,我有奇怪的换行符,如图所示。该文本不包含任何换行符。
Unfortunately the background highlighting does not work and i have strange linebreaks as shown in the picture. The text does not contain any linebreaks.
(对不起图片质量,它是一个真实的截图:))
(Sorry for the picture quality, its a real screenshot :))
任何帮助表示赞赏。
解决方案
正如@eckig建议的那样,使用多个标签
在 HBox
中是一个好主意,因为每个'Label'都有自己的背景颜色,你可以使用尽可能多的标签
根据需要在 HBox
中排队:
Solution
As @eckig suggested, using multiple Labels
in a HBox
is an good idea, because each 'Label' can have its own background color and you can use as much Labels
in line in a HBox
as needed:
col3.setCellValueFactory(new PropertyValueFactory<RegexMatch, String("excerptLineTable"));
col3.setCellFactory(new Callback<TableColumn, TableCell>() {
@Override
public TableCell call(TableColumn param) {
TableCell cell = new TableCell() {
@Override
protected void updateItem(Object text, boolean empty) {
if (text != null && text instanceof String) {
HBox hbox = new HBox();
String str = (String) text;
if (txtSearchField.getText().length() > 3 && str.contains(HIGHLIGHT_START)) {
// Something to highlight
hbox.getChildren().clear();
while (str.contains(HIGHLIGHT_START)) {
// First part
Label label = new Label(str.substring(0, str.indexOf(HIGHLIGHT_START)));
hbox.getChildren().add(label);
str = str.substring(str.indexOf(HIGHLIGHT_START) + HIGHLIGHT_START.length(), str.length());
// Part to highlight
Label label2 = new Label(str.substring(0, str.indexOf(HIGHLIGHT_END)));
label2.setStyle("-fx-background-color: blue;");
hbox.getChildren().add(label2);
// Last part
str = str.substring(str.indexOf(HIGHLIGHT_END) + HIGHLIGHT_END.length(), str.length());
if (!str.contains(HIGHLIGHT_START)) {
Label label3 = new Label(str);
hbox.getChildren().add(label3);
}
}
} else if (txtSearchField.getText().length() < 1) {
// Remove former highlightings and show simple text
str = str.replaceAll(HIGHLIGHT_START, "");
str = str.replaceAll(HIGHLIGHT_END, "");
hbox.getChildren().clear();
Label label = new Label(str);
hbox.getChildren().add(label);
} else {
// show simple text
hbox.getChildren().clear();
Label label = new Label(str);
hbox.getChildren().add(label);
}
setGraphic(hbox);
}
}
};
return cell;
}
});
推荐答案
双读你的问题之后我想我们可以恢复这个如下所示:
After double reading your problem I think we can resume this as follows:
- TableColumn中相当长的文本
- 用户应该能够过滤
- 每个与当前搜索词匹配的文本片段都要突出显示。
现在您有两个选择:
- 创建一个HBox并添加包含文本片段的标签。标签扩展区域,因此可能具有背景颜色。
- 使用TextFlow并将文本添加为文本片段。在那里你可以只改变前景色。
啊,在我忘记之前:要禁用TextFlow文本换行,你不能调用 textModule.setWrappingWidth(Double.MAX_VALUE);
但是 textModule.setPrefWidth(Double.MAX_VALUE);
Ah and before I forget: To disable TextFlow text wrapping you must not call textModule.setWrappingWidth(Double.MAX_VALUE);
but instead textModule.setPrefWidth(Double.MAX_VALUE);
另一个提示:尝试尽可能多地回收。在每次更新时重新创建整个TextFlow并不是一个好主意(而是将其作为成员变量存储在单元格中)。
And another hint: Try to recycle as much as possible. Recreating the whole TextFlow on each update is not really a good idea (instead store it as member variable in the cell).
这篇关于带有突出显示文本的JavaFX TableView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!