我想要突出显示JavaFX
TableView
中显示的部分文字。直到现在我在Text
个对象中使用TextFlow
个对象。要突出显示文本中的特定部分,我使用标签剪切部分文本(javafx.scene.text
个对象)以突出显示或不突出显示以下代码。
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;
}
});
不幸的是背景突出显示不起作用,我有奇怪的换行符,如图所示。该文本不包含任何换行符。
(对不起图片质量,这是一个真实的截图:))
感谢任何帮助。
解决方案
正如@eckig建议的那样,在Labels
中使用多个HBox
是一个好主意,因为每个&#39;标签&#39;可以有自己的背景颜色,您可以根据需要在Labels
中使用尽可能多的HBox
:
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;
}
});
答案 0 :(得分:3)
根据this,Text
没有背景样式属性,这就是为什么更改-fx-text-background-color
不会对其产生任何影响的原因。
一种可能的解决方法是将此文本节点包装在HBox
中,您可以在其中轻松将其背景设置为黄色。但这有几个缺点,例如文本流失失了管理内容的能力。
如果你真的需要突出显示,其他可能的解决方案可能是设置文本流的背景,找到文本的边界,并设置适当的插图。
这是我使用Scenic Builder和一些css快速完成的一个例子:
.textflow {
-fx-background-color: yellow;
-fx-background-insets: 2 139.3 10 200;
}
我已经考虑了文本流的宽度(510)以及使用本地边界的不同文本节点的宽度:200,170.7和129.所以右边插图是510-200-170.7 = 139.3并且左侧插图是从第一个节点宽度200给出的。
现在挑战是在你的方法中适应这个......
答案 1 :(得分:3)
在仔细阅读您的问题之后,我想我们可以按照以下步骤恢复:
现在您有两个选择:
啊,在我忘记之前:要禁用TextFlow文字换行,您不得拨打textModule.setWrappingWidth(Double.MAX_VALUE);
,而是textModule.setPrefWidth(Double.MAX_VALUE);
另一个暗示:尝试尽可能多地回收。在每次更新时重新创建整个TextFlow并不是一个好主意(而是将其作为成员变量存储在单元格中)。