2013-04-09 5 views
6

Я последовал за Пример 13-11 Альтернативное решение редактирования ячеек от offical tableview tutorial, но я хочу, чтобы мой tableview действовал как jtable. Это означает, что когда ячейка получает фокус, она готова к редактированию, а с помощью клавиш со стрелками или клавишей Enter следует немедленно зафиксировать редактирование и перейти к следующей ячейке.Кто-нибудь понял, как сделать табличное представление javafx как jtable?

Это то, что я зашел так далеко:

Во-первых, я добавил

table.getSelectionModel().setCellSelectionEnabled(true); 

Затем я попытался изменить класс EditingCell:

class EditingCell extends TableCell<Person, String> { 

    private TextField textField; 

    public EditingCell() { 
    } 

    @Override 
    public void updateSelected(boolean selected) { 
     super.updateSelected(selected); 
     if (selected) { 
      createTextField(); 
      setText(null); 
      setGraphic(textField); 
      textField.requestFocus(); 
      textField.selectAll(); 
     } else { 
      String value = textField.getText(); 
      if (value != null) { 
       commitEdit(value); 
      } else { 
       commitEdit(null); 
      } 
     } 
    } 


    @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()); 
       } 
      } 
     }); 
     textField.setOnKeyPressed(new EventHandler<KeyEvent>() { 
      @Override 
      public void handle(KeyEvent t) { 
       if ((t.getCode() == KeyCode.ENTER) || (t.getCode() == KeyCode.UP) || (t.getCode() == KeyCode.DOWN) || (t.getCode() == KeyCode.LEFT) || (t.getCode() == KeyCode.RIGHT)) { 
        t.consume(); 
        String value = textField.getText(); 
        if (value != null) { 
         commitEdit(value); 
        } else { 
         commitEdit(null); 
        } 
       } else if (t.getCode() == KeyCode.ESCAPE) { 
        cancelEdit(); 
       } 
      } 
     }); 
    } 

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

tableview меня есть беспорядок - я должен дважды нажать Enter, чтобы завершить редактирование, и он не будет совершать редактирование, а вместо этого отменяет его.

Может ли кто-нибудь указать мне в правильном направлении?

+0

Я чувствую вашу боль ... Я не работал над столами javafx через несколько лет, но вот хлебная крошка, которая может быть тем, что вы пытаетесь сделать: http://stackoverflow.com/questions/7880494/TableView-лучше-редактирование-через-связывающим/7884249 # 7884249 – jkaufmann

ответ

1

К сожалению, в этом учебнике отсутствуют некоторые исправления кода, которые были введены позже в классе TextFieldTableCell для правильной работы ENTER (RT-34685 - Use onAction instead of onKeyPressed и RT-28132 - Call requestFocus()).

Вот рабочий пример, это сокращенный вариант TextFieldTableCell кода, который также использует Node.fireEvent() для перехода к следующей ячейке после окончания фиксации (имитирует KeyPressed события):

class EditingCell extends TableCell<Person, String> 
{ 
    private TextField textField; 

    public EditingCell() 
    { 
    } 

    @Override 
    public void startEdit() 
    { 
     if (!isEditable() || !getTableView().isEditable() 
       || !getTableColumn().isEditable()) 
     { 
      return; 
     } 
     super.startEdit(); 

     if (isEditing()) 
     { 
      if (textField == null) 
      { 
       createTextField(); 
      } 
      setText(null); 
      setGraphic(textField); 
      textField.selectAll(); 
      // requesting focus so that key input can immediately go into 
      // the TextField (see RT-28132) 
      textField.requestFocus(); 
     } 
    } 

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

     // Use onAction here rather than onKeyReleased (with check for 
     // Enter), as otherwise we encounter RT-34685 
     textField.setOnAction(t -> { 
      commitEdit(textField.getText()); 
      t.consume(); 
     }); 
     textField.setOnKeyReleased(t -> { 
      if (t.getCode() == KeyCode.ESCAPE) 
      { 
       cancelEdit(); 
       t.consume(); 
      } 
     }); 

     textField.setOnKeyPressed(new EventHandler<KeyEvent>() 
     { 
      @Override 
      public void handle(KeyEvent t) 
      { 
       if ((t.getCode() == KeyCode.UP) || (t.getCode() == KeyCode.DOWN) 
         || (t.getCode() == KeyCode.LEFT) 
         || (t.getCode() == KeyCode.RIGHT)) 
       { 
        // Commit the current text 
        commitEdit(textField.getText()); 

        // Let's move out simulating a key press in this Cell 
        KeyEvent event = new KeyEvent(t.getSource(), t.getTarget(), 
          KeyEvent.KEY_PRESSED, "", "", t.getCode(), false, false, 
          false, false); 
        EditingCell.this.fireEvent(event); 
       } 
      } 
     }); 
    } 

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

Надеется, что это помогает!