带有突出显示文本的JavaFX TableView

时间:2014-11-13 10:35:52

标签: java javafx tableview textflow

我想要突出显示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;
    }
});

不幸的是背景突出显示不起作用,我有奇怪的换行符,如图所示。该文本不包含任何换行符。

scrennshot oft table

(对不起图片质量,这是一个真实的截图:))

感谢任何帮助。

解决方案
正如@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;
    }
});

2 个答案:

答案 0 :(得分:3)

根据thisText没有背景样式属性,这就是为什么更改-fx-text-background-color不会对其产生任何影响的原因。

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

如果你真的需要突出显示,其他可能的解决方案可能是设置文本流的背景,找到文本的边界,并设置适当的插图。

这是我使用Scenic Builder和一些css快速完成的一个例子:

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

Highlighted text

我已经考虑了文本流的宽度(510)以及使用本地边界的不同文本节点的宽度:200,170.7和129.所以右边插图是510-200-170.7 = 139.3并且左侧插图是从第一个节点宽度200给出的。

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

答案 1 :(得分:3)

在仔细阅读您的问题之后,我想我们可以按照以下步骤恢复:

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

现在您有两个选择:

  1. 创建一个HBox并添加包含文本片段的标签。标签扩展了区域,因此可能具有背景颜色。
  2. 使用TextFlow并将文本添加为​​文本片段。在那里你可以“只”改变前景色。
  3. 啊,在我忘记之前:要禁用TextFlow文字换行,您不得拨打textModule.setWrappingWidth(Double.MAX_VALUE);,而是textModule.setPrefWidth(Double.MAX_VALUE);

    另一个暗示:尝试尽可能多地回收。在每次更新时重新创建整个TextFlow并不是一个好主意(而是将其作为成员变量存储在单元格中)。