当前位置: 首页 > 知识库问答 >
问题:

让javafx TableView像JTable一样

夏侯旻
2023-03-14

有没有办法让javafx中的TableView像swing中的JTable一样工作?

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

  1. 选择单元格。
  2. 在单元格上按回车键进入编辑模式。
  3. 打字。
  4. 按回车键提交编辑。

而在jtable中要容易得多;您不必按enter键进行编辑;你可以直接编辑。

在这一点上,有没有让javafx表视图像jtable一样工作的想法?

共有1个答案

严天逸
2023-03-14

我和一群听众一起做。我将添加我的代码片段,因为这些列实际上不适用于您。

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();
        }
    }

}
 类似资料:
  • 我创建了一个TableView,其中包含一个复选框列(isSelected)和三个信息列(姓名、姓氏、职务)。我想根据用户信息禁用一些复选框。例如,如果用户名为“Peter”,则Peter旁边的复选框将被禁用。但我不能。以下是我的一些代码: 人JAVA 控制器。JAVA

  • 我正在使用一个功能组件,我需要能够使用componentDidMount()。我在网上发现,通过react钩子,可以将useEffect()用作功能组件中的componentDidMount()。然而,这并不像我想象的那样有效。我原以为在页面加载时会触发,但事实并非如此。有人知道如何让useEffect表现得像componentDidMount吗? 我试着只是简单地这样做,但它创建了一个无限循环,

  • 我一直在尝试访问Angular应用程序中的sqwiggle API,并使用Postman进行测试。一切似乎都很顺利。我定义了一个BasicAuth头,对消息endpoint执行GET请求,得到了一个很好的响应。这些是请求头(来自邮递员): 现在在我的AngularJS应用程序中,我想做同样的事情: 但这会导致以下请求标头: 鉴于Postman使用JS从API获取数据,在AngularJS中也应该是

  • 我一直在使用毕加索的库将图像加载到我的应用程序中的gridview中,它的工作和外观完全符合我的要求。但是用户告诉我图像的加载速度非常慢。我知道这是因为糟糕的网络速度和毕加索正在加载我的完整图像,这是非常大的,然后调整它们的大小,以适应我的图像视图。所以我尝试使用glide,它以几乎两倍的速度装载图像,但在一些图像上,它不像毕加索那样保持结构。例如,毕加索加载图像看起来像 当滑翔加载时,它们有不同

  • 我有一个像这个图像的登录表单。 登录按钮是一个带有图标的JLabel。我想要能够按下“进入”和登录。 我已经将登录逻辑放入名为doAction()的方法中;我在login Label上有一个MouseEvent,它按预期工作,并在任何时候单击login JLabel时调用doAction()。我希望同样的事情发生在任何时候,我按下“回车”。我试过这个: 问题是,只有当我使用PasswordFiel

  • 题外话 最近一直在关注比特币社区的大事件,Mike Hearn说比特币实验失败了,比特币交易价格应声大跌,币圈的朋友该如何站队,比特币的未来会如何,很多人又一次陷入迷茫。 我个人,反而更加坚定了信心。这件事充分说明,一个产品有它的生命周期,有它失败的风险,一项技术却永远前进在路上。无论产品消亡与否(当然,比特币不会那么轻易消亡),都会留下丰厚的技术遗产。 希望我的技术分享,能为这句话做个见证。 前