当前位置: 首页 > 知识库问答 >
问题:

带高亮显示文本的JavaFX TableView

百里弘致
2023-03-14

我想突出显示JavaFX中显示的部分文本。到目前为止,我正在使用TextFlow对象中的Text对象。为了突出显示文本中的特定部分,我使用标记将文本切割成部分(javafx.scene.textobjects),以突出显示或不突出显示以下代码。

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所建议的,在HBox中使用多个标签是一个好主意,因为每个“标签”都有自己的背景色,您可以根据需要在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;
    }
});

共有2个答案

锺离马鲁
2023-03-14

据此,Text没有背景样式属性,这就是为什么更改-fx-text-background-Color对其没有任何影响。

一种可能的解决方法是将此文本节点包装在HBox中,您可以轻松地将其背景设置为黄色。但这有几个缺点,例如textflow失去了管理内容的能力。

如果确实需要突出显示,其他可能的解决方案可以是通过查找文本的边界并设置适当的插入来设置文本流的背景样式。

这是一个我用场景构建器和一些css快速完成的示例:

.textflow {
    -fx-background-color: yellow;
    -fx-background-insets: 2 139.3 10 200;
}

我已经考虑了textflow的宽度(510)和使用局部边界的不同文本节点的宽度:200、170.7和129。因此,右插图为510-200-170.7=139.3,左插图由第一个节点宽度200给出。

现在的挑战是在你的方法中适应这个...

阎庆
2023-03-14

在仔细阅读您的问题后,我认为我们可以继续如下操作:

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

现在您有两个选择:

  1. 创建HBox并添加包含文本片段的标签。标签延伸区域,因此可能具有背景色

啊,在我忘记之前:要禁用TextFlow文本包装,您不能调用textModule。setWrappingWidth(Double.MAX\u值) 但改为<代码>文本模块。setPrefWidth(双倍最大值)

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

 类似资料:
  • 我正在使用mouseup事件来触发一个函数,该函数突出显示文本,并用跨度包围突出显示的文本(堆栈溢出函数): 我遇到的主要问题是,只要包含,文本只会在高亮显示尝试中高亮显示约20%(否则高亮显示会立即消失)。我尝试添加一个setTimeout,在1s内不调用surroundContent。我还尝试删除remove()语句,但仍然没有效果。 你知道为什么会这样吗?

  • 对于我使用的语法高亮Highlight.js自定义主题. 自动语言检测已关闭,因此您可能希望指定您使用的编程语言 ```rust fn main() { // Some code } ``` 与主题的其余部分一样,用于语法突出显示的css,可以使用您自己的文件覆盖. highlight.js 通常你不应该覆盖这个文件,除非你想使用更新的版本. highlight.css highlight

  • 在页面上有两个框 这两个框是一个数组的数据类似与 [ 这种格式的我去循环然后画的框 想要实现无论点击这两行哪行 这两行都高亮显示 用过根据id查找页面元素,但id只能返回第一个所以只能第一个高亮

  • 我目前使用的是原生JS,我正在尝试在contenteditable div中构建突出显示文本功能。我已经成功构建了突出显示功能,但当我想使用单个按钮在突出显示文本和非突出显示文本之间切换时,遇到了一个问题。所以我通过 并且我正在使用作为范围对象函数的周围内容包装选定的文本。 但是现在,当我试图取消突出显示的文本的某些部分和纯文本的某些部分时,自然行为应该取消突出显示的文本并突出显示纯文本。为了实现

  • 我试图在一个tkinter文本小部件中突出显示文本的一部分。如果您知道要突出显示的文本的line.col索引,这很容易做到。但是,我想突出显示的文本部分的索引是典型的字符串索引格式(整数),而不是tkinter要求的line.col索引格式。下面是一些简化的代码,显示了我正在努力实现的目标: 我有三种不同的突出显示文本定义。第一个(highlight_text_index)只使用我要突出显示的文本

  • 我是SWT/JFace技术的新手,我发现了一个让我发疯的问题。在Eclipse RCP应用程序中,我有一个视图,其中放置了一个带有JFace TreeViewer的SWT树,该树通过标签提供程序提供标签和图标。根据客户要求,树的背景颜色为深蓝色,字体颜色为白色。当节点被选中时,这种颜色的组合导致节点文本的可视化效果不佳,文本不适合树区域,我们将鼠标指针放在节点上。不知何故出现了“本地高亮显示”。这