20

Given a TableView, i need to detect the doubleclick on a cell.

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

How to determine the cell on which the mouse has been clicked?

Marv
  • 3,517
  • 2
  • 22
  • 47
AgostinoX
  • 7,477
  • 20
  • 77
  • 137

5 Answers5

32

Code example.
Run the "Example 12-11: Alternative Solution Of Cell Editing" of official tableview tutorial.
Replace the followings:

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

No need to EditingCell since your cells are uneditable. Cell factory is used for cell rendering. So one can put any node/control other than default Labeled using cell's setGraphics() method. IMO you cannot access the default cell directly so you should define your own cell factory to be able to put event filter on cell.

Uluk Biy
  • 48,655
  • 13
  • 146
  • 153
  • This approach is nice because it allows you to set up column specific mouse listeners configured for just that column: `myCol.setCellFactory(cellFactory);` I've included an example that can be used for the entire table if you want a cell to be both editable and respond independently to mouse events. – VikingGlen Sep 07 '15 at 23:49
9

JavaFX allows you to set up multiple listeners per cell (I'm not saying that this is good or bad, just that you can). Each listener will execute your code if you have code set to execute a response to the specific listener for the specific column/row. To capture cell mouse clicks, I use the following:

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

You can see from the above code, on the columns I want to do something based on a mouse click, I have code:

if ( col == <int> ) { ... do something ... }

I also have those columns set to not allow editing:

thisCol.setEditable(false);

The rows that I want to edit I have .setEditable(true) but don't have a response included with a mouse click.

Cell editing defaults to 2 mouse clicks. You can change the above code to capture different mouse events on a cell, so you can still edit the cell with 2 mouse clicks, or open a URL, dialog box, etc., with any other mouse event determined by you. TableView allows you to determine your own functionality based on your imagination and programming skills. You're not stuck with "I can either edit it, or fire a mouse event with it." You can do both :)

VikingGlen
  • 1,705
  • 18
  • 18
4

Add the following in the body of your listener, with T the type of your table record :

  @SuppressWarnings("rawtypes")
  ObservableList<TablePosition> cells = tableView.getSelectionModel().getSelectedCells();
  for( TablePosition< T, ? > cell : cells )
  {
     System.out.println( cell.getColumn());
  }// for
Aubin
  • 14,617
  • 9
  • 61
  • 84
2

Create your cell using a cell factory and in the cell factory which creates the cell node, place an mouse event handler or filter on the node rather than the tableView.

jewelsea
  • 150,031
  • 14
  • 366
  • 406
  • 1
    Ok, can you expand with a little example? Here is my problem. My cells are not editable, so I think it wont be the TextFieldTableCell to catch the event, but the Label. Where do i set such component? – AgostinoX Sep 23 '12 at 19:02
  • Uluk's answer https://stackoverflow.com/a/12591417/1155209 provides an example of this approach. – jewelsea Oct 26 '20 at 14:12
2

In my case i use next code

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());
                    }
                }
            }
        });
Dmitry Nelepov
  • 7,246
  • 8
  • 53
  • 74