JavaFX - TableColumn 图形高于其他行

JavaFX - TableColumn graphic higher than other rows

我正在使用 JavaFX 制作 table。每行都有文字。一行有一个图形,因为该单元格的文本有多种颜色。

代码仅在特定条件为真时适用(该部分有效):

departTimeCol.setCellFactory(column -> new TableCell<Ride, String>() {
            @Override
            protected void updateItem(String item, boolean empty) {
                super.updateItem(item, empty);

                setText(item);

                if(item != null && ! empty){
                    if(item.matches("^([0-9]|0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]\s\+[\d]")) {
                        Text timeText = new Text(item.split(" ")[0].trim() + " ");
                        Text delayText = new Text(item.split(" ")[1].trim());

                        delayText.setFill(Color.RED);

                        TextFlow flow = new TextFlow(timeText, delayText);

                        setText(null);
                        setGraphic(flow);

                    }
                }
            }
        });

结果是:

红色+2的那一行是图形。所有其他行都包含文本。我怎样才能给包含图形的行相同的高度?

只需将首选高度设置为 0 即可使高度正好适合存储文本的高度。

Pattern pattern = Pattern.compile("((?:[0-9]|[01][0-9]|2[0-3]):[0-5][0-9]\s)(\+\d)");

departTimeCol.setCellFactory(column -> new TableCell<Ride, String>() {

    private final Text timeText = new Text();
    private final Text delayText = new Text();
    private final TextFlow flow = new TextFlow(timeText, delayText);

    {
        delayText.setFill(Color.RED);
        flow.setPrefHeight(0);
        flow.heightProperty().addListener((observable, oldValue, newValue) -> {
            this.setMinHeight(newValue.doubleValue() + 4);
        });
        flow.setMinHeight(Region.USE_COMPUTED_SIZE);
        setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
        setGraphic(flow);
    }

    @Override
    protected void updateItem(String item, boolean empty) {
        super.updateItem(item, empty);

        if (empty || item == null) {
            timeText.setText("");
            delayText.setText("");
            delayText.setVisible(false);
        } else {
            Matcher m = pattern.matcher(item);
            if (m.matches()) {
                timeText.setText(m.group(1));
                delayText.setText(m.group(2));
                delayText.setVisible(true);
            } else {
                timeText.setText(item);
                delayText.setText("");
                delayText.setVisible(false);
            }
        }

    }
});

请注意,代码中还有一些内容需要修复:

  • 您永远不会将图形设置回 null,即使 String 不再匹配正则表达式或单元格变为空。这意味着您可以使 TableCell 进入 text 属性 不为空且 graphic 包含 TextFlow 的状态。 注意:无论调用 updateItem 方法的频率如何,并且与传递的参数无关,始终确保单元格的外观状态是正确的。
  • 在一种情况下使用 graphic + a TextFlow 而在另一种情况下使用 text 属性 会产生不一致的外观。 (只要看看屏幕截图中文本最左边的部分!它们没有正确对齐)。
  • 使用 Cells 的全部目的是重用节点以防止不必要的节点创建。您通过重新创建 TextFlow 等来破坏此尝试。在 updateItem 方法中而不是重复使用这些节点。
  • 正则表达式不需要以 ^ 开头,因为 matches 已经确保整个输入匹配。此外,用于 split 的分隔符在正则表达式中没有完全等效的分隔符。除了 </code>,还有其他 space 个字符,例如制表符。只需检查以下代码的作用...</p> <pre><code>System.out.println("a\tb".matches(".\s.")); System.out.println("a\tb".split(" ")[1]);

    您还可以使用 Pattern+Matcher 和捕获组在同一步骤中解析输入并匹配它。这样你也不会出现上述问题