TableVew - 选择并关注单击的单元格

时间:2015-02-13 09:14:38

标签: java javafx mouseevent tableview javafx-8

我在TableView上有一个侦听鼠标事件的事件监听器。当抛出鼠标事件时,如何获取鼠标单击的单元格索引(并将焦点更改为新单元格)。

public class PrnTableController
{
    @FXML
    private TableView<SimpleStringProperty> table;
    @FXML
    private TableColumn<SimpleStringProperty, String> data;

    @FXML
    private void initialize()
    {
        this.data.setCellValueFactory(cellData -> cellData.getValue());
        this.data.setCellFactory(event -> new EditCell(this.observablePrnPropertyData, this.table));

        // Add mouse Listener
        this.table.setOnMouseClicked(event -> this.handleOnMouseClick(event));
    }

    private void handleOnMouseClick(MouseEvent event)
    {
        TableView tv = (TableView) event.getSource();

        // TODO : get the mouse clicked cell index
        int index = ???

        if (event.getButton().equals(MouseButton.PRIMARY))
        {
            if (event.getClickCount() == 2)
            {
                LOGGER.info("Double clicked on cell");

                final int focusedIndex = this.table.getSelectionModel().getFocusedIndex();
                if (index == focusedIndex)
                {
                     // TODO : Double click
                }
            }
            else if (event.getClickCount() == 1)
            {
                // TODO : Single click
            }
        }
    }
}

当鼠标事件位于Cell但不是表格时,我已设法获取单击的单元格索引。

当事件在Cell上时,可以使用以下代码获取单击的单元格索引。当鼠标事件在TabelCell上时,我遇到了选择和更改焦点的问题。焦点不会改变为新细胞。如果双击,它会改变。只需单击一下就不会发生任何事我怀疑那是因为我有其他事件监听器,可能会有相互冲突的事件。我在TableCell上有以下事件 - setOnDragDetected,setOnMouseDragEntered和TableView上的以下事件 - addEventFilter,setOnKeyPressed,setOnEditCommit。

TableCell<Map<String, SimpleStringProperty>, String> cell = (TableCell<Map<String, SimpleStringProperty>, String>) mouseEvent.getSource();
int index = cell.getIndex();

这是一个问题的例子。基本上,当您单击一个单元格时,您可以看到该事件已注册但没有任何反应。我的意思是焦点确实会改变到新点击的单元格。

public class TableViewEditOnType extends Application
{
private TableView<Person> table;
private ObservableList<Person> observableListOfPerson;

@Override
public void start(Stage primaryStage)
{

    this.table = new TableView<>();

    this.table.getSelectionModel().setCellSelectionEnabled(true);
    this.table.setEditable(true);

    TableColumn<Person, String> firstName = this.createColumn("First Name", Person::firstNameProperty);
    TableColumn<Person, String> lastName = this.createColumn("Last Name", Person::lastNameProperty);
    TableColumn<Person, String> email = this.createColumn("Email", Person::emailProperty);
    this.table.getColumns().add(firstName);
    this.table.getColumns().add(lastName);
    this.table.getColumns().add(email);

    this.observableListOfPerson = FXCollections.observableArrayList();
    this.observableListOfPerson.add(new Person("Jacob", "Smith", "jacob.smith@example.com"));
    this.observableListOfPerson.add(new Person("Isabella", "Johnson", "isabella.johnson@example.com"));
    this.observableListOfPerson.add(new Person("Ethan", "Williams", "ethan.williams@example.com"));
    this.observableListOfPerson.add(new Person("Emma", "Jones", "emma.jones@example.com"));
    this.observableListOfPerson.add(new Person("Michael", "Brown", "michael.brown@example.com"));

    this.table.getItems().addAll(this.observableListOfPerson);

    firstName.setOnEditCommit(event -> this.editCommit(event, "firstName"));
    lastName.setOnEditCommit(event -> this.editCommit(event, "lastName"));
    email.setOnEditCommit(event -> this.editCommit(event, "email"));

    this.table.setOnKeyPressed(event -> {
        TablePosition<Person, ?> pos = this.table.getFocusModel().getFocusedCell();
        if (pos != null)
        {
            this.table.edit(pos.getRow(), pos.getTableColumn());
        }
    });

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

private void editCommit(CellEditEvent<Person, String> event, String whatEdited)
{
    if (whatEdited.equals("firstName"))
    {
        event.getTableView().getItems().get(event.getTablePosition().getRow()).setFirstName(event.getNewValue());
    }
    else if (whatEdited.equals("lastName"))
    {
        event.getTableView().getItems().get(event.getTablePosition().getRow()).setLastName(event.getNewValue());
    }
    else if (whatEdited.equals("email"))
    {
        event.getTableView().getItems().get(event.getTablePosition().getRow()).setEmail(event.getNewValue());
    }
}

private TableColumn<Person, String> createColumn(String title, Function<Person, StringProperty> property)
{
    TableColumn<Person, String> col = new TableColumn<>(title);
    col.setCellValueFactory(cellData -> property.apply(cellData.getValue()));

    col.setCellFactory(column -> new EditCell(property, this.table, this.observableListOfPerson));

    return col;
}

private static class EditCell extends TableCell<Person, String>
{

    private final TextField textField = new TextField();

    private final Function<Person, StringProperty> property;

    private TableView table;
    private ObservableList<Person> observableListOfPerson;

    EditCell(Function<Person, StringProperty> property, TableView table, ObservableList<Person> observableListOfPerson)
    {
        this.property = property;
        this.table = table;
        this.observableListOfPerson = observableListOfPerson;

        this.textProperty().bind(this.itemProperty());
        this.setGraphic(this.textField);
        this.setContentDisplay(ContentDisplay.TEXT_ONLY);

        this.textField.setOnAction(evt -> {
            this.commitEdit(this.textField.getText());
        });
        this.textField.focusedProperty().addListener((obs, wasFocused, isNowFocused) -> {
            if (!isNowFocused)
            {
                this.commitEdit(this.textField.getText());
            }
        });

        // On mouse click event

        this.setOnMouseClicked(mouseEvent -> this.handleCellMouseClick(mouseEvent));
    }

    private void handleCellMouseClick(final MouseEvent mouseEvent)
    {
        System.out.println("MOUSE EVENT");

        TableCell<Map<String, SimpleStringProperty>, String> cell = (TableCell<Map<String, SimpleStringProperty>, String>) mouseEvent.getSource();
        int index = cell.getIndex();
        // Set up the map data structure before editing
        this.validCell(index);
        if (mouseEvent.getButton().equals(MouseButton.PRIMARY))
        {
            if (mouseEvent.getClickCount() == 2)
            {
                System.out.println("Double clicked on cell");

                final int focusedIndex = this.table.getSelectionModel().getFocusedIndex();
                if (index == focusedIndex)
                {
                    this.changeTableCellFocus(this.table, index);
                }
            }
            else if (mouseEvent.getClickCount() == 1)
            {
                System.out.println("Single click on cell");

                this.changeTableCellFocus(this.table, index);

            }
        }
    }

    private void validCell(final int cellIndex)
    {
        if (cellIndex >= this.observableListOfPerson.size())
        {
            for (int x = this.observableListOfPerson.size(); x <= cellIndex; x++)
            {
                this.observableListOfPerson.add(new Person("", "", ""));

            }
        }
    }

    public void changeTableCellFocus(final TableView<?> table, final int focusIndex)
    {
        table.requestFocus();
        table.getSelectionModel().clearAndSelect(focusIndex);
        table.getFocusModel().focus(focusIndex);
    }

    @Override
    public void startEdit()
    {
        super.startEdit();
        this.textField.setText(this.getItem());
        this.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
        this.textField.requestFocus();
    }

    @Override
    public void cancelEdit()
    {
        super.cancelEdit();
        this.setContentDisplay(ContentDisplay.TEXT_ONLY);
    }

    @Override
    public void commitEdit(String text)
    {
        super.commitEdit(text);
        Person person = this.getTableView().getItems().get(this.getIndex());
        StringProperty cellProperty = this.property.apply(person);
        cellProperty.set(text);
        this.setContentDisplay(ContentDisplay.TEXT_ONLY);
    }

}

public static class Person
{
    private final StringProperty firstName = new SimpleStringProperty();
    private final StringProperty lastName = new SimpleStringProperty();
    private final StringProperty email = new SimpleStringProperty();

    public Person(String firstName, String lastName, String email)
    {
        this.setFirstName(firstName);
        this.setLastName(lastName);
        this.setEmail(email);
    }

    public final StringProperty firstNameProperty()
    {
        return this.firstName;
    }

    public final java.lang.String getFirstName()
    {
        return this.firstNameProperty().get();
    }

    public final void setFirstName(final java.lang.String firstName)
    {
        this.firstNameProperty().set(firstName);
    }

    public final StringProperty lastNameProperty()
    {
        return this.lastName;
    }

    public final java.lang.String getLastName()
    {
        return this.lastNameProperty().get();
    }

    public final void setLastName(final java.lang.String lastName)
    {
        this.lastNameProperty().set(lastName);
    }

    public final StringProperty emailProperty()
    {
        return this.email;
    }

    public final java.lang.String getEmail()
    {
        return this.emailProperty().get();
    }

    public final void setEmail(final java.lang.String email)
    {
        this.emailProperty().set(email);
    }

}

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

1 个答案:

答案 0 :(得分:0)

试试这个:

TableCell tc = (TableCell) event.getSource();
int index = tc.getIndex();