右键单击事件并双击tableview javafx上的事件

右键单击事件并双击tableview javafx上的事件,java,javafx,tableview,Java,Javafx,Tableview,我正在将一个应用程序从swing重写为javafx 我不明白如何在tableview的同一行上实现双击事件和右键单击事件。 它们单独工作正常 这是我的右键点击行为代码 words_table.setRowFactory( new Callback<TableView<WordsToFind>, TableRow<WordsToFind>>() { @Override public TableRow<WordsToFind> call(TableVi

我正在将一个应用程序从swing重写为javafx

我不明白如何在tableview的同一行上实现双击事件和右键单击事件。 它们单独工作正常

这是我的右键点击行为代码

words_table.setRowFactory(
new Callback<TableView<WordsToFind>, TableRow<WordsToFind>>() {
@Override
public TableRow<WordsToFind> call(TableView<WordsToFind> tableView) {
final TableRow<WordsToFind> row = new TableRow<>();
final ContextMenu rowMenu = new ContextMenu();
MenuItem removeItem = new MenuItem("Delete");
removeItem.setOnAction(e -> {
int wordid = words_table.getSelectionModel().getSelectedItem().getWordToFindId();
deleteWord(wordid);
words_table.getItems().remove(row.getItem());
});
rowMenu.getItems().addAll(removeItem);
row.contextMenuProperty().bind(
  Bindings.when(Bindings.isNotNull(row.itemProperty()))
  .then(rowMenu)
  .otherwise((ContextMenu)null));
return row;
    }    
});
words\u table.setRowFactory(
新回调函数(){
@凌驾
公共TableRow调用(TableView TableView){
最终TableRow行=新TableRow();
最终上下文菜单行菜单=新上下文菜单();
MenuItem removeItem=新MenuItem(“删除”);
删除项目设置操作(e->{
int-wordid=words\u table.getSelectionModel().getSelectedItem().getWordToFindId();
删除字(wordid);
words_table.getItems().remove(row.getItem());
});
rowMenu.getItems().addAll(removeItem);
row.contextMenuroperty().bind(
Bindings.when(Bindings.isNotNull(row.itemProperty()))
.then(行菜单)
。否则((ContextMenu)null));
返回行;
}    
});
这是我的双击行为代码

words_table.setRowFactory(  
new Callback<TableView<WordsToFind>, TableRow<WordsToFind>>() {
@Override
public TableRow<WordsToFind> call(TableView<WordsToFind> tableView) {
final TableRow<WordsToFind> row = new TableRow<>();
row.setOnMouseClicked(new EventHandler<MouseEvent>(){
    @Override
        public void handle(MouseEvent event){
            if (event.getClickCount() == 2 && (! row.isEmpty()) ) {
               some code here .....
            }
    }
});
return row;
    }    
});
words\u table.setRowFactory(
新回调函数(){
@凌驾
公共TableRow调用(TableView TableView){
最终TableRow行=新TableRow();
row.setOnMouseClicked(新的EventHandler(){
@凌驾
公共无效句柄(MouseeEvent事件){
如果(event.getClickCount()==2&&(!row.isEmpty()){
这里有一些代码。。。。。
}
}
});
返回行;
}    
});

感谢Alb

您可以通过执行
row.setOnMouseClicked(..)
本身将这两个事件添加到该行,如下所示

words_table.setRowFactory(  
    new Callback<TableView<WordsToFind>, TableRow<WordsToFind>>() {
    @Override
    public TableRow<WordsToFind> call(TableView<WordsToFind> tableView) {
    final TableRow<WordsToFind> row = new TableRow<>();
    row.setOnMouseClicked(new EventHandler<MouseEvent>(){
        @Override
            public void handle(MouseEvent event){

                if (event.getClickCount() == 2 && (! row.isEmpty()) ) {
                   //double click code here
                }
                else if(event.isSecondaryButtonDown()){
                  //right click code here
                }
        }
    });
    return row;
        }    
    });
words\u table.setRowFactory(
新回调函数(){
@凌驾
公共TableRow调用(TableView TableView){
最终TableRow行=新TableRow();
row.setOnMouseClicked(新的EventHandler(){
@凌驾
公共无效句柄(MouseeEvent事件){
如果(event.getClickCount()==2&&(!row.isEmpty()){
//双击此处的代码
}
else if(event.isSecondaryButtonDown()){
//右键单击此处的代码
}
}
});
返回行;
}    
});

您可以通过执行
row.setOnMouseClicked(..)
本身将这两个事件添加到该行,如下所示

words_table.setRowFactory(  
    new Callback<TableView<WordsToFind>, TableRow<WordsToFind>>() {
    @Override
    public TableRow<WordsToFind> call(TableView<WordsToFind> tableView) {
    final TableRow<WordsToFind> row = new TableRow<>();
    row.setOnMouseClicked(new EventHandler<MouseEvent>(){
        @Override
            public void handle(MouseEvent event){

                if (event.getClickCount() == 2 && (! row.isEmpty()) ) {
                   //double click code here
                }
                else if(event.isSecondaryButtonDown()){
                  //right click code here
                }
        }
    });
    return row;
        }    
    });
words\u table.setRowFactory(
新回调函数(){
@凌驾
公共TableRow调用(TableView TableView){
最终TableRow行=新TableRow();
row.setOnMouseClicked(新的EventHandler(){
@凌驾
公共无效句柄(MouseeEvent事件){
如果(event.getClickCount()==2&&(!row.isEmpty()){
//双击此处的代码
}
else if(event.isSecondaryButtonDown()){
//右键单击此处的代码
}
}
});
返回行;
}    
});

只需在第一行工厂的
call()
方法中放置
行。setOnMouseClicked
调用

words_table.setRowFactory(tableView -> {
    final TableRow<WordsToFind> row = new TableRow<>();
    final ContextMenu rowMenu = new ContextMenu();
    MenuItem removeItem = new MenuItem("Delete");
    removeItem.setOnAction(e -> {
        int wordid = words_table.getSelectionModel().getSelectedItem().getWordToFindId();
        deleteWord(wordid);
        words_table.getItems().remove(row.getItem());
    });

    rowMenu.getItems().addAll(removeItem);
    row.contextMenuProperty().bind(
        Bindings.when(Bindings.isNotNull(row.itemProperty()))
                .then(rowMenu)
                .otherwise((ContextMenu)null));

    row.setOnMouseClicked(event -> {
        if (event.getClickCount() == 2 && (! row.isEmpty()) ) {
            // some code here .....
        }
    });

    return row;
});
words\u table.setRowFactory(tableView->{
最终TableRow行=新TableRow();
最终上下文菜单行菜单=新上下文菜单();
MenuItem removeItem=新MenuItem(“删除”);
删除项目设置操作(e->{
int-wordid=words\u table.getSelectionModel().getSelectedItem().getWordToFindId();
删除字(wordid);
words_table.getItems().remove(row.getItem());
});
rowMenu.getItems().addAll(removeItem);
row.contextMenuroperty().bind(
Bindings.when(Bindings.isNotNull(row.itemProperty()))
.then(行菜单)
。否则((ContextMenu)null));
row.setOnMouseClicked(事件->{
如果(event.getClickCount()==2&&(!row.isEmpty()){
//这里有一些代码。。。。。
}
});
返回行;
});
(为了可读性,我将匿名inners类转换为lambda表达式。)

下面是一个完整的示例,演示了这一工作原理:

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

import javafx.application.Application;
import javafx.beans.binding.Bindings;
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.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableRow;
import javafx.scene.control.TableView;
import javafx.stage.Stage;

public class RowFactoryExample extends Application {

    @Override
    public void start(Stage primaryStage) {

        TableView<Item> table = new TableView<>();
        table.getColumns().add(column("Item", Item::nameProperty));
        table.getColumns().add(column("Value", Item::valueProperty));
        table.getItems().setAll(createData());

        table.setRowFactory(tableView -> {
            final TableRow<Item> row = new TableRow<>();
            final ContextMenu rowMenu = new ContextMenu();
            MenuItem removeItem = new MenuItem("Delete");
            removeItem.setOnAction(e -> {
                table.getItems().remove(row.getItem());
            });

            rowMenu.getItems().addAll(removeItem);
            row.contextMenuProperty().bind(
                Bindings.when(Bindings.isNotNull(row.itemProperty()))
                        .then(rowMenu)
                        .otherwise((ContextMenu)null));

            row.setOnMouseClicked(event -> {
                if (event.getClickCount() == 2 && (! row.isEmpty()) ) {
                    System.out.println("Double click on "+row.getItem().getName());
                }
            });

            return row;
        });

        Scene scene = new Scene(table, 600, 600);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private <S,T> TableColumn<S,T> column(String text, Function<S, ObservableValue<T>> prop) {
        TableColumn<S,T> col = new TableColumn<>(text);
        col.setCellValueFactory(cellData -> prop.apply(cellData.getValue()));
        return col ;
    }

    private List<Item> createData() {
        Random rng = new Random();
        List<Item> data = new ArrayList<>();
        for (int i = 1 ; i <= 100; i++) {
            data.add(new Item("Item "+i, rng.nextInt(1000))) ;
        }
        return data ;
    }

    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 final StringProperty nameProperty() {
            return this.name;
        }


        public final String getName() {
            return this.nameProperty().get();
        }


        public final void setName(final String name) {
            this.nameProperty().set(name);
        }


        public final IntegerProperty valueProperty() {
            return this.value;
        }


        public final int getValue() {
            return this.valueProperty().get();
        }


        public final void setValue(final int value) {
            this.valueProperty().set(value);
        }



    }

    public static void main(String[] args) {
        launch(args);
    }
}
import java.util.ArrayList;
导入java.util.List;
导入java.util.Random;
导入java.util.function.function;
导入javafx.application.application;
导入javafx.beans.binding.Bindings;
导入javafx.beans.property.IntegerProperty;
导入javafx.beans.property.SimpleIntegerProperty;
导入javafx.beans.property.SimpleStringProperty;
导入javafx.beans.property.StringProperty;
导入javafx.beans.value.observeValue;
导入javafx.scene.scene;
导入javafx.scene.control.ContextMenu;
导入javafx.scene.control.MenuItem;
导入javafx.scene.control.TableColumn;
导入javafx.scene.control.TableRow;
导入javafx.scene.control.TableView;
导入javafx.stage.stage;
公共类RowFactoryExample扩展了应用程序{
@凌驾
公共无效开始(阶段primaryStage){
TableView table=新TableView();
table.getColumns().add(列(“项”,项::nameProperty));
table.getColumns().add(column(“Value”,Item::valueProperty));
table.getItems().setAll(createData());
表.setRowFactory(表视图->{
最终TableRow行=新TableRow();
最终上下文菜单行菜单=新上下文菜单();
MenuItem removeItem=新MenuItem(“删除”);
删除项目设置操作(e->{
table.getItems().remove(row.getItem());
});
rowMenu.getItems().addAll(removeItem);
row.contextMenuroperty().bind(
Bindings.when(Bindings.isNotNull(row.itemProperty()))
.then(行菜单)
。否则((ContextMenu)null));
row.setOnMouseClicked(事件->{
如果(event.getClickCount()==2&&(!row.isEmpty()){
System.out.println(“双击”+row.getItem().getName());
}
});
返回行;
});
场景=新场景(表600600);
初级阶段。场景(场景);
primaryStage.show();
}
私有表列(字符串文本、函数属性){
TableColumn col=新的TableColumn(tex