【问题标题】:javafx, TableView: detect a doubleclick on a celljavafx,TableView:检测单元格上的双击
【发布时间】:2012-09-12 00:44:40
【问题描述】:

给定一个 TableView,我需要检测单元格上的双击。

tableView.setOnMouseClicked(new EventHandler<MouseEvent>()
{
    @Override
    public void handle(MouseEvent event)
    {
        if(event.getClickCount()>1)
        {
            System.out.println("double clicked!");
        }
    }
});

如何判断鼠标点击的单元格?

【问题讨论】:

    标签: tableview javafx-2


    【解决方案1】:

    JavaFX 允许您为每个单元设置多个侦听器(我并不是说这是好是坏,只是您可以)。如果您将代码设置为对特定列/行的特定侦听器执行响应,则每个侦听器都将执行您的代码。要捕获单元格鼠标点击,我使用以下内容:

    table.setEditable(true);
    table.getSelectionModel().setCellSelectionEnabled(true);  // selects cell only, not the whole row
    table.setOnMouseClicked(new EventHandler<MouseEvent>() {
     @Override
     public void handle(MouseEvent click) {
      if (click.getClickCount() == 2) {
       @SuppressWarnings("rawtypes")
       TablePosition pos = table.getSelectionModel().getSelectedCells().get(0);
       int row = pos.getRow();
       int col = pos.getColumn();
       @SuppressWarnings("rawtypes")
       TableColumn column = pos.getTableColumn();
       String val = column.getCellData(row).toString(); System.out.println("Selected Value, " + val + ", Column: " + col + ", Row: " + row);
       if ( col == 2 ) { ... do something ... } 
       if ( col == 5 ) { ... do something ... } 
       if ( col == 6 ) { ... do something ... } 
       if ( col == 8 ) { ... do something ... } 
      }
     }
    });
    

    从上面的代码可以看出,在我想基于鼠标点击做某事的列上,我有代码:

    if ( col == &lt;int&gt; ) { ... do something ... }

    我也将这些列设置为不允许编辑:

    thisCol.setEditable(false);

    我想要编辑的行有.setEditable(true),但没有包含通过鼠标单击的响应。

    单元格编辑默认为 2 次鼠标单击。您可以更改上述代码以捕获单元格上的不同鼠标事件,因此您仍然可以通过两次鼠标单击来编辑单元格,或者使用您确定的任何其他鼠标事件打开 URL、对话框等。 TableView 允许您根据自己的想象力和编程技能来确定自己的功能。你不会被“我可以编辑它,或者用它触发鼠标事件”所困。你可以两者都做:)

    【讨论】:

    • 感谢非常有用的回答
    【解决方案2】:

    代码示例。
    运行official tableview tutorial“示例12-11:单元格编辑的替代解决方案”
    替换以下内容:

    table.setEditable(false);
    Callback<TableColumn, TableCell> cellFactory =
            new Callback<TableColumn, TableCell>() {
                public TableCell call(TableColumn p) {
                    TableCell cell = new TableCell<Person, String>() {
                        @Override
                        public void updateItem(String item, boolean empty) {
                            super.updateItem(item, empty);
                            setText(empty ? null : getString());
                            setGraphic(null);
                        }
    
                        private String getString() {
                            return getItem() == null ? "" : getItem().toString();
                        }
                    };
    
                    cell.addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
                        @Override
                        public void handle(MouseEvent event) {
                            if (event.getClickCount() > 1) {
                                System.out.println("double clicked!");
                                TableCell c = (TableCell) event.getSource();
                                System.out.println("Cell text: " + c.getText());
                            }
                        }
                    });
                    return cell;
                }
            };
    

    无需EditingCell,因为您的单元格不可编辑。细胞工厂用于细胞渲染。因此,可以使用单元格的 setGraphics() 方法放置除默认 Labeled 以外的任何节点/控件。 IMO 您不能直接访问默认单元格,因此您应该定义自己的单元格工厂以便能够在单元格上放置事件过滤器。

    【讨论】:

    • 这种方法很好,因为它允许您设置为该列配置的特定于列的鼠标侦听器:myCol.setCellFactory(cellFactory); 我提供了一个示例,如果您想要一个可以用于整个表的示例单元格既可编辑又可独立响应鼠标事件。
    【解决方案3】:

    在我的情况下,我使用下一个代码

    tableViewObject.setOnMouseClicked(new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent t) {
                    if (t.getClickCount() == 2 && getSelectedItem() != null) {
                        SMPBLogger.logInfo("Double cliked", Boolean.TRUE);
                        if (listener != null) {
                            listener.doubleClicked(tableViewObject.this,getSelectedItem());
                        }
                    }
                }
            });
    

    【讨论】:

    • 我们中的一些人想做的事
    【解决方案4】:

    在您的侦听器正文中添加以下内容,T 是您的表记录类型:

      @SuppressWarnings("rawtypes")
      ObservableList<TablePosition> cells = tableView.getSelectionModel().getSelectedCells();
      for( TablePosition< T, ? > cell : cells )
      {
         System.out.println( cell.getColumn());
      }// for
    

    【讨论】:

      【解决方案5】:

      使用单元工厂创建您的单元,并在创建单元节点的单元工厂中,将鼠标事件处理程序或过滤器放置在节点而不是 tableView 上。

      【讨论】:

      • 好的,你能举个小例子吗?这是我的问题。我的单元格不可编辑,所以我认为捕捉事件的不是 TextFieldTableCell,而是标签。我在哪里设置这样的组件?
      • Uluk 的回答 stackoverflow.com/a/12591417/1155209 提供了这种方法的一个示例。
      猜你喜欢
      • 2014-07-22
      • 2014-12-21
      • 1970-01-01
      • 2012-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-19
      • 1970-01-01
      相关资源
      最近更新 更多