2011-08-29 5 views
7

J'ai une table avec des cases à cocher. Je veux changer la sélection de la case dans la première colonne lorsque je clique sur la case à cocher dans la troisième ou la quatrième colonne. Je veux être en mesure de changer les autres cellules sur la même ligne. J'ai déjà les colonnes, donc je veux savoir dans quelle rangée se trouve la cellule. Je suis également très incertain si je l'ai déjà fait ou non.JavaFX 2: Récupère l'index de ligne TableCell

Ce que je l'ai fait jusqu'à présent je me suis dit principalement de

enter image description here

Voici mon SSCCE (Short Sel f Contained compilable Exemple)

S'il vous plaît me corriger s'il y a quelque chose de mal avec le code ci-dessous.

package javafxapplication5; 

import javafx.application.Application; 
import javafx.beans.property.StringProperty; 
import javafx.collections.FXCollections; 
import javafx.collections.ObservableList; 
import javafx.scene.Group; 
import javafx.scene.Scene; 
import javafx.scene.control.CheckBox; 
import javafx.scene.control.TableCell; 
import javafx.scene.control.TableColumn; 
import javafx.scene.control.TableView; 
import javafx.scene.paint.Color; 
import javafx.stage.Stage; 
import javafx.util.Callback; 

public class JavaFXApplication extends Application { 

    private static final ObservableList<ContactOptions> addContactOption = FXCollections.observableArrayList(
      new ContactOptions("Yes", "John Doe", "No", "Yes"), 
      new ContactOptions("Yes", "Jane Doe", "No", null), 
      new ContactOptions("Yes", "John Smith", "Yes", "Yes"), 
      new ContactOptions("Yes", "Patty Smith", "Yes", "No"), 
      new ContactOptions("Yes", "Jo Johnson", "Yes", "Yes"), 
      new ContactOptions("No", "Mary Johnson", "No", "No"), 
      new ContactOptions("Yes", "Clint Doe", "No", null), 
      new ContactOptions("Yes", "Sally Sue", "No", "Yes"), 
      new ContactOptions("Yes", "Bob Ryan", null, "Yes"), 
      new ContactOptions("No", "Mary Sue", "No", "No"), 
      new ContactOptions("Yes", "Bob Smith", "No", "Yes")); 
    private static TableView<ContactOptions> contactOptions = new TableView<ContactOptions>(); 

    public static void main(String[] args) { 
     Application.launch(JavaFXApplication.class, args); 
    } 

    @Override 
    public void start(Stage primaryStage) { 
     primaryStage.setTitle("Hello World"); 
     Group root = new Group(); 
     Scene scene = new Scene(root, 400, 200, Color.LIGHTGREEN); 

     Callback<TableColumn, TableCell> cellFactory = new Callback<TableColumn, TableCell>() { 

      @Override 
      public TableCell call(final TableColumn param) { 
       final CheckBox checkBox = new CheckBox(); 
       final TableCell cell = new TableCell() { 

        @Override 
        public void updateItem(Object item, boolean empty) { 
         super.updateItem(item, empty); 
         if (item == null) { 
          checkBox.setDisable(true); 
          checkBox.setSelected(false); 
         } else { 
          checkBox.setDisable(false); 
          checkBox.setSelected(item.toString().equals("Yes") ? true : false); 
          commitEdit(checkBox.isSelected() ? "Yes" : "No"); 
         } 
        } 
       }; 
       cell.setNode(checkBox); 
       return cell; 
      } 
     }; 

     TableColumn firstCol = new TableColumn("Contact?"); 
     firstCol.setPrefWidth(60); 
     firstCol.setProperty("one"); 
     firstCol.setCellFactory(cellFactory); 

     TableColumn secondCol = new TableColumn("Name"); 
     secondCol.setPrefWidth(200); 
     secondCol.setSortAscending(true); 
     secondCol.setProperty("two"); 

     TableColumn thirdCol = new TableColumn("Call"); 
     thirdCol.setPrefWidth(60); 
     thirdCol.setProperty("three"); 
     thirdCol.setCellFactory(cellFactory); 

     TableColumn fourthCol = new TableColumn("Email"); 
     fourthCol.setPrefWidth(60); 
     fourthCol.setProperty("four"); 
     fourthCol.setCellFactory(cellFactory); 

     contactOptions.setItems(addContactOption); 
     contactOptions.getColumns().addAll(firstCol, secondCol, thirdCol, fourthCol); 
     contactOptions.setPrefSize(400, 200); 

     root.getChildren().add(contactOptions); 
     primaryStage.setScene(scene); 
     primaryStage.setVisible(true); 
    } 

    public static class ContactOptions { 

     private final StringProperty one; 
     private final StringProperty two; 
     private final StringProperty three; 
     private final StringProperty four; 

     ContactOptions(String col1, String col2, String col3, String col4) { 
      this.one = new StringProperty(col1); 
      this.two = new StringProperty(col2); 
      this.three = new StringProperty(col3); 
      this.four = new StringProperty(col4); 
     } 

     public String getOne() { 
      return one.get(); 
     } 

     public String getTwo() { 
      return two.get(); 
     } 

     public String getThree() { 
      return three.get(); 
     } 

     public String getFour() { 
      return four.get(); 
     } 
    } 
} 

Répondre

6

Presque Il

Avant d'appeler commitEdit, il est nécessaire d'appeler getTableView().edit(getTableRow().getIndex(), param). Cela met la cellule en "mode d'édition". Comme il n'y a pas de méthode startEdit, il y a très peu d'implication dans la saisie du mode d'édition, mais cela reste nécessaire.

Après cela, comme décrit ici: http://download.oracle.com/javafx/2.0/ui_controls/table-view.htm

Il est nécessaire d'appeler

firstCol.setOnEditCommit(new EventHandler<EditEvent<String>>() { 
    @Override 
    public void handle(EditEvent<String> event) { 
     String newValue = event.getNewValue(); 
     ContactOptions data = (ContactOptions) event.getTableView().getItems().get(event.getTablePosition().getRow()); 
     data.one.set(newValue) 
     if(newValue.equals("No")) { 
      data.three.set("No"); 
      data.four.set("No"); 
     } 
    } 
} 

Maintenant, tout ce que je dois savoir est how to update the table's display once the data is updated.

1

Un avantage d'utiliser Observables est que les éléments de l'interface utilisateur JavaFX peuvent effectuer les liaisons pour vous « dans les coulisses. » En d'autres termes, si vous implémentez votre classe de modèle de données en tant que JavaFX Bean, votre interface utilisateur se met automatiquement à jour chaque fois qu'elle change. Il le fait parce que les liaisons pour les données observables dans votre modèle sont automatiquement attribuées et modifient les événements de notification générés automatiquement.

Mais vous devez définir votre modèle de données selon le paradigme de haricot JavaFX pour que cela se produise, sinon votre interface utilisateur ne sera pas mise à jour en fonction des changements.

Votre modèle de données est défini comme ceci:

public static class ContactOptions { 

    private final StringProperty one; 
    private final StringProperty two; 
    private final StringProperty three; 
    private final StringProperty four; 

    ContactOptions(String col1, String col2, String col3, String col4) { 
     this.one = new StringProperty(col1); 
     this.two = new StringProperty(col2); 
     this.three = new StringProperty(col3); 
     this.four = new StringProperty(col4); 
    } 

    public String getOne() { 
     return one.get(); 
    } 

    public String getTwo() { 
     return two.get(); 
    } 

    public String getThree() { 
     return three.get(); 
    } 

    public String getFour() { 
     return four.get(); 
    } 
} 

Pour cette réponse, je vais concentrer uniquement sur votre domaine 1ère instance, un. Pour transformer ce afin qu'il soit conforme au paradigme de haricot JavaFX pour une JavaFX propriété, écrivez votre code de cette façon, par exemple:

public static class ContactOptions { 

    private final StringProperty one = new SimpleStringProperty(); 

    public final String getOne() { return this.one.get(); } 
    public final void setOne(String v) { this.one.set(v); } 
    public final StringProperty oneProperty() { return this.one; } 

Il est possible d'écrire des définitions de propriété pour un haricot JavaFX qui offrent un plus paresseux initialisation, mais cela fonctionnera. La différence entre un bean Java et un bean JavaFX est que vous devez également fournir un accesseur pour la propriété (la dernière ligne ci-dessus).

Si vous convertissez tous vos champs en propriétés similaires à celles ci-dessus, vous constaterez que vos mises à jour de l'interface utilisateur reflètent les modifications.