2013-04-09 46 views
6

我跟着例13-11細胞編輯的替代解決方案offical tableview tutorial,但我想我的tableview行爲像jtable。這意味着當一個單元格獲得焦點時,就可以編輯了,然後使用箭頭鍵或Enter鍵立即提交編輯並移動到下一個單元格。有沒有人想過如何使一個javafx tableview行爲像一個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 2013-06-19 03:36:34

回答

1

不幸的是,教程缺少一些代碼修復,這些修補後來在TextFieldTableCell類中引入,以便ENTER正常工作(RT-34685 - Use onAction instead of onKeyPressedRT-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(); 
    } 
} 

希望這有助於!

相關問題