5

我有一个TreeTableView每个节点都有一个图标的地方。当我展开树时,一切正常,但是当我折叠树时,不再可见项目的图标被留下。

行和文本被删除,但图标保持“自由浮动”。在屏幕截图中,您可以看到TreeTableView两次,一次是使用正确的文本展开,一次是折叠并仅显示剩余的图标。

带有正确展开的 TreeTableView 和损坏的折叠的屏幕截图

上面的屏幕截图是从以下最小示例创建的(您只需要添加自己的icon.png):

import javafx.application.Application;
import javafx.beans.property.ReadOnlyStringWrapper;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.TreeTableColumn;
import javafx.scene.control.TreeTableColumn.CellDataFeatures;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeTableView;
import javafx.stage.Stage;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;

public class TreeTableViewSample extends Application {
    private static final Image icon = new Image(TreeTableViewSample.class.getResourceAsStream("icon.png"));

    public static void main(String[] args) {
        Application.launch(args);
    }

    @Override
    public void start(Stage stage) {
        stage.setTitle("Tree Table View Samples");
        final Scene scene = new Scene(new Group(), 200, 400);
        Group sceneRoot = (Group)scene.getRoot();  

        //Creating tree items
        final TreeItem<String> childNode1 = new TreeItem<>("Child Node 1", new ImageView(icon));
        final TreeItem<String> childNode2 = new TreeItem<>("Child Node 2", new ImageView(icon));
        final TreeItem<String> childNode3 = new TreeItem<>("Child Node 3", new ImageView(icon));

        //Creating the root element
        final TreeItem<String> root = new TreeItem<>("Root node", new ImageView(icon));
        root.setExpanded(true);   

        //Adding tree items to the root
        root.getChildren().setAll(childNode1, childNode2, childNode3);        

        //Creating a column
        TreeTableColumn<String,String> column = new TreeTableColumn<>("Column");
        column.setPrefWidth(150);   

        //Defining cell content
        column.setCellValueFactory((CellDataFeatures<String, String> p) -> 
            new ReadOnlyStringWrapper(p.getValue().getValue()));  

        //Creating a tree table view
        final TreeTableView<String> treeTableView = new TreeTableView<>(root);
        treeTableView.getColumns().add(column);
        treeTableView.setPrefWidth(152);
        treeTableView.setShowRoot(true);             
        sceneRoot.getChildren().add(treeTableView);
        stage.setScene(scene);
        stage.show();
    }     
}

我已经在 Linux 上使用 OpenJDK 和 Oracle Java 8u92 并在 Windows 上使用 Oracle Java 8u92 进行了尝试。

4

1 回答 1

9

那是一个错误。它适用于我的旧 1.8.0_71,但正如您使用 1.8.0_92 所描述的那样失败。

恕我直言,无论如何定义图形TreeItem都是胡说八道:它TreeItem是树模型的一部分,应该只包含数据,而不是数据如何呈现的细节。图形应该是单元格的属性,并且应该在单元格工厂中定义。以下解决方法按预期工作:

import javafx.application.Application;
import javafx.beans.property.ReadOnlyStringWrapper;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeTableCell;
import javafx.scene.control.TreeTableColumn;
import javafx.scene.control.TreeTableColumn.CellDataFeatures;
import javafx.scene.control.TreeTableView;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class TreeTableViewSample extends Application {
    private static final Image icon = new Rectangle(12, 12, Color.CORNFLOWERBLUE).snapshot(null, null);

    public static void main(String[] args) {
        Application.launch(args);
    }

    @Override
    public void start(Stage stage) {
        stage.setTitle("Tree Table View Samples");
        final Scene scene = new Scene(new Group(), 200, 400);
        Group sceneRoot = (Group)scene.getRoot();  

        //Creating tree items
//        final TreeItem<String> childNode1 = new TreeItem<>("Child Node 1", new ImageView(icon));
//        final TreeItem<String> childNode2 = new TreeItem<>("Child Node 2", new ImageView(icon));
//        final TreeItem<String> childNode3 = new TreeItem<>("Child Node 3", new ImageView(icon));

        final TreeItem<String> childNode1 = new TreeItem<>("Child Node 1");
        final TreeItem<String> childNode2 = new TreeItem<>("Child Node 2");
        final TreeItem<String> childNode3 = new TreeItem<>("Child Node 3");

        //Creating the root element
//        final TreeItem<String> root = new TreeItem<>("Root node", new ImageView(icon));
        final TreeItem<String> root = new TreeItem<>("Root node");
        root.setExpanded(true);   

        //Adding tree items to the root
        root.getChildren().setAll(childNode1, childNode2, childNode3);        

        //Creating a column
        TreeTableColumn<String,String> column = new TreeTableColumn<>("Column");
        column.setPrefWidth(150);   

        //Defining cell content
        column.setCellValueFactory((CellDataFeatures<String, String> p) -> 
            new ReadOnlyStringWrapper(p.getValue().getValue()));  


        // cell factory to display graphic:
        column.setCellFactory(ttc -> new TreeTableCell<String, String>() {

            private final ImageView graphic = new ImageView(icon);

            @Override
            protected void updateItem(String item, boolean empty) {
                super.updateItem(item, empty);
                setText(empty ? null : item);
                setGraphic(empty ? null : graphic);
            }
        });

        //Creating a tree table view
        final TreeTableView<String> treeTableView = new TreeTableView<>(root);
        treeTableView.getColumns().add(column);
        treeTableView.setPrefWidth(152);
        treeTableView.setShowRoot(true);             
        sceneRoot.getChildren().add(treeTableView);
        stage.setScene(scene);
        stage.show();
    }     
}
于 2016-04-28T14:23:56.007 回答