行双击时无法触发MouseEvent

时间:2013-12-28 10:48:48

标签: java javafx javafx-2 javafx-8

这是一个单击行的JavaFX表的基本示例:

    public class MainApp extends Application
{

    private TableView<Person> table = new TableView<>();
    private final ObservableList<Person> data
        = FXCollections.observableArrayList(
            new Person("Processor", "72"),
            new Person("RAM", "78"),
            new Person("HDD Free Space", "890"),
            new Person("Lan Adapter NIC 1", "36"),
            new Person("Lan Adapter NIC 2", "67"));

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

    @Override
    public void start(Stage stage)
    {
        //Scene scene = new Scene(new Group());
        stage.setTitle("Table View Sample");
        //stage.setWidth(850);
        //stage.setHeight(550);

        final Label label = new Label("Address Book");
        label.setFont(new Font("Arial", 20));

        //table.setStyle("-fx-font-size: 11;"); // Set table font size
        table.setEditable(false);

        Callback<TableColumn<Person, String>, TableCell<Person, String>> cellFactory = new Callback<TableColumn<Person, String>, TableCell<Person, String>>()
        {
            @Override
            public TableCell<Person, String> call(TableColumn<Person, String> col)
            {
                TableCell<Person, String> cell = new EditingCell();
                cell.addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>()
                {
                    @Override
                    public void handle(MouseEvent event)
                    {
                        if (event.getClickCount() > 1)
                        {
                            System.out.println("double clicked!");
                            // TODO GET THE OBJECT AND MAKE SQL QUERY IN ORDER TO MAKE NEW DIALOG WITH
                            TableCell c = (TableCell) event.getSource();
                            System.out.println("Cell text: " + c.getText());
                        }
                    }
                });
                return cell;
            }
        };

        table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);

        TableColumn firstNameCol = new TableColumn("Credentials");
        //firstNameCol.setPrefWidth(300);
        firstNameCol.setMinWidth(20);
        //firstNameCol.prefWidthProperty().bind(table.widthProperty().divide(2)); // w * 1/2

        firstNameCol.setCellValueFactory(new PropertyValueFactory<>("firstName"));
        firstNameCol.setCellFactory(cellFactory);
        firstNameCol.setOnEditCommit(
            new EventHandler<CellEditEvent<Person, String>>()
            {
                @Override
                public void handle(CellEditEvent<Person, String> t)
                {
                    ((Person) t.getTableView().getItems().get(
                        t.getTablePosition().getRow())).setFirstName(t.getNewValue());
                }
            }
        );

        TableColumn lastNameCol = new TableColumn("Value");
        //lastNameCol.setPrefWidth(300);
        lastNameCol.setMinWidth(20);
        //lastNameCol.prefWidthProperty().bind(table.widthProperty().divide(2));  // w * 1/2

        lastNameCol.setCellValueFactory(new PropertyValueFactory<>("lastName"));
        lastNameCol.setCellFactory(cellFactory);
        lastNameCol.setOnEditCommit(
            new EventHandler<CellEditEvent<Person, String>>()
            {
                @Override
                public void handle(CellEditEvent<Person, String> t)
                {
                    ((Person) t.getTableView().getItems().get(
                        t.getTablePosition().getRow())).setLastName(t.getNewValue());
                }
            }
        );

        table.setItems(data);
        table.getColumns().addAll(firstNameCol, lastNameCol);

        VBox vbox = new VBox();
        VBox.setVgrow(table, Priority.ALWAYS);
        vbox.setSpacing(5);
        vbox.setPadding(new Insets(10, 10, 10, 10));
        vbox.getChildren().addAll(label, table);

        Scene scene = new Scene(vbox);
        stage.setScene(scene);
        stage.show();
    }

    public static class Person
    {

        private final SimpleStringProperty firstName;
        private final SimpleStringProperty lastName;

        private Person(String fName, String lName)
        {
            this.firstName = new SimpleStringProperty(fName);
            this.lastName = new SimpleStringProperty(lName);
        }

        public String getFirstName()
        {
            return firstName.get();
        }

        public void setFirstName(String fName)
        {
            firstName.set(fName);
        }

        public String getLastName()
        {
            return lastName.get();
        }

        public void setLastName(String fName)
        {
            lastName.set(fName);
        }

    }

    class EditingCell extends TableCell<Person, String>
    {

        private TextField textField;

        public EditingCell()
        {

            // Right-Click mouse context menu
            final ContextMenu contextMenu = new ContextMenu();

            contextMenu.setOnShowing(
                new EventHandler<WindowEvent>()
                {

                    @Override
                    public void handle(WindowEvent e)
                    {
                        System.out.println("showing");
                    }
                }
            );
            contextMenu.setOnShown(new EventHandler<WindowEvent>()
            {
                @Override
                public void handle(WindowEvent e)
                {
                    System.out.println("shown");
                }
            });

            MenuItem item1 = new MenuItem("About");
            item1.setOnAction(new EventHandler<ActionEvent>()
            {
                @Override
                public void handle(ActionEvent e)
                {
                    System.out.println("About");
                }
            });
            MenuItem item2 = new MenuItem("Preferences");
            item2.setOnAction(new EventHandler<ActionEvent>()
            {
                @Override
                public void handle(ActionEvent e)
                {
                    System.out.println("Preferences");
                }
            });

            MenuItem item3 = new MenuItem("Delete row");
            item3.setOnAction(new EventHandler<ActionEvent>()
            {
                @Override
                public void handle(ActionEvent e)
                {
                    // TODO - send SQL query from this code
                    getTableView().getItems().remove(getIndex());
                    System.out.println("Delete row");
                }
            });

            contextMenu.getItems().addAll(item1, item2, item3);

            setContextMenu(contextMenu);
        }

        @Override
        public void startEdit()
        {
            if (!isEmpty())
            {
                super.startEdit();
                createTextField();
                setText(null);
                setGraphic(textField);
                textField.selectAll();
            }
        }

        @Override
        public void cancelEdit()
        {
            super.cancelEdit();

            setText((String) getItem());
            setGraphic(null);
        }

        @Override
        public void updateItem(String item, boolean empty)
        {
            super.updateItem(item, empty);

            if (empty)
            {
                setText(null);
                setGraphic(null);
            }
            else
            {
                if (isEditing())
                {
                    if (textField != null)
                    {
                        textField.setText(getString());
                    }
                    setText(null);
                    setGraphic(textField);
                }
                else
                {
                    setText(getString());
                    setGraphic(null);

                }
            }
        }

        private void createTextField()
        {
            textField = new TextField(getString());
            textField.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);
            textField.focusedProperty().addListener(new ChangeListener<Boolean>()
            {
                @Override
                public void changed(ObservableValue<? extends Boolean> arg0,
                    Boolean arg1, Boolean arg2)
                {
                    if (!arg2)
                    {
                        commitEdit(textField.getText());
                    }
                }
            });
        }

        private String getString()
        {
            return getItem() == null ? "" : getItem().toString();
        }
    }

}

当我双击表格行时,我无法打印任何内容。你能帮我解决这个问题吗?

2 个答案:

答案 0 :(得分:3)

只需将eventFilter添加到EditingCell并将其返回:

Callback<TableColumn<Person, String>, TableCell<Person, String>> cellFactory = new Callback<TableColumn<Person, String>, TableCell<Person, String>>() {
  @Override
  public TableCell<Person, String> call(TableColumn<Person, String> col) { 
    TableCell<Person, String> cell = new EditingCell();
    cell.addEventFilter(...); // same code as you have in the question
    return cell ;
  }
});

也可以在EditingCell的构造函数中添加EventFilter,但这种方法可能更清晰。

答案 1 :(得分:2)

嗯,你回来了错误的单元格

cell.addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
                    @Override
                    public void handle(MouseEvent event) {
                        if (event.getClickCount() > 1) {
                            System.out.println("double clicked!");
                            // TODO GET THE OBJECT AND MAKE SQL QUERY IN ORDER TO MAKE NEW DIALOG WITH
                            TableCell c = (TableCell) event.getSource();
                            System.out.println("Cell text: " + c.getText());
                        }
                    }
                });
                **return new EditingCell(); // replace this with return cell;**
            }
        };