2013-04-09 14 views
6

Ho seguito Esempio 13-11 Soluzione alternativa di modifica delle celle da offical tableview tutorial, ma voglio che il mio tableview si comporti come un jtable. Ciò significa che quando una cella viene messa a fuoco, è pronta per essere modificata, e utilizzando i tasti freccia o il tasto Invio dovrebbe immediatamente eseguire il commit della modifica e passare alla cella successiva.Qualcuno ha capito come fare un visual tableview javafx come un jtable?

Questo è quello che ho passato finora:

In primo luogo, ho aggiunto

table.getSelectionModel().setCellSelectionEnabled(true); 

Poi ho cercato di modificare la classe 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(); 
    } 
} 

Il tableview ho ottenuto è un pasticcio - Devo fare clic sul tasto Invio due volte per terminare la modifica, e non impegnerà la modifica, ma la annulla invece.

Qualcuno può indicarmi la giusta direzione?

+0

Sento il tuo dolore ... Non ho lavorato su tabelle javafx in pochi anni, ma qui c'è una briciola di pane che potrebbe essere ciò che stai cercando di fare: http://stackoverflow.com/questions/7880494/Tableview-better-editing di legame-through-/ 7884249 # 7884249 – jkaufmann

risposta

1

Purtroppo in questo tutorial mancano alcune correzioni di codice introdotte successivamente nella classe TextFieldTableCell affinché l'INVIO funzioni correttamente (RT-34685 - Use onAction instead of onKeyPressed e RT-28132 - Call requestFocus()).

Ecco un esempio di lavoro, si tratta di una versione ridotta del codice TextFieldTableCell che utilizza anche Node.fireEvent() per passare alla cella successiva dopo il commit (mima un evento 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(); 
    } 
} 

Spero che questo aiuti!

Problemi correlati