从JavaFX TableColumn的组合框CellFactory中删除\添加项目的问题

时间:2015-09-30 10:44:36

标签: javafx event-handling javafx-8 observable tablecolumn

我有一个JavaFX TableColumn。该列有一个ComboBoxTableCell由ObservableList填充,我传递给它。

我有一个"活跃"列表和" deactive"组合框列表。选择完成后,我希望从活动的" real"列表中删除所选项目(并将其添加到停用的项目列表中)。

选择完成后,正在触发CellEditEvent并按所选的一个(从组合框)设置行对象。 问题是,当我从列表中删除select项目时,在事件处理程序中,我的CellEditEvent事件处理程序再次被触发 - 这次是错误的"新值"!

当然这种行为完全破坏了我的流逻辑。

有关如何解决这种情况的任何想法?谢谢

情况的SSCCE:

package tableviewexample;

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.property.*;
import javafx.beans.value.ObservableValue;
import javafx.collections.*;
import javafx.event.*;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.*;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.Callback;
import javafx.util.StringConverter;

public class TableViewExample extends Application {

    @Override
    public void start(Stage primaryStage) {
        TableView<MappingItem> table = new TableView<>();

        // FIRST COLUMN
        TableColumn<MappingItem, String> colA = new TableColumn<>("Excel Column");        

        colA.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<MappingItem, String>, ObservableValue<String>> () {
            @Override
            public ObservableValue<String> call(TableColumn.CellDataFeatures<MappingItem, String> param) {
                return new ReadOnlyObjectWrapper(param.getValue().getExcelColumnName());
            }            
        });   

        //SECOND COLUMN
        TableColumn<MappingItem, GoldplusField> colB = new TableColumn<>("Database Field Column");
        colB.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<MappingItem, GoldplusField>, ObservableValue<GoldplusField>> () {
            @Override
            public ObservableValue<GoldplusField> call(TableColumn.CellDataFeatures<MappingItem, GoldplusField> param) {
                return new ReadOnlyObjectWrapper(param.getValue().getGpField());
            }            
        });

        GoldplusField gp1 = new GoldplusField("T1", "fName", "First Name");
        GoldplusField gp2 = new GoldplusField("T1", "phn", "Phone");
        GoldplusField gp3 = new GoldplusField("T2", "lName", "Last Name");
        GoldplusField gp4 = new GoldplusField("T2", "adrs", "Address");        

        ObservableList<GoldplusField> deactiveFieldsList = FXCollections.observableArrayList();
        ObservableList<GoldplusField> activeFieldsList = FXCollections.observableArrayList(gp1, gp2, gp3, gp4);
        colB.setCellFactory(ComboBoxTableCell.forTableColumn(new FieldToStringConvertor(), activeFieldsList));  

        colB.setOnEditCommit(
            new EventHandler<TableColumn.CellEditEvent<MappingItem, GoldplusField>>() {
                @Override
                public void handle(TableColumn.CellEditEvent<MappingItem, GoldplusField> t) {
                    if (t.getNewValue() != null) { 
                        deactiveFieldsList.add(t.getNewValue());

                        ((MappingItem) t.getTableView().getItems().get(
                        t.getTablePosition().getRow())
                        ).setGpField(t.getNewValue());

                        // ******************************************************************************************** //
                        // This creates a new instance of the EventHandler in which I get the "next" item on the List.
                        // ******************************************************************************************** //
                        activeFieldsList.remove(t.getNewValue());   
                    }
                }
            }
        );


        //THIRD COLUMN
        TableColumn<MappingItem, String> colC = new TableColumn<>("Test Column");
        PropertyValueFactory<MappingItem, String> nameFac = new PropertyValueFactory<>("name");
        colC.setCellValueFactory(nameFac);
        colC.setCellFactory(TextFieldTableCell.forTableColumn());        

        table.setEditable(true);
        table.getColumns().addAll(colA, colB, colC);

        GoldplusField gp5 = new GoldplusField("T1", "other", "Other");
        MappingItem mi1 = new MappingItem("name", gp5);
        mi1.excelColumnName.set("name1");
        MappingItem mi2 = new MappingItem("phone", gp5);
        mi2.excelColumnName.set("nam2");
        ObservableList<MappingItem> miList = FXCollections.observableArrayList(mi1, mi2);

        table.setItems(miList);

        StackPane root = new StackPane();
        root.getChildren().add(table);

        Scene scene = new Scene(root, 300, 250);

        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

    class FieldToStringConvertor extends StringConverter<GoldplusField> {

        @Override
        public String toString(GoldplusField object) {

            if (object != null)
                return object.getGpName();
            else
                return "";
        }

        @Override
        public GoldplusField fromString(String string) {
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        }        
    }

    public class MappingItem {
        private StringProperty excelColumnName = new SimpleStringProperty(this, "excelColumnName");
        private ObjectProperty<GoldplusField> gpField = new SimpleObjectProperty<GoldplusField>(this, "gpField");

        public String getExcelColumnName() { return excelColumnName.get(); }

        public void setExcelColumnName(String excelColumnName) { this.excelColumnName.set(excelColumnName); }

        public StringProperty excelColumnNameProperty() { return excelColumnName;        }

        public GoldplusField getGpField() { return gpField.get(); }

        public void setGpField(GoldplusField gpField) { this.gpField.set(gpField); }

        public ObjectProperty gpFieldProperty() { return this.gpField;        }

        public MappingItem(String columnName) { this.excelColumnName.set(columnName); }    

        public MappingItem(GoldplusField gpField) { this.gpField.set(gpField); }    

        public MappingItem(String columnName, GoldplusField gpField) {

            this.excelColumnName.set(columnName);
            this.gpField.set(gpField);
        }         
    }    

    public class GoldplusField {
        private StringProperty table = new SimpleStringProperty(this, "table");
        private StringProperty dbName = new SimpleStringProperty(this, "dbName");
        private StringProperty gpName = new SimpleStringProperty(this, "gpName");

        public String getDbName() { return dbName.get(); }

        public String getGpName() { return gpName.get(); }

        public String getTable() { return table.get(); }

        public void setDbName(String dbName) { this.dbName.set(dbName); }

        public void setGpName(String gpName) { this.gpName.set(gpName); }

        public void setTable(String table) { this.table.set(table); }

        public StringProperty tableProperty() { return this.table;        }

        public StringProperty gpNameProperty() { return this.gpName;        }    

        public StringProperty dbNameProperty() { return this.dbName;        }

        public GoldplusField(String table, String dbName, String gpName) {

            this.dbName.set(dbName);
            this.gpName.set(gpName);
            this.table.set(table);
        }
    }
}

0 个答案:

没有答案