【问题标题】:How to set tooltip ONLY on truncated cell dynamically如何仅在截断的单元格上动态设置工具提示
【发布时间】:2020-09-17 04:00:12
【问题描述】:

我的目标是在启动时和运行时截断文本的单元格上显示工具提示,这意味着如果调整列的大小,某些工具提示可能会出现或消失。

在我的单元工厂中,我认为会有一个我可以绑定或监听的属性,并简单地将一个工具提示链接到它,但我没有找到。

这是我在cell factory 中的每个单元格上设置工具提示的代码:

public void updateItem(T item, boolean empty) {
    super.updateItem(item, empty);

    if (empty || item == null) {
        setText(null);
        setGraphic(null);
    } else {
        setText(adapter.getCellContentParser().toString(item));
        setTooltip(new Tooltip(this.getText());
    }
}

请注意,我会在网站上寻找所有可能的解决方案,例如: https://stackoverflow.com/questions/15683907/javafx-tableviews-cellvalue-is-not-enough-to-display-in-columns-it-will-be-cl#=

How to show tooltip only on those table cells which text is ellipsized (...)?

当您启动程序时它们非常好,但是在调整列大小时不起作用

我有什么遗漏吗?我觉得这种东西没有可观察的属性真的很奇怪。

【问题讨论】:

    标签: java javafx cell tablecolumn truncated


    【解决方案1】:

    这有点小技巧,但是您可以通过在执行布局后搜索单元格下方的场景图来检索单元格中的子 Text 节点,然后为工具提示创建一个绑定以检查单元格的text 与文本的文本相同。请注意,我们在这里忽略了单元格上的任何图形集,因此仅搜索显示单元格的 text 属性的 Text 节点:

    setCellFactory(tc -> new TableCell<>() {
        private Text text ;
        private Tooltip tooltip = new Tooltip() ;
    
        {
            tooltip.textProperty().bind(textProperty());
        }
    
        @Override
        protected void updateItem(String item, boolean empty) {
            super.updateItem(item, empty);
    
            if (item == null || empty) {
                setText("");
            } else {
                setText(item);
            }
        }
    
        @Override
        protected void layoutChildren() {
            super.layoutChildren();
            if (text == null) {
                text = findTextNode(this);
                bindTooltip();
            }               
        }
    
        private void bindTooltip() {
            tooltipProperty().bind(Bindings.createObjectBinding(() -> {
                if (getItem()==null) return null ;
                if (getText().equals(text.getText())) return null ;
                return tooltip ;
            }, text.textProperty(), itemProperty(), textProperty()));
        }
    
        // recursively search through child node graph to find the Text node
        private Text findTextNode(Node root) {
            // Ignore the graphic and all its child nodes:
            if (root == getGraphic()) {
                return null ;
            }
            if (root instanceof Text) {
                return (Text) root ;
            }
            if (root instanceof Parent) {
                for (Node node : ((Parent)root).getChildrenUnmodifiable()) {
                    Text text = findTextNode(node);
                    if (text != null) return text ;
                }
            }
            return null ;
        }
    });
    

    这是一个完整的工作示例:

    import java.util.Random;
    import java.util.function.Function;
    
    import javafx.application.Application;
    import javafx.beans.binding.Bindings;
    import javafx.beans.property.IntegerProperty;
    import javafx.beans.property.Property;
    import javafx.beans.property.SimpleIntegerProperty;
    import javafx.beans.property.SimpleStringProperty;
    import javafx.beans.property.StringProperty;
    import javafx.scene.Node;
    import javafx.scene.Parent;
    import javafx.scene.Scene;
    import javafx.scene.control.TableCell;
    import javafx.scene.control.TableColumn;
    import javafx.scene.control.TableView;
    import javafx.scene.control.Tooltip;
    import javafx.scene.layout.BorderPane;
    import javafx.scene.text.Text;
    import javafx.stage.Stage;
    
    /**
     * JavaFX App
     */
    public class App extends Application {
    
        @Override
        public void start(Stage stage) {
    
            var table = new TableView<Item>();
            var itemCol = column("Item", Item::nameProperty);
            var valueCol = column("Value", Item::valueProperty);
            table.getColumns().add(itemCol);
            table.getColumns().add(valueCol);
    
            itemCol.setCellFactory(tc -> new TableCell<>() {
                private Text text ;
                private Tooltip tooltip = new Tooltip() ;
    
                {
                    tooltip.textProperty().bind(textProperty());
                }
    
                @Override
                protected void updateItem(String item, boolean empty) {
                    super.updateItem(item, empty);
    
                    if (item == null || empty) {
                        setText("");
                    } else {
                        setText(item);
                    }
                }
    
                @Override
                protected void layoutChildren() {
                    super.layoutChildren();
                    if (text == null) {
                        text = findTextNode(this);
                        bindTooltip();
                    }               
                }
    
                private void bindTooltip() {
                    tooltipProperty().bind(Bindings.createObjectBinding(() -> {
                        if (getItem()==null) return null ;
                        if (getText().equals(text.getText())) return null ;
                        return tooltip ;
                    }, text.textProperty(), itemProperty(), textProperty()));
                }
    
                // recursively search through child node graph to find the Text node
                private Text findTextNode(Node root) {
                    // Ignore the graphic and all its child nodes:
                    if (root == getGraphic()) {
                        return null ;
                    }
                    if (root instanceof Text) {
                        return (Text) root ;
                    }
                    if (root instanceof Parent) {
                        for (Node node : ((Parent)root).getChildrenUnmodifiable()) {
                            Text text = findTextNode(node);
                            if (text != null) return text ;
                        }
                    }
                    return null ;
                }
            });
    
            var rng = new Random();
            for (int i = 1 ; i <= 40 ; i++) {
                table.getItems().add(new Item("Item "+i, rng.nextInt(100)));
            }
    
            var scene = new Scene(new BorderPane(table));
            stage.setScene(scene);
            stage.show();
        }
    
        public static <S,T>  TableColumn<S,T> column(String title, Function<S, Property<T>> prop) {
            TableColumn<S,T> col = new TableColumn<>(title);
            col.setCellValueFactory(cellData -> prop.apply(cellData.getValue()));
            return col ;
        }
    
        public static class Item {
            private final StringProperty name = new SimpleStringProperty();
            private final IntegerProperty value = new SimpleIntegerProperty();
            public Item(String name, int value) {
                this.name.set(name);
                this.value.set(value);
            }
    
            public final StringProperty nameProperty() {
                return name ;
            }
    
            public final IntegerProperty valueProperty() {
                return value ;
            }
        }
    
        public static void main(String[] args) {
            launch();
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-08
      • 1970-01-01
      • 2014-09-23
      • 1970-01-01
      • 2020-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多