【问题标题】:How to get selected TableCell in JavaFX TableView如何在 JavaFX TableView 中获取选定的 TableCell
【发布时间】:2014-02-24 13:02:14
【问题描述】:

我正在寻找一种方法来获取 TableView 控件的选定单元格。请注意,我不仅想要单元格值,还想要一个实际的 TableCell 对象。人们会期望该方法:

tableView.getSelectionModel().getSelectedCells().get(0)

这样做,但它返回一个 TablePosition 对象,它为您提供行和列信息,但我看不到从中获取 TableCell 对象的方法。

我需要这个的原因是因为我想响应按键,但是将事件过滤器附加到 TableCell 不起作用(可能是因为它不可编辑)。所以我将它附加到 TableView 上,但是我需要获取当前选择的单元格。

编辑:对于未来的读者:不要弄乱 TableCell 对象,除非在单元工厂中。按照设计者的意图使用 TableView,否则你会遇到很多麻烦。如果您需要单个表中来自多个源的数据,最好创建一个聚合所有数据的新类并将其用作 TableView 源。

【问题讨论】:

  • 可以获取存储在单元格中的数据,但是获取单元格对象,我从来没有这样做过
  • JavaFX 重用单元格和行。将只创建足够的单元格来覆盖表格中实际可见的内容,并且可能还有一些额外的单元格。就像您在编辑中所说的那样,通过单元工厂创建具有所需功能的单元。它应该具有确定其状态所需的所有信息。

标签: javafx javafx-8


【解决方案1】:

我刚刚发布了一个使用此代码编辑单元格的答案。我认为您无法获得对实际表格单元格的引用,因为它位于表格视图的内部。

tp = tv.getFocusModel().getFocusedCell();
tv.edit(tp.getRow(), tp.getTableColumn());

您的方法还返回一个 TablePosition,因此您也可以使用它。

这是链接https://stackoverflow.com/a/21988562/2855515

【讨论】:

  • 谢谢,但我不想编辑单元格,我想获得对它的引用。我的单元格不可编辑。
  • 为什么需要参考?我已经尝试过,但了解到您需要参考的大多数事情都可以在 cellfactory 中完成。
  • 我有一个相当复杂的场景,其中单元格从多个来源获取其价值。当用户按下一个键时,会打开一个新窗口,以便用户输入数据,然后我需要使用 setItem() 将该数据放入单元格的值中。我知道不建议手动调用 setItem(),但我没有看到其他方法。
  • 您应该更新表模型数据,而不是调用 setItem()。您需要对单元格绑定到的对象的引用。这可以使用tableView.getItems().get(tablePosition.getRow()) 来完成,然后调用 set 方法来更改您想要更改的内容。
  • 我知道,但就像我说的,单元格从多个来源获取它们的值,我只能将一个模型实体与 TableView 关联。无论如何,我可以看到从 TableView 获取单元格引用是不可能的,所以我想我需要自己保留单元格引用列表,因为 CellFactory 会生成它们。
【解决方案2】:

这可能会被否决,因为 OP 询问的是返回单元格本身,而不是我将描述的内容,但谷歌搜索将我引到这里来解决我的问题。

我个人在尝试从单个单元格中检索数据时遇到了问题。

java.is.for.desktop 提供了与此问题相关的错误代码,会引发 ArrayIndexOutOfBoundsException,但在正确的轨道上。我的目标是使用 lambda 提供一个更好的示例。

从单个 TableCell 访问数据:

tableView.getFocusModel().focusedCellProperty().addListener((ObservableValue<? extends TablePosition> observable, TablePosition oldPos, TablePosition pos) -> {
    int    row           = pos.getRow();
    int    column        = pos.getColumn();
    String selectedValue = "";

    /* pos.getColumn() can return -1 if the TableView or
     * TableColumn instances are null. The JavaDocs state
     * this clearly. Failing to check will produce an 
     * ArrayIndexOutOfBoundsException when underlying data is changed.
     */
    if ((pos.getRow() != -1) && (pos.getColumn() != -1))
    {
        selectedValue = tableView.getItems()
                                          .get(row)
                                          .get(column);

        if ((selectedValue != null) && (!selectedValue.isEmpty()))
        {
            // handling if contains data
        }
        else
        {
            // handling if doesn't contain data
        }
    }
});

编辑: 我的意思是说 ArrayIndexOutOfBoundsException,而不是 NullPointerException,我更新了这个答案以反映这一点。我还清理了拼写和语法。

【讨论】:

    【解决方案3】:

    您想响应按键吗?最好不要。

    相反,您可以注册一个侦听器来聚焦表格单元格,这将与箭头键和鼠标点击表格单元格一起工作(即使是触摸事件,哦,天哪,未来已经存在).

    table.getFocusModel().focusedCellProperty().addListener(
            new ChangeListener<TablePosition>() {
        @Override
        public void changed(ObservableValue<? extends TablePosition> observable,
                TablePosition oldPos, TablePosition pos) {
            int row = pos.getRow();
            int column = pos.getColumn();
            String selectedValue = "";
    
            if (table.getItems().size() > row
                    && table.getItems().get(row).size() > column) {
                selectedValue = table.getItems().get(row).get(column);
            }
    
            label.setText(selectedValue);
        }
    });
    

    在此示例中,我使用“经典”TableViewList&lt;String&gt; 作为列模型。 (因此,您的数据类型可能与 String 不同。)当然,label 只是我代码中的一个示例。

    【讨论】:

    • 这不是问题的答案:OP 想要 TableCell 而不是值
    猜你喜欢
    • 2020-01-21
    • 2020-02-05
    • 1970-01-01
    • 1970-01-01
    • 2013-06-27
    • 1970-01-01
    • 2012-11-15
    • 1970-01-01
    • 2016-12-07
    相关资源
    最近更新 更多