将ComboBox添加到TableColumn并绑定到行数据

时间:2018-03-22 14:33:51

标签: java javafx tableview

我有一个简单的表格,如下所示:

enter image description here

以下是MCVE代码。

Main.java

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
        primaryStage.setScene(new Scene(root, 300, 275));
        primaryStage.show();
    }


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

Controller.java

public class Controller {

    @FXML
    private TableView<TemplateColumn> tblColumns;
    @FXML
    private TableColumn<TemplateColumn, Integer> colColumnIndex;
    @FXML
    private TableColumn<TemplateColumn, String> colColumnName;
    @FXML
    private TableColumn<TemplateColumn, String> colMappedTo;

    private Template sourceTemplate;
    private Template destinationTemplate;

    @FXML
    private void initialize() {

        createSampleData();

        // Initialize the table
        colColumnIndex.setCellValueFactory(new PropertyValueFactory<>("columnIndex"));
        colColumnName.setCellValueFactory(new PropertyValueFactory<>("columnName"));
        colMappedTo.setCellValueFactory(new PropertyValueFactory<>("destinationColumnIndex"));

        tblColumns.setItems(sourceTemplate.getColumns());

        ComboBox<TemplateColumn> cboMappedColumns = new ComboBox<>();
        cboMappedColumns.setItems(destinationTemplate.getColumns());

    }

    private void createSampleData() {

        destinationTemplate = new Template();
        destinationTemplate.setTemplateName("Output");
        destinationTemplate.setColumns(FXCollections.observableArrayList(
                new TemplateColumn("Destination 0", 0, -1),
                new TemplateColumn("Destination 1", 1, -1),
                new TemplateColumn("Destination 2", 2, -1),
                new TemplateColumn("Destination 3", 3, -1))
        );

        sourceTemplate = new Template();
        sourceTemplate.setTemplateName("Input");
        sourceTemplate.setColumns(FXCollections.observableArrayList(
                new TemplateColumn("Source 0", 0, 3),
                new TemplateColumn("Source 1", 1, 1),
                new TemplateColumn("Source 2", 2, 0),
                new TemplateColumn("Source 3", 3, 2))
        );
        sourceTemplate.setDestinationTemplate(destinationTemplate);

    }
}

Template.java

public class Template {

    private final SimpleStringProperty templateName = new SimpleStringProperty("");
    private final SimpleStringProperty destinationTemplateName = new SimpleStringProperty("");
    private SimpleObjectProperty<Template> destinationTemplate = new SimpleObjectProperty<>();

    // The list of TemplateColumns
    private List<TemplateColumn> columns;

    public Template() {
        templateName.set("NEW");
    }

    public Template(ArrayList<TemplateColumn> columns) {
        this.columns = columns;
    }

    public String getTemplateName() {
        return templateName.get();
    }

    public SimpleStringProperty templateNameProperty() {
        return templateName;
    }

    public void setTemplateName(String templateName) {
        this.templateName.set(templateName);
    }

    public String getDestinationTemplateName() {
        return destinationTemplateName.get();
    }

    public void setDestinationTemplateName(String destinationTemplateName) {
        this.destinationTemplateName.set(destinationTemplateName);
    }

    public ObservableList<TemplateColumn> getColumns() {
        return FXCollections.observableArrayList(columns);
    }

    public SimpleStringProperty destinationTemplateNameProperty() {
        return destinationTemplateName;
    }

    public Template getDestinationTemplate() {
        return destinationTemplate.get();
    }

    public SimpleObjectProperty<Template> destinationTemplateProperty() {
        return destinationTemplate;
    }

    public void setDestinationTemplate(Template destinationTemplate) {
        this.destinationTemplate.set(destinationTemplate);
    }

    public void setColumns(List<TemplateColumn> columns) {
        this.columns = columns;
    }

    public TemplateColumn getReportColumn(int index) {
        for (TemplateColumn col : columns) {
            if (col.getColumnIndex() == index) return col;
        }
        return null;
    }

    @Override
    public String toString() {
        return templateName.get();
    }
}

TemplateColumn.java

public class TemplateColumn {

    private final SimpleStringProperty columnName = new SimpleStringProperty("");
    private final SimpleIntegerProperty columnIndex = new SimpleIntegerProperty(0);
    private final SimpleIntegerProperty destinationColumnIndex = new SimpleIntegerProperty(-1);

    public TemplateColumn(String columnName, int columnIndex, int destinationColumnIndex) {
        this.columnName.set(columnName);
        this.columnIndex.set(columnIndex);
        this.destinationColumnIndex.set(destinationColumnIndex);
    }

    public int getDestinationColumnIndex() {
        return destinationColumnIndex.get();
    }

    public SimpleIntegerProperty destinationColumnIndexProperty() {
        return destinationColumnIndex;
    }

    public void setDestinationColumnIndex(int destinationColumnIndex) {
        this.destinationColumnIndex.set(destinationColumnIndex);
    }

    public String getColumnName() {
        return columnName.get();
    }

    public SimpleStringProperty columnNameProperty() {
        return columnName;
    }

    public void setColumnName(String columnName) {
        this.columnName.set(columnName);
    }

    public int getColumnIndex() {
        return columnIndex.get();
    }

    public SimpleIntegerProperty columnIndexProperty() {
        return columnIndex;
    }

    public void setColumnIndex(int columnIndex) {
        this.columnIndex.set(columnIndex);
    }

    @Override
    public String toString() {
        return columnName.get();
    }
}

问题

基本上,我需要的是cboMappedColumns ComboBox显示在表格中每行的Mapped To列中,其值(双向)绑定到TemplateColumn { {1}}与该行的来源columnIndex的{​​{1}}匹配。

所以,而不是显示&#34; 3&#34;在第一行中,它将是一个ComboBox,其值为&#34; Destination 3&#34;而是选择了。

注意:这是我发布有效问题的第三次尝试;如果我还缺少某些东西,请告诉我。谢谢你的帮助!

1 个答案:

答案 0 :(得分:0)

setCellFactory表示包含ComboBox

的列
  • 创建您的类型的新ComboBox,并将其价值属性双向绑定到您班级中的所需媒体资源。
  • 将创建的ComboBox设置为行的图形。

我希望以下示例可以帮助您解决问题。

Output

<强>控制器:

import java.net.URL;
import java.util.ResourceBundle;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;

/**
 *
 * @author M. S.
 */
public class FXMLDocumentController implements Initializable {

    @FXML
    private TableView<Employee> table;

    @FXML
    private TableColumn<Employee, String> nameColumn;

    @FXML
    private TableColumn<Employee, CompanyType> companyTypeColumn;

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        nameColumn.setCellValueFactory((param) -> {
            return new SimpleStringProperty(param.getValue().getName());
        });

        companyTypeColumn.setCellValueFactory((param) -> {
            return param.getValue().companyTypeProperty();
        });

        companyTypeColumn.setCellFactory((column) -> {
            return new TableCell<Employee, CompanyType>() {
                @Override
                protected void updateItem(CompanyType item, boolean empty) {
                    super.updateItem(item, empty);
                    if (item != null && !empty) {
                        ComboBox<CompanyType> comboBox = new ComboBox<>(FXCollections.observableArrayList(CompanyType.values()));

                        Employee employee = (Employee) getTableRow().getItem();
                        comboBox.valueProperty().bindBidirectional(employee.companyTypeProperty());

                        setGraphic(comboBox);
                    } else {
                        setText(null);
                        setGraphic(null);
                    }
                }
            };
        });

        table.getItems().add(new Employee("Foo", CompanyType.PRIVATE));
        table.getItems().add(new Employee("Bar", CompanyType.PUBLIC));
        table.getItems().add(new Employee("John", CompanyType.PUBLIC));
    }

}

员工类:

import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;

/**
 * 
 * @author M. S.
 */
public class Employee {

    private String name;

    public Employee(String name, CompanyType companyType) {
        this.name = name;
        this.setCompanyType(companyType);
    }

    private final ObjectProperty<CompanyType> companyType = new SimpleObjectProperty<>();

    public CompanyType getCompanyType() {
        return companyType.get();
    }

    public void setCompanyType(CompanyType value) {
        companyType.set(value);
    }

    public ObjectProperty companyTypeProperty() {
        return companyType;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return "Employee{" + "name=" + name + ", companyType=" + companyType + '}';
    }

}

CompanyType类:

/**
 * 
 * @author M. S.
 */
public enum CompanyType {
    PRIVATE, PUBLIC;
}