刷新表格视图时丢失组合框数据

时间:2018-07-15 08:32:14

标签: java javafx

在我的TableView中,我有多个可编辑的列。在这里,两列包含组合框,其他两列包含文本字段。一切都很好,但是问题是每当我在表中的0索引处添加新行时,我都会丢失从列表中选择的组合框值。我发现其背后的原因是table.refresh(),但是如果我停止使用table.refresh(),则我的组合框将保留值,但是新行的文本字段将显示上一行的值(我正在添加新行的索引为0,并且有一行现在索引为1)。如何在组合框中保留所选值,并且不显示上一行的文本字段值? 这是我的代码。 TestController

public class TestController implements Initializable {
@FXML
private TableColumn colNumber;

@FXML
private TableColumn colEmergency;

@FXML
private Button btnAdd;

@FXML
private TableColumn colCountry;

@FXML
private TableColumn colSMS;

@FXML
private TableColumn colArea;

@FXML
private TableColumn colPhoneType;

@FXML
private Button btnSaveTable;

@FXML
private TableView<ModelPhone> table;

private ObservableList<String> phoneType = FXCollections.observableArrayList("Cell", "Lan");
private final ObservableList countryList = FXCollections.observableArrayList("A", "B", "C");

@Override
public void initialize(URL location, ResourceBundle resources) {
    table.setEditable(true);
    table.getSelectionModel().setCellSelectionEnabled(true);
    colArea.setEditable(true);
    colCountry.setEditable(true);
    colEmergency.setEditable(true);
    colNumber.setEditable(true);
    colPhoneType.setEditable(true);
    colSMS.setEditable(true);

    Callback<TableColumn, TableCell> cellFactory = new Callback<TableColumn, TableCell>() {
        public TableCell call(TableColumn p) {
            return new EditingCell();
        }
    };

    table.setRowFactory(tv -> {
        TableRow<ModelPhone> row = new TableRow<>();
        row.addEventFilter(MouseEvent.MOUSE_PRESSED, e -> {
            if (e.getButton() == MouseButton.SECONDARY) {
                e.consume();
            }
        });
        return row;
    });

    colArea.setCellValueFactory(new PropertyValueFactory<ModelPhone, String>("AreaCode"));
    colArea.setCellFactory(cellFactory);

    colNumber.setCellValueFactory(new PropertyValueFactory<ModelPhone, String>("PhoneNumber"));
    colNumber.setCellFactory(cellFactory);

    colSMS.setCellValueFactory(new PropertyValueFactory<>("SMScheck"));
    colSMS.setCellFactory(tc -> new CheckBoxTableCell<>());

    colEmergency.setCellValueFactory(new PropertyValueFactory<>("Emergencycheck"));
    colEmergency.setCellFactory(tc -> new CheckBoxTableCell<>());
    colPhoneType.setCellValueFactory(new PropertyValueFactory<ModelPhone, String>("PhoneType"));

    // colPhoneType.setCellFactory(tc -> new ComboBoxTableCell<>(PhoneType));
    colPhoneType.setCellFactory(tc -> {
        ComboBox combo = new ComboBox();
        combo.getItems().addAll(phoneType);

        combo.setPrefWidth(colPhoneType.getWidth() - 5);
        combo.setMaxWidth(colPhoneType.getWidth() - 5);
        TableCell<ModelPhone, String> cell = new TableCell<ModelPhone, String>() {
            @Override
            protected void updateItem(String reason, boolean empty) {
                super.updateItem(reason, empty);
                if (empty) {
                    setGraphic(null);
                } else {
                    // combo.setValue(reason);
                    setText(this.getItem());
                    setGraphic(combo);
                }
            }
        };
        // combo.getSelectionModel().select(0);

        combo.setOnAction(
                e -> table.getItems().get(cell.getIndex()).setPhoneType(String.valueOf(combo.getValue())));
        return cell;
    });
    colPhoneType.setOnEditCommit(new EventHandler<CellEditEvent<ModelPhone, String>>() {
        @Override
        public void handle(TableColumn.CellEditEvent<ModelPhone, String> t) {
            ((ModelPhone) t.getTableView().getItems().get(t.getTablePosition().getRow()))
                    .setPhoneType(t.getNewValue());
        }
    });
    colCountry.setCellValueFactory(new PropertyValueFactory<ModelPhone, String>("CountryName"));
    colCountry.setCellFactory(tc -> {
        ComboBox combo = new ComboBox();
        combo.getItems().addAll(countryList);
        combo.setPrefWidth(colCountry.getWidth() - 5);
        combo.setMaxWidth(colCountry.getWidth() - 5);
        // combo.getSelectionModel().selectFirst();
        TableCell<ModelPhone, String> cell = new TableCell<ModelPhone, String>() {
            @Override
            protected void updateItem(String reason, boolean empty) {
                super.updateItem(reason, empty);
                if (empty) {
                    setGraphic(null);
                } else {
                    // combo.setValue(reason);
                    setText(this.getItem());
                    setGraphic(combo);
                }
            }
        };

        combo.setOnAction(
                e -> table.getItems().get(cell.getIndex()).setCountryName(String.valueOf(combo.getValue())));

        return cell;
    });
    colCountry.setOnEditCommit(new EventHandler<CellEditEvent<ModelPhone, String>>() {
        @Override
        public void handle(TableColumn.CellEditEvent<ModelPhone, String> t) {
            ((ModelPhone) t.getTableView().getItems().get(t.getTablePosition().getRow()))
                    .setCountryName(t.getNewValue());
        }
    });

}

@FXML
void addRow(ActionEvent event) {
    table.layout();
    table.getItems().add(0, new ModelPhone());
    table.refresh();// losing selected combo box value
}

@FXML
void saveTable(ActionEvent event) {

}

 }

这是我的Test.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane prefHeight="209.0" prefWidth="719.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.biziitech.bgeneral.view.TestController">
   <children>
      <TableView fx:id="table" layoutX="10.0" layoutY="46.0" maxHeight="-Infinity" prefHeight="150.0" prefWidth="696.0" AnchorPane.bottomAnchor="0.0" AnchorPane.topAnchor="46.0">
         <columnResizePolicy>
            <TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
         </columnResizePolicy>
         <columns>
            <TableColumn fx:id="colPhoneType" maxWidth="3000.0" prefWidth="206.0" text="Phone Type" />
            <TableColumn fx:id="colCountry" maxWidth="3000.0" prefWidth="206.0" text="Country" />
            <TableColumn fx:id="colArea" maxWidth="500.0" minWidth="102.0" prefWidth="102.0" text="Area Code" />
            <TableColumn fx:id="colEmergency" maxWidth="74.0" minWidth="74.0" prefWidth="74.0" text="Emergency?" />
            <TableColumn fx:id="colSMS" maxWidth="74.0" minWidth="49.0" prefWidth="49.0" text="SMS?" />
            <TableColumn fx:id="colNumber" prefWidth="256.0" text="Phone Number" />
         </columns>
      </TableView>
      <Button fx:id="btnAdd" layoutX="14.0" layoutY="8.0" mnemonicParsing="false" onAction="#addRow" text="Add" />
   </children>
</AnchorPane>

这是我的EditingCell类,用于表视图内的文本字段。

public class EditingCell<S, T> extends TableCell<S, T> {

    private TextField textField;

    public EditingCell() {
    }

    @Override
    public void startEdit() {
        if (!isEmpty()) {
            super.startEdit();
            if (textField == null) {
                createTextField();
            }

            setGraphic(textField);
            setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
            // textField.selectAll();
            Platform.runLater(new Runnable() {
                @Override
                public void run() {
                    textField.requestFocus();
                    textField.selectAll();
                }
            });
        }
    }

    @Override
    public void cancelEdit() {
        super.cancelEdit();

        setText((String) getItem());
        setGraphic(null);
        setContentDisplay(ContentDisplay.TEXT_ONLY);
    }

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

        if (empty) {
            setText(null);
            setGraphic(null);
        } else {
            if (isEditing()) {
                if (textField != null) {
                    textField.setText(getString());
                }
                setGraphic(textField);
                setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
            } else {
                setText(getString());
                setContentDisplay(ContentDisplay.TEXT_ONLY);
            }
        }
    }

    @Override
    public void commitEdit(T item) {

        // This block is necessary to support commit on losing focus, because the
        // baked-in mechanism
        // sets our editing state to false before we can intercept the loss of focus.
        // The default commitEdit(...) method simply bails if we are not editing...
        if (!isEditing() && !item.equals(getItem())) {
            TableView<S> table = getTableView();
            if (table != null) {
                TableColumn<S, T> column = getTableColumn();
                CellEditEvent<S, T> event = new CellEditEvent<>(table,
                        new TablePosition<S, T>(table, getIndex(), column), TableColumn.editCommitEvent(), item);
                Event.fireEvent(column, event);
            }
            super.cancelEdit(); // this fires an invalid EditCancelEvent.

            // update the item within this cell, so that it represents the new value
            updateItem(item, false);

            if (table != null) {
                // reset the editing cell on the TableView
                table.edit(-1, null);

                // request focus back onto the table, only if the current focus
                // owner has the table as a parent (otherwise the user might have
                // clicked out of the table entirely and given focus to something else.
                // It would be rude of us to request it back again.
                // requestFocusOnControlOnlyIfCurrentFocusOwnerIsChild(table);
            }
        }

        super.commitEdit(item);

        setContentDisplay(ContentDisplay.TEXT_ONLY);
    }

    private void createTextField() {
        textField = new TextField(getString());
        // textField.setMinWidth(this.getWidth() - this.getGraphicTextGap()
        // * 2);

        textField.focusedProperty().addListener(new ChangeListener<Boolean>() {
            @Override
            public void changed(ObservableValue<? extends Boolean> arg0, Boolean arg1, Boolean arg2) {
                if (!arg2) {
                    commitEdit((T) textField.getText());
                }
            }
        });
        /*
         * textField.focusedProperty().addListener((obs, wasFocused, isNowFocused) -> {
         * if (!isNowFocused) { commitEdit((T)textField.getText()); } });
         */

        textField.setOnKeyPressed(new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent t) {
                if (t.getCode() == KeyCode.ENTER) {
                    commitEdit((T) textField.getText());
                } else if (t.getCode() == KeyCode.ESCAPE) {
                    cancelEdit();
                } else if (t.getCode() == KeyCode.TAB) {
                    commitEdit((T) textField.getText());
                    TableColumn nextColumn = getNextColumn(!t.isShiftDown());
                    if (nextColumn != null) {
                        getTableView().edit(getTableRow().getIndex(), nextColumn);
                    }

                } else if (t.getCode() == KeyCode.RIGHT) {
                    commitEdit((T) textField.getText());
                    getTableView().getSelectionModel().selectRightCell();
                    TableColumn nextColumn = getNextColumn(!t.isShiftDown());
                    if (nextColumn != null) {
                        getTableView().edit(getTableRow().getIndex(), nextColumn);
                    }

                    t.consume();
                } else if (t.getCode() == KeyCode.LEFT) {
                    commitEdit((T) textField.getText());
                    getTableView().getSelectionModel().selectLeftCell();
                    TableColumn prevColumn = getNextColumn(false);
                    if (prevColumn != null) {
                        getTableView().edit(getTableRow().getIndex(), prevColumn);
                    }
                    t.consume();
                } else if (t.getCode() == KeyCode.UP) {
                    commitEdit((T) textField.getText());
                    getTableView().getSelectionModel().selectAboveCell();
                    int i = getTableView().getSelectionModel().getSelectedIndex();
                    if (i >= 0)
                        getTableView().edit(i, getTableColumn());
                    t.consume();
                } else if (t.getCode() == KeyCode.DOWN) {
                    commitEdit((T) textField.getText());
                    getTableView().getSelectionModel().selectBelowCell();
                    int i = getTableView().getSelectionModel().getSelectedIndex();
                    if (i >= 0)
                        getTableView().edit(i, getTableColumn());
                    t.consume();
                }

            }

        });

        /*
         * textField.setOnMouseClicked(new EventHandler<MouseEvent>() {
         * 
         * @Override public void handle(MouseEvent t) { // TODO Auto-generated method
         * stub if ( t.getButton() == MouseButton.PRIMARY && t.getClickCount() == 2 ) {
         * commitEdit((T)textField.getText()); t.consume(); } } });
         */

    }

    private String getString() {
        return getItem() == null ? "" : getItem().toString();
    }

    private TableColumn<S, ?> getNextColumn(boolean forward) {
        List<TableColumn<S, ?>> columns = new ArrayList<>();
        for (TableColumn<S, ?> column : getTableView().getColumns()) {
            columns.addAll(getLeaves(column));
        }
        // There is no other column that supports editing.
        if (columns.size() < 2) {
            return null;
        }
        int currentIndex = columns.indexOf(getTableColumn());
        int nextIndex = currentIndex;
        if (forward) {
            nextIndex++;
            if (nextIndex > columns.size() - 1) {
                nextIndex = 0;
            }
        } else {
            nextIndex--;
            if (nextIndex < 0) {
                nextIndex = columns.size() - 1;
            }
        }
        return columns.get(nextIndex);
    }

    private List<TableColumn<S, ?>> getLeaves(TableColumn<S, ?> root) {
        List<TableColumn<S, ?>> columns = new ArrayList<>();
        if (root.getColumns().isEmpty()) {
            // We only want the leaves that are editable.
            if (root.isEditable()) {
                columns.add(root);
            }
            return columns;
        } else {
            for (TableColumn<S, ?> column : root.getColumns()) {
                columns.addAll(getLeaves(column));
            }
            return columns;
        }
    }
}

ModelPhone.java

public class ModelPhone {
    private LongProperty phoneId = new SimpleLongProperty();
    private LongProperty userId = new SimpleLongProperty();
    private LongProperty countryId = new SimpleLongProperty();
    private IntegerProperty typeId = new SimpleIntegerProperty();
    private StringProperty countryName = new SimpleStringProperty();
    private StringProperty phoneType = new SimpleStringProperty();
    private StringProperty areaCode = new SimpleStringProperty();
    private StringProperty phoneNumber = new SimpleStringProperty();
    private StringProperty remarks = new SimpleStringProperty();
    private IntegerProperty entered_By = new SimpleIntegerProperty();
    private Timestamp entryTimestap;
    private IntegerProperty updatedBy = new SimpleIntegerProperty();
    private Timestamp updateTimestap;
    private IntegerProperty activeStatus = new SimpleIntegerProperty();
    private IntegerProperty SMS = new SimpleIntegerProperty();
    private IntegerProperty emergency = new SimpleIntegerProperty();
    private SimpleBooleanProperty SMScheck = new SimpleBooleanProperty();
    private SimpleBooleanProperty emergencycheck = new SimpleBooleanProperty();
    private SimpleBooleanProperty active = new SimpleBooleanProperty();

    public ModelPhone() {

    }

    public ModelPhone(LongProperty phoneId, LongProperty userId, LongProperty countryId, IntegerProperty typeId,
            StringProperty countryName, StringProperty phoneType, StringProperty areaCode, StringProperty phoneNumber,
            StringProperty remarks, IntegerProperty entered_By, Timestamp entryTimestap, IntegerProperty updatedBy,
            Timestamp updateTimestap, IntegerProperty activeStatus, IntegerProperty sMS, IntegerProperty emergency,
            SimpleBooleanProperty sMScheck, SimpleBooleanProperty emergencycheck, SimpleBooleanProperty active) {
        super();
        this.phoneId = phoneId;
        this.userId = userId;
        this.countryId = countryId;
        this.typeId = typeId;
        this.countryName = countryName;
        this.phoneType = phoneType;
        this.areaCode = areaCode;
        this.phoneNumber = phoneNumber;
        this.remarks = remarks;
        this.entered_By = entered_By;
        this.entryTimestap = entryTimestap;
        this.updatedBy = updatedBy;
        this.updateTimestap = updateTimestap;
        this.activeStatus = activeStatus;
        SMS = sMS;
        this.emergency = emergency;
        SMScheck = sMScheck;
        this.emergencycheck = emergencycheck;
        this.active = active;
    }

    public final LongProperty phoneIdProperty() {
        return this.phoneId;
    }

    public final long getPhoneId() {
        return this.phoneIdProperty().get();
    }

    public final void setPhoneId(final long phoneId) {
        this.phoneIdProperty().set(phoneId);
    }

    public final LongProperty userIdProperty() {
        return this.userId;
    }

    public final long getUserId() {
        return this.userIdProperty().get();
    }

    public final void setUserId(final long userId) {
        this.userIdProperty().set(userId);
    }

    public final LongProperty countryIdProperty() {
        return this.countryId;
    }

    public final long getCountryId() {
        return this.countryIdProperty().get();
    }

    public final void setCountryId(final long countryId) {
        this.countryIdProperty().set(countryId);
    }

    public final IntegerProperty typeIdProperty() {
        return this.typeId;
    }

    public final int getTypeId() {
        return this.typeIdProperty().get();
    }

    public final void setTypeId(final int typeId) {
        this.typeIdProperty().set(typeId);
    }

    public final StringProperty countryNameProperty() {
        return this.countryName;
    }

    public final String getCountryName() {
        return this.countryNameProperty().get();
    }

    public final void setCountryName(final String countryName) {
        this.countryNameProperty().set(countryName);
    }

    public final StringProperty phoneTypeProperty() {
        return this.phoneType;
    }

    public final String getPhoneType() {
        return this.phoneTypeProperty().get();
    }

    public final void setPhoneType(final String phoneType) {
        this.phoneTypeProperty().set(phoneType);
    }

    public final StringProperty areaCodeProperty() {
        return this.areaCode;
    }

    public final String getAreaCode() {
        return this.areaCodeProperty().get();
    }

    public final void setAreaCode(final String areaCode) {
        this.areaCodeProperty().set(areaCode);
    }

    public final StringProperty phoneNumberProperty() {
        return this.phoneNumber;
    }

    public final String getPhoneNumber() {
        return this.phoneNumberProperty().get();
    }

    public final void setPhoneNumber(final String phoneNumber) {
        this.phoneNumberProperty().set(phoneNumber);
    }

    public final StringProperty remarksProperty() {
        return this.remarks;
    }

    public final String getRemarks() {
        return this.remarksProperty().get();
    }

    public final void setRemarks(final String remarks) {
        this.remarksProperty().set(remarks);
    }

    public final IntegerProperty entered_ByProperty() {
        return this.entered_By;
    }

    public final int getEntered_By() {
        return this.entered_ByProperty().get();
    }

    public final void setEntered_By(final int entered_By) {
        this.entered_ByProperty().set(entered_By);
    }

    public final IntegerProperty updatedByProperty() {
        return this.updatedBy;
    }

    public final int getUpdatedBy() {
        return this.updatedByProperty().get();
    }

    public final void setUpdatedBy(final int updatedBy) {
        this.updatedByProperty().set(updatedBy);
    }

    public final IntegerProperty activeStatusProperty() {
        return this.activeStatus;
    }

    public final int getActiveStatus() {
        return this.activeStatusProperty().get();
    }

    public final void setActiveStatus(final int activeStatus) {
        this.activeStatusProperty().set(activeStatus);
    }

    public final IntegerProperty SMSProperty() {
        return this.SMS;
    }

    public final int getSMS() {
        return this.SMSProperty().get();
    }

    public final void setSMS(final int SMS) {
        this.SMSProperty().set(SMS);
    }

    public final IntegerProperty emergencyProperty() {
        return this.emergency;
    }

    public final int getEmergency() {
        return this.emergencyProperty().get();
    }

    public final void setEmergency(final int emergency) {
        this.emergencyProperty().set(emergency);
    }

    public final SimpleBooleanProperty SMScheckProperty() {
        return this.SMScheck;
    }

    public final boolean isSMScheck() {
        return this.SMScheckProperty().get();
    }

    public final void setSMScheck(final boolean SMScheck) {
        this.SMScheckProperty().set(SMScheck);
    }

    public final SimpleBooleanProperty emergencycheckProperty() {
        return this.emergencycheck;
    }

    public final boolean isEmergencycheck() {
        return this.emergencycheckProperty().get();
    }

    public final void setEmergencycheck(final boolean emergencycheck) {
        this.emergencycheckProperty().set(emergencycheck);
    }

    public final SimpleBooleanProperty activeProperty() {
        return this.active;
    }

    public final boolean isActive() {
        return this.activeProperty().get();
    }

    public final void setActive(final boolean active) {
        this.activeProperty().set(active);
    }

    public Timestamp getEntryTimestap() {
        return entryTimestap;
    }

    public void setEntryTimestap(Timestamp entryTimestap) {
        this.entryTimestap = entryTimestap;
    }

    public Timestamp getUpdateTimestap() {
        return updateTimestap;
    }

    public void setUpdateTimestap(Timestamp updateTimestap) {
        this.updateTimestap = updateTimestap;
    }

    @Override
    public String toString() {
        return "ModelPhone [phoneId=" + phoneId + ", userId=" + userId + ", countryId=" + countryId + ", typeId="
                + typeId + ", countryName=" + countryName + ", phoneType=" + phoneType + ", areaCode=" + areaCode
                + ", phoneNumber=" + phoneNumber + ", remarks=" + remarks + ", entered_By=" + entered_By
                + ", entryTimestap=" + entryTimestap + ", updatedBy=" + updatedBy + ", updateTimestap=" + updateTimestap
                + ", activeStatus=" + activeStatus + ", SMS=" + SMS + ", emergency=" + emergency + ", SMScheck="
                + SMScheck + ", emergencycheck=" + emergencycheck + ", active=" + active + "]";
    }

}

0 个答案:

没有答案