3

我想突出显示在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 建议的那样,在 a 中使用多个LabelsHBox一个好主意,因为每个“标签”都可以有自己的背景颜色,您可以根据需要Labels在 a 中使用尽可能多的内容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;
    }
});
4

2 回答 2

3

仔细阅读您的问题后,我认为我们可以按如下方式恢复:

  • TableColumn 中相当长的文本
  • 用户应该能够过滤此文本
  • 与当前搜索词匹配的每个文本片段都将被突出显示。

现在你有两个选择:

  1. 创建一个 HBox 并添加包含文本片段的标签。标签扩展区域,因此可能具有背景颜色。
  2. 使用 TextFlow 并将文本添加为​​文本片段。在那里你可以“只”改变前景色。

啊,在我忘记之前:要禁用 TextFlow 文本换行,您不能调用textModule.setWrappingWidth(Double.MAX_VALUE);,而是textModule.setPrefWidth(Double.MAX_VALUE);

还有一个提示:尽量回收利用。在每次更新时重新创建整个 TextFlow 并不是一个好主意(而是将其作为成员变量存储在单元格中)。

于 2014-11-13T19:16:27.870 回答
3

根据thisText没有背景样式属性,所以这就是为什么改变-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。

现在的挑战是在你的方法中调整它......

于 2014-11-13T13:40:45.793 回答