2015-02-13 3 views
0

У меня есть прослушиватель событий в TableView, который прослушивает события мыши. Как я могу получить индекс ячейки с щелчком мыши (и изменить фокус на новую ячейку), когда вызывается событие мыши.TableVew - Выделить ячейку с нажатой клавишей

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

Мне удалось получить индекс щелкнутой ячейки, когда событие мыши находится в ячейке, но не в таблице.

Следующий код может использоваться для получения индекса щелкнутой ячейки, когда событие находится в Ячейке. У меня были проблемы с выбором и изменением фокуса, когда событие мыши находится на 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", "[email protected]")); 
    this.observableListOfPerson.add(new Person("Isabella", "Johnson", "[email protected]")); 
    this.observableListOfPerson.add(new Person("Ethan", "Williams", "ethan.wil[email protected]")); 
    this.observableListOfPerson.add(new Person("Emma", "Jones", "[email protected]")); 
    this.observableListOfPerson.add(new Person("Michael", "Brown", "[email protected]")); 

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

Как правило, если вы хотите получить информацию о клетке с помощью мыши необходимо зарегистрировать слушателя мыши на ячейку. Можете ли вы объяснить больше «С одним щелчком ничего не происходит» (возможно, создайте простой, полный пример, показывающий проблему). Если я зарегистрирую прослушиватель мыши для щелчка на ячейке таблицы, он отображает текущую сфокусированную ячейку в качестве этой ячейки. –

+0

Я могу получить текущую выбранную/сфокусированную ячейку. Я также могу получить индекс или щелкнув по ячейке. Проблема в том, что я пытаюсь изменить фокус на ячейку с щелчком. Он не меняет фокус на щелканную ячейку индекса. Я думаю, что проблема связана с тем, что ячейка пуста. Поэтому я попытался добавить объект при щелчке по ячейке. Еще одна проблема. – breaktop

+0

Да, вы нажимаете границы предполагаемого прецедента «TableView» здесь. «TableView» предназначен для просмотра набора данных, с которыми вы можете манипулировать. В этом контексте нет смысла фокусироваться на ячейке, которая пуста, и, как правило, API не поддерживает это. Ваше обходное решение (добавление новых элементов в модель данных) немного проблематично: нет реальной гарантии того, что добавление новых данных приводит к тому, что текущая ячейка используется для представления правильных данных из-за повторного использования соты. –

ответ

0

Попробуйте это:

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

Я пробовал это. Проблема в том, что он дает ячейку, которая уже сфокусирована/выбрана. Я пытаюсь получить индекс ячейки, который не был выбран/сфокусирован, но щелкнула ячейку, которая, в свою очередь, вызвала событие. Проблема здесь в том, что ее щелчок таблицы вызывает событие. Должен быть способ получить TableCell, который зависал, когда событие было выброшено. – breaktop

+0

Вы пытаетесь редактировать заполненную ячейку или редактировать пустое одним нажатием кнопки? –

+0

Я пытался сфокусироваться на щелкнутой ячейке (даже если ячейка пуста, то есть ее нельзя кликать). Когда вы нажимаете на ячейку, вы можете получить индекс независимо от того, пуст ли он или нет. То, как мне удалось работать (я не думаю, что это хороший способ), прислушайтесь к событию клика. Если ячейка пуста, добавьте пустые данные (это может быть пустая строка в зависимости от данных, которые принимает ячейка). Затем смените фокус на щелканную ячейку. – breaktop

Смежные вопросы