使javafx TableView像JTable一样

时间:2014-05-04 15:36:27

标签: javafx jtable tableview

有没有办法让javafx中的TableView在摆动时像JTable一样动作?

TableView编辑单元格内容的当前过程是:

  1. 选择单元格。
  2. 在单元格上按Enter键进入编辑模式。
  3. 键入。
  4. 按Enter键提交编辑。
  5. 而在jtable中则更容易;你不必按Enter进行编辑;你可以直接编辑。

    在这一点上让javafx表视图像jtable一样的任何想法?

1 个答案:

答案 0 :(得分:0)

我是用一堆听众做的。我会添加我的代码片段,因为列不会真正适用于您。

public class DataTable extends TableView<LineItem> {
    private final Data data;
    //used for keyreleased in table to put table in editing state and remember which key was    pressed
    private String lastKey = null;
    /** makes a table 
     * @param data The Data structure
     */
    public DataTable(Data data){
        super(data.lines);
        this.data = data;
        setEditable(true);
        //cut out my deleted lines stack but left some code because has to handle del in textfield

        Callback<TableColumn<LineItem,String>, TableCell<LineItem,String>> txtCellFactory = 
                (TableColumn<LineItem,String> p) -> {return new EditingCell();};

        TableColumn<LineItem,String> lineNoCol = new TableColumn<>("Line");
        lineNoCol.setCellValueFactory(new PropertyValueFactory<>("LineNo"));
        lineNoCol.setCellFactory(txtCellFactory);
        lineNoCol.setOnEditCommit((TableColumn.CellEditEvent<LineItem, String> evt) -> {
            evt.getTableView().getItems().get(evt.getTablePosition().getRow())
                    .setLineNo(evt.getNewValue());
        });
//more columns

/////  This puts it in editing state and remebers the key pressed for the textfield
        setOnKeyPressed((KeyEvent t) -> {
            TablePosition tp;
            if (!t.isControlDown() &&
                    (t.getCode().isLetterKey() || t.getCode().isDigitKey())) {
                lastKey = t.getText();
                tp = getFocusModel().getFocusedCell();
                edit(tp.getRow(),tp.getTableColumn());
                lastKey = null;
            }
        });

        addEventFilter(KeyEvent.KEY_PRESSED, (KeyEvent t) -> {
            if (getEditingCell() == null && t.getCode() == KeyCode.ENTER) {
                if (t.isShiftDown()) {
                    getSelectionModel().selectAboveCell();
                } else {
                    getSelectionModel().selectBelowCell();
                }
                t.consume();
            }

            if (t.isControlDown() && t.getCode() == KeyCode.TAB) {
                if (t.isShiftDown()) {
                    getSelectionModel().selectLeftCell();
                } else {
                    getSelectionModel().selectRightCell();
                }
                t.consume();
            }
        });

        setOnKeyReleased((KeyEvent t) -> {
            TablePosition tp;
            switch (t.getCode()) {
                case INSERT:
                    data.lines.add(new LineItem());//maybe try adding at position
                    getSelectionModel().selectLast();
                    break;
                case DELETE:
                    //textfield has to consume this so it doesn't reach here.
                    tp = getSelectionModel().getSelectedCells().get(0);
                    if (tp.getTableColumn() == lineNoCol) {
                        deletedLines.push(data.lines.remove(tp.getRow()));
                        //todo reselect something
                    } else { //maybe delete cell value
                    }
                    break;
                case Z:
                    if (t.isControlDown()) {
                        if (!deletedLines.isEmpty()) {
                            data.lines.add(deletedLines.pop());
                            //todo re-sort etc
                        }
                    }
            }
        });
    }

    private class EditingCell extends TableCell {//no type for now

        private TextField textField;

        @Override
        public void startEdit() {
            if (!isEmpty()) {
                super.startEdit();
                createTextField();
                setText(null);
                setGraphic(textField);
                Platform.runLater(() -> {//without this space erases text, f2 doesn't
                    textField.requestFocus();//also selects
                });
                if (lastKey != null) {
                    textField.setText(lastKey);
                    Platform.runLater(() -> {
                        textField.deselect();
                        textField.end();
                    });
                }
            }
        }

        @Override
        public void cancelEdit() {
            super.cancelEdit();
            try {
                setText(getItem().toString());
            } catch (Exception e) {}
            setGraphic(null);
        }

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

            if (empty) {
                setText(null);
                setGraphic(null);
            } else if (isEditing()) {
                if (textField != null) {
                    textField.setText(getString());
                }
                setText(null);
                setGraphic(textField);
            } else {
                setText(getString());
                setGraphic(null);
                //not applicable but shows how to align columns
                if (getTableColumn().getText().equals("Amount"))
                    setAlignment(Pos.CENTER_RIGHT);
            }
        } 

        private void createTextField() {
            textField = new TextField(getString());
            //setPadding(Insets.EMPTY);//screws up table cell for after
            textField.setPadding(new Insets(0,0,0,5));
            textField.setPrefHeight(this.getHeight()-2);//border hgt??

            textField.focusedProperty().addListener(
                    (ObservableValue<? extends Boolean> arg0, Boolean arg1, Boolean arg2) -> {
                if (!arg2) commitEdit(textField.getText());
            });

            textField.setOnKeyReleased((KeyEvent t) -> {
                if (t.getCode() == KeyCode.ENTER) {
                    commitEdit(textField.getText());
                    EditingCell.this.getTableView().requestFocus();//why does it lose focus??
                    EditingCell.this.getTableView().getSelectionModel().selectBelowCell();
                }
                else if (t.getCode() == KeyCode.RIGHT) {//dont really like this
                    if (textField.getCaretPosition() >= textField.getLength()){
                        commitEdit(textField.getText());
                        EditingCell.this.getTableView().requestFocus();//why does it lose focus??
                        EditingCell.this.getTableView().getSelectionModel().selectRightCell();
                    }
                }
                else if (t.getCode() == KeyCode.UP) {//moves caret to 0
                    if (textField.getCaretPosition() == 0){
                        commitEdit(textField.getText());
                        EditingCell.this.getTableView().requestFocus();//why does it lose focus??
                        EditingCell.this.getTableView().getSelectionModel().selectAboveCell();
                    }
                }
                else if (t.getCode() == KeyCode.DOWN) {
                    if (textField.getCaretPosition() >= textField.getLength()){
                        commitEdit(textField.getText());
                        EditingCell.this.getTableView().requestFocus();//why does it lose focus??
                        EditingCell.this.getTableView().getSelectionModel().selectBelowCell();
                    }
                }
                else if (t.getCode() == KeyCode.ESCAPE) {
                    cancelEdit();
                }
            });

            textField.addEventFilter(KeyEvent.KEY_RELEASED, (KeyEvent t) -> {
                if (t.getCode() == KeyCode.DELETE) {
                    t.consume();//stop from deleting line in table keyevent
                }
            });
        }

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

}