【问题标题】:JavaFX - TableColumn graphic higher than other rowsJavaFX - TableColumn 图形高于其他行
【发布时间】:2017-01-07 13:31:20
【问题描述】:

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

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

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的行是图形。所有其他行都包含文本。我怎样才能让包含图形的行具有相同的高度?

【问题讨论】:

    标签: java javafx graphic tablecolumn


    【解决方案1】:

    只需将首选高度设置为 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 + TextFlow 并在另一种情况下使用text 属性会产生不一致的外观。 (请看一下屏幕截图中文本的最左边部分!那些没有正确对齐)。
    • 使用Cells 的全部目的是重用节点以防止不必要的节点创建。您通过重新创建TextFlow 等来破坏这种尝试。在updateItem 方法中,而不是重用这些节点。
    • 正则表达式不需要以^ 开头,因为matches 已经确保整个输入匹配。此外,用于split 的分隔符在正则表达式中没有完全等价的。除了,还有其他空格字符,比如tab。只需检查以下代码的作用...

      System.out.println("a\tb".matches(".\\s."));
      System.out.println("a\tb".split(" ")[1]);
      

      您还可以使用Pattern+Matcher 和捕获组在同一步骤中解析输入并匹配它。这样你也没有上面提到的问题。

    【讨论】:

    • 感谢您的回答。我尝试了您的解决方案,但 +2 没有变成红色:/
    猜你喜欢
    • 2013-11-09
    • 2014-05-09
    • 1970-01-01
    • 1970-01-01
    • 2019-05-27
    • 2013-11-25
    • 2014-12-23
    • 2018-07-21
    • 1970-01-01
    相关资源
    最近更新 更多