如何在JavaFX TableView中获取选定的TableCell

4

我希望找到一种方法来获取TableView控件中选定的单元格。请注意,我不仅想要单元格的值,我需要一个实际的TableCell对象。人们可能会期望使用以下方法:

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

该方法实现了这一点,但它返回一个TablePosition对象,该对象提供行和列信息,但我没有找到从中获取TableCell对象的方法。

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

编辑: 对于未来的读者:除了在单元格工厂中使用之外,请勿干扰TableCell对象。按照设计师的意图使用TableView,否则你会遇到很多麻烦。如果您需要从多个源获取数据并将其放入单个表格中,则最好创建一个聚合所有数据的新类,并将其用作TableView源。


你可以获取存储在单元格中的数据,但是获取单元格对象,我从未这样做过。 - ItachiUchiha
JavaFX 重用单元格和行。只会创建足够覆盖表格中实际可见部分以及可能的一些额外部分的单元格。就像您在编辑中所说的,通过单元格工厂创建具有所需功能的单元格。它应该具有确定其状态所需的所有信息。 - SephB
3个回答

4

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

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

你的方法也返回一个TablePosition,所以你也可以使用它。
这是链接 https://dev59.com/tnzaa4cB1Zd3GeqPVd6f#21988562

谢谢,但我不想编辑单元格,我想获取对它的引用。我的单元格是不可编辑的。 - Nikša Baldun
为什么需要引用?我尝试过,但学到的大多数需要引用的事情都可以在cellfactory中完成。 - brian
我有一个相当复杂的情况,其中单元格从多个来源获取其值。当用户按下键时,会打开一个新窗口,以便用户可以输入数据,然后我需要使用setItem()将该数据放入单元格的值中。我知道手动调用setItem()不被推荐,但我没有看到其他方法。 - Nikša Baldun
不要调用setItem(),而是更新表模型数据。您需要引用绑定到单元格的对象。可以使用tableView.getItems().get(tablePosition.getRow())来实现。然后,调用所需更改的设置方法即可。 - brian
是的,单一的源代码是首选,但并不总是最合适的。我认为我的解决方案很优雅,只是漏掉了这个小细节。现在一切都按预期运行。至少你的回答证实了我所要求的是做不到的,我会接受你的答案。 - Nikša Baldun
显示剩余2条评论

0

这可能会被踩,因为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,我已经更新了答案以反映这一点。我还清理了拼写和语法。


-1

你想要响应按键事件吗?最好不要。

相反,你可以注册一个监听器来监听表格单元格的聚焦事件,这将能够处理箭头键和鼠标点击表格单元格的操作(甚至包括触摸事件,哦,未来已经来了)

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

在这个例子中,我使用了一个“经典”的TableView,其中List<String>作为列模型。(因此,您的数据类型可能与String不同。)当然,那个label只是我的代码中的一个示例。

1
这不是问题的答案:OP想要的是_TableCell_而不是值。 - kleopatra

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接