Detect doubleclick on row of TableView JavaFX

JavaTableviewJavafx 8

Java Problem Overview


I need to detect double clicks on a row of a TableView.

How can I listen for double clicks on any part of the row and get all data of this row to print it to the console?

Java Solutions


Solution 1 - Java

TableView<MyType> table = new TableView<>();

//...

table.setRowFactory( tv -> {
    TableRow<MyType> row = new TableRow<>();
    row.setOnMouseClicked(event -> {
        if (event.getClickCount() == 2 && (! row.isEmpty()) ) {
            MyType rowData = row.getItem();
            System.out.println(rowData);
        }
    });
    return row ;
});

Here is a complete working example:

import java.util.Random;
import java.util.function.Function;

import javafx.application.Application;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ObservableValue;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableRow;
import javafx.scene.control.TableView;
import javafx.stage.Stage;

public class TableViewDoubleClickOnRow extends Application {

	@Override
	public void start(Stage primaryStage) {
		TableView<Item> table = new TableView<>();
		table.setRowFactory(tv -> {
		    TableRow<Item> row = new TableRow<>();
		    row.setOnMouseClicked(event -> {
		        if (event.getClickCount() == 2 && (! row.isEmpty()) ) {
		            Item rowData = row.getItem();
		            System.out.println("Double click on: "+rowData.getName());
		        }
		    });
		    return row ;
		});
		table.getColumns().add(column("Item", Item::nameProperty));
		table.getColumns().add(column("Value", Item::valueProperty));
		
		Random rng = new Random();
		for (int i = 1 ; i <= 50 ; i++) {
			table.getItems().add(new Item("Item "+i, rng.nextInt(1000)));
		}
		
		Scene scene = new Scene(table);
		primaryStage.setScene(scene);
		primaryStage.show();
	}
	
	private static <S,T> TableColumn<S,T> column(String title, Function<S, ObservableValue<T>> property) {
		TableColumn<S,T> col = new TableColumn<>(title);
		col.setCellValueFactory(cellData -> property.apply(cellData.getValue()));
		return col ;
	}
	
	public static class Item {
		private final StringProperty name = new SimpleStringProperty();
		private final IntegerProperty value = new SimpleIntegerProperty();
		
		public Item(String name, int value) {
			setName(name);
			setValue(value);
		}
		
		public StringProperty nameProperty() {
			return name ;
		}
		
		public final String getName() {
			return nameProperty().get();
		}
		
		public final void setName(String name) {
			nameProperty().set(name);
		}
		
		public IntegerProperty valueProperty() {
			return value ;
		}
		
		public final int getValue() {
			return valueProperty().get();
		}
		
		public final void setValue(int value) {
			valueProperty().set(value);
		}
	}

	public static void main(String[] args) {
		launch(args);
	}
}

Solution 2 - Java

Example:

table.setOnMousePressed(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
if (event.isPrimaryButtonDown() && event.getClickCount() == 2) {
System.out.println(table.getSelectionModel().getSelectedItem());

}
}
});

If you are using custom selection model, then you can get the row from event, example:

table.setOnMousePressed(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
if (event.isPrimaryButtonDown() && event.getClickCount() == 2) {
Node node = ((Node) event.getTarget()).getParent();
TableRow row;
if (node instanceof TableRow) {
row = (TableRow) node;
} else {
// clicking on text part
row = (TableRow) node.getParent();
}
System.out.println(row.getItem());
}
}
});

Solution 3 - Java

This works for me:

table.setOnMouseClicked((MouseEvent event) -> {
            if (event.getButton().equals(MouseButton.PRIMARY) && event.getClickCount() == 2){
                System.out.println(table.getSelectionModel().getSelectedItem());
            }
        });
    }

Solution 4 - Java

If you are using SceneBuilder you can set your table's OnMouseClicked to handleRowSelect() method as shown below:

MyType temp;
Date lastClickTime;
@FXML
private void handleRowSelect() {
	MyType row = myTableView.getSelectionModel().getSelectedItem();
    if (row == null) return;
	if(row != temp){
		temp = row;
		lastClickTime = new Date();
	} else if(row == temp) {
		Date now = new Date();
		long diff = now.getTime() - lastClickTime.getTime();
		if (diff < 300){ //another click registered in 300 millis
             System.out.println("Edit dialog");
		} else {
			lastClickTime = new Date();
		}
	}
}

Solution 5 - Java

This answer has been tested:

table.setOnMouseClicked( event -> {
   if( event.getClickCount() == 2 ) {
      System.out.println( table.getSelectionModel().getSelectedItem());
   }});

table.getSelectionModel().getSelectedItem() can be use since we catch a double-click. One the first click the selection moves, on the second this handler is executed.

Solution 6 - Java

I had similar situation not to detect mouse double click event on TableView. Above all samples worked perfectly. but my application did not detect double click event at all.

But I found that if TableView is on editable, mouse double click event can not be detected !!

check your application if TableView is on editable like this.

tableView.setEditable( true );

if then, double click event only raises on same row selected.

Solution 7 - Java

Extending the previous answer:

The extra check ensures the selected row was double clicked - ignoring double clicks on empty rows or the column header

table.setRowFactory(param -> {
            TableRow<MyType> row = new TableRow<>();
            row.setOnMouseClicked(event -> Optional.ofNullable(row.getItem()).ifPresent(rowData-> {
                if(event.getClickCount() == 2 && rowData.equals(table.getSelectionModel().getSelectedItem())){
                    System.out.println(rowData);
                }
            }));
            return row;
        });
```

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMarcosView Question on Stackoverflow
Solution 1 - JavaJames_DView Answer on Stackoverflow
Solution 2 - JavaAlexander.BergView Answer on Stackoverflow
Solution 3 - JavaAbdul.MoqueetView Answer on Stackoverflow
Solution 4 - JavaSushal PenugondaView Answer on Stackoverflow
Solution 5 - JavaAubinView Answer on Stackoverflow
Solution 6 - JavanayasisView Answer on Stackoverflow
Solution 7 - JavaAnthony StewartView Answer on Stackoverflow