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

时间:2017-05-22 08:36:57

标签: java javafx tableview

我正在将一个应用程序从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_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;
    }    
});

感谢Alb

2 个答案:

答案 0 :(得分:1)

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

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

(为了便于阅读,我将匿名内部类转换为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);
    }
}

答案 1 :(得分:0)

您可以通过执行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;
        }    
    });