首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >TreeTableView:显示不同的数据类型

TreeTableView:显示不同的数据类型
EN

Stack Overflow用户
提问于 2016-09-20 14:36:37
回答 1查看 1.7K关注 0票数 0

我有一个Factory类,它包含一个员工列表。我想使用TreeTableView来显示Factory数据。显示Factory的名称和大小是非常好的,但是我不知道如何显示员工的名字!

代码语言:javascript
复制
public class Factory {
       private String name;
       private double size;
       private List<Employee> employees;

       public Factory(name, size){this.name=name; this.size=size} 

       // Getters & setters

    }

我希望有以下输出:

有可能关闭工厂。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-09-20 19:19:42

TreeViewTreeTableView中,树中的所有节点都必须是相同类型的。这使得你想要的那种设计(这是非常自然的)有点痛苦。基本上,您必须使TreeViewTreeTableView的类型成为树中所有类型行中最具体的超类:也就是说,在这种情况下,TreeTableView的类型需要是EmployeeFactory的超类。然后,列上的单元格值工厂必须键入测试行对象,以确定返回的值。

不寻常的是,有一个对象模型,其中这些继承与继承相关,而不是作为Object的子类,所以这里可能需要一个TreeTableView<Object>

因此,粗略地说(如果您使用的是普通的旧JavaBean样式,而不是推荐的JavaFX性质),您可以定义如下

代码语言:javascript
复制
TreeTableView<Object> treeTable = new TreeTableView<>();
treeTable.setShowRoot(false);

TreeTableColumn<Object, String> nameColumn = new TreeTableColumn<>("Name");
nameColumn.setCellValueFactory(cellData -> {
    TreeItem<Object> rowItem = cellData.getValue();
    if (rowItem != null && (rowItem.getValue() instanceof Factory)) {
        Factory f = (Factory) rowItem.getValue() ;
        return new SimpleStringProperty(f.getName());
    } else {
        return new SimpleStringProperty("");
    }
});

TreeTableColumn<Object, Number> sizeColumn = new TreeTableColumn<>("Size");
sizeColumn.setCellValueFactory(cellData -> {
    TreeItem<Object> rowItem = cellData.getValue();
    if (rowItem != null && (rowItem.getValue() instanceof Factory)) {
        Factory f = (Factory) rowItem.getValue() ;
        return new SimpleObjectProperty<Number>(Double.valueOf(f.getSize()));
    } else {
        return new SimpleObjectProperty<Number>(null);
    }
});

TreeTableColumn<Object, String> employeeColumn = new TreeTableColumn<>("Employee");
employeeColumn.setCellValueFactory(cellData -> {
    TreeItem<Object> rowItem = cellData.getValue();
    if (rowItem != null && (rowItem.getValue() instanceof Employee)) {
        Employee emp = (Employee) rowItem.getValue() ;
        return new SimpleStringProperty(emp.getName());
    } else {
        return new SimpleStringProperty("");
    }
});

treeTable.getColumns().addAll(nameColumn, sizeColumn, employeeColumn);

当然,你用

代码语言:javascript
复制
// fully initialized list of factories, with employee lists initialized:
List<Factory> factories = ... ;

TreeItem<Object> root = new TreeItem<>(null);
for (Factory factory : factories) {
    TreeItem<Object> factoryItem = new TreeItem<>(factory);
    root.getChildren().add(factoryItem);
    for (Employee emp : factory.getEmployees()) {
        TreeItem<Object> employeeItem = new TreeItem<>(emp);
        factoryItem.getChildren().add(employeeItem);
    }
}
treeTable.setRoot(root);

下面是一个使用以下内容的简单SSCCE:

代码语言:javascript
复制
import java.util.ArrayList;
import java.util.List;

import javafx.application.Application;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.scene.Scene;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeTableColumn;
import javafx.scene.control.TreeTableView;
import javafx.stage.Stage;

public class TreeTableExample extends Application {

    @Override
    public void start(Stage primaryStage) {
        TreeTableView<Object> treeTable = new TreeTableView<>();
        treeTable.setShowRoot(false);

        TreeTableColumn<Object, String> nameColumn = new TreeTableColumn<>("Name");
        nameColumn.setCellValueFactory(cellData -> {
            TreeItem<Object> rowItem = cellData.getValue();
            if (rowItem != null && (rowItem.getValue() instanceof Factory)) {
                Factory f = (Factory) rowItem.getValue() ;
                return new SimpleStringProperty(f.getName());
            } else {
                return new SimpleStringProperty("");
            }
        });

        TreeTableColumn<Object, Number> sizeColumn = new TreeTableColumn<>("Size");
        sizeColumn.setCellValueFactory(cellData -> {
            TreeItem<Object> rowItem = cellData.getValue();
            if (rowItem != null && (rowItem.getValue() instanceof Factory)) {
                Factory f = (Factory) rowItem.getValue() ;
                return new SimpleObjectProperty<Number>(Double.valueOf(f.getSize()));
            } else {
                return new SimpleObjectProperty<Number>(null);
            }
        });

        TreeTableColumn<Object, String> employeeColumn = new TreeTableColumn<>("Employee");
        employeeColumn.setCellValueFactory(cellData -> {
            TreeItem<Object> rowItem = cellData.getValue();
            if (rowItem != null && (rowItem.getValue() instanceof Employee)) {
                Employee emp = (Employee) rowItem.getValue() ;
                return new SimpleStringProperty(emp.getName());
            } else {
                return new SimpleStringProperty("");
            }
        });

        treeTable.getColumns().addAll(nameColumn, sizeColumn, employeeColumn);

        List<Factory> factories = createData();
        TreeItem<Object> root = new TreeItem<>(null);
        for (Factory factory : factories) {
            TreeItem<Object> factoryItem = new TreeItem<>(factory);
            root.getChildren().add(factoryItem);
            for (Employee emp : factory.getEmployees()) {
                TreeItem<Object> employeeItem = new TreeItem<>(emp);
                factoryItem.getChildren().add(employeeItem);
            }
        }
        treeTable.setRoot(root);

        Scene scene = new Scene(treeTable, 800, 800);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private List<Factory> createData() {
        String[][] empNames = {
                {"John", "Jane", "Mary"},
                {"Susan", "Mike"},
                {"Alex", "Francois", "Joanne"}
        };
        List<Factory> factories = new ArrayList<>();
        for (String[] emps : empNames) {
            int count = factories.size()+1 ;
            Factory f = new Factory("Factory "+ count, count*10);
            for (String empName : emps) {
                f.getEmployees().add(new Employee(empName));
            }
            factories.add(f);
        }
        return factories ;
    }

    public static class Employee {
        private String name ;

        public Employee(String name) {
            this.name = name ;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }


    }

    public class Factory {
        private String name ;
        private double size ;
        private List<Employee> employees ;

        public Factory(String name, double size) {
            this.name = name ;
            this.size = size ;
            this.employees = new ArrayList<>();
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public double getSize() {
            return size;
        }

        public void setSize(double size) {
            this.size = size;
        }

        public List<Employee> getEmployees() {
            return employees;
        }


    }

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

另一种方法(我认为这有点人为)是创建一个类,表示表视图中的行,然后生成它的FactoryEmployee子类:

代码语言:javascript
复制
public abstract class EmploymentEntity {

    public String getName() {
        return null ;
    }

    public Double getSize() {
        return null ;
    }

    public String getEmployeeName {
        return null ;
    }
}

然后

代码语言:javascript
复制
public class Employee extends EmploymentEntity {
    private String name ;

    public Employee(String name) {
        this.name = name ;
    }

    @Override
    public String getEmployeeName() {
        return name ;
    }

    public void setEmployeeName(String name) {
        this.name = name ; 
    }
}

代码语言:javascript
复制
public class Factory extends EmploymentEntity {

    private String name ;
    private double size ;
    private List<Employee> employees ;

    public Factory(String name, double size) {
        this.name = name ;
        this.size = size ;
        this.employees = new ArrayList<>();
    }

    @Override
    public String getName() {
        return name ;
    }

    public void setName(String name) {
        this.name = name ;
    }

    @Override
    public Double getSize() {
        return size ;
    }

    public void setSize(double size) {
        this.size = size ;
    }

    public List<Employee> getEmployees() {
        return employees ;
    }
}

这个对象模型是非常不自然的(无论如何,对我来说),但是它确实使表变得更容易了:

代码语言:javascript
复制
TreeTableView<EmploymentEntity> treeTable = new TreeTableView<>();
TreeTableColumn<EmploymentEntity, String> nameColumn = new TreeTableColumn<>("Name");
nameColumn.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getValue().getName()));
TreeTableColumn<EmploymentEntity, Number> sizeColumn = new TreeTableColumn<>("Size");
sizeColumn.setCellValueFactory(cellData -> new SimpleObjectProperty<Number>(cellData.getValue().getValue().getSize()));
TreeTableColumn<EmploymentEntity, String> employeeColumn = new TreeTableColumn<>("Employee");
employeeColumn.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getValue().getEmployeeName()));
// etc...
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39596980

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档