2017-07-25 3 views
0

Je n'arrive pas à bien faire les choses. J'ai un listbox avec des catégories. J'ai aussi un modèle de données qui définit l'ID, le nom, le nom, la catégorie .. et un ObservableList qui contient les données. J'essaie de mettre à jour l'objet existant au cas où l'utilisateur clique sur le même élément dans le listbox et change de nom, nom de famille.Empêcher les doublons dans ObservableList

Voici mon code:

public class FXMLDocController implements Initializable { 

    ObservableList<String> listitems = FXCollections.observableArrayList(
             "Visual Basic", "ASP.net", "JavaFX"); 
    ObservableList<Persons> personData = FXCollections.observableArrayList(); 
    Persons pp = new Persons(); 

    private Label label; 
    @FXML 
    private TextField txtName; 
    @FXML 
    private TextField txtLastName; 
    @FXML 
    private Button btnSave; 
    @FXML 
    private TextArea txtArea; 
    @FXML 
    private ListView<String> listview = new ListView<String>(); 
    @FXML 
    private Button btnTest; 
    @FXML 
    private Label lblCategory; 
    @FXML 
    private Label lblIndex; 



    @Override 
    public void initialize(URL url, ResourceBundle rb) { 
     listview.setItems(listitems); 

    }  

    @FXML 
    private void handleSave(ActionEvent event) { 

     String category = lblCategory.getText(); 
     boolean duplicate = false; 
     //Add data. Check first if personData is empty 

       if (personData.isEmpty()){ 
        pp = new Persons(Integer.valueOf(lblIndex.getText()),category,txtName.getText(),txtLastName.getText()); 
        personData.add(pp); 
       }else{ 
        for(int i = 0 ; i<personData.size() ; i ++){ 
         if(Integer.toString(personData.get(i).getID()).equals(lblIndex.getText())){ 
          duplicate = true; 
         }else{ 
          duplicate = false; 

         } 
        } 
        System.out.println(duplicate); 
        if (duplicate == false){ 
         pp = new Persons(Integer.valueOf(lblIndex.getText()),category,txtName.getText(),txtLastName.getText()); 
         personData.add(pp); 
        }else{ 
         System.out.println("Duplicate"); 
        // Do Update later. 

        } 

       } 

     //Show data to Test 

      System.out.println("-- START OF LIST --"); 
     for (Persons person : personData){ 

      System.out.println(person.getID() + " " + person.getCategory()+ " " + person.getName() + " " + person.getLastname() + " "); 
     } 
     System.err.println(" "); 
    } 


    @FXML 
    private void handleListClick(MouseEvent event) { 
     lblCategory.setText(listview.getSelectionModel().getSelectedItem()); 
     lblIndex.setText(String.valueOf(listview.getSelectionModel().getSelectedIndex())); 
    } 
} 

Si je clique plusieurs fois sur un élément sur la listbox il fonctionne bien .. mais si par exemple je clique sur Visual Basic, puis ASP.net le Retournons Visual Basic l'accepte toujours. :( besoin de conseils et d'aide. S'il vous plaît

Voici le code basé sur la suggestion de Phil

@FXML 
private void handleSave(ActionEvent event) { 

    String category = lblCategory.getText(); 
    boolean duplicate = false; 
    int x = 0; 
    //Add data 

      Persons newPerson = new Persons(Integer.valueOf(lblIndex.getText()), category, txtName.getText(), txtLastName.getText()); 
      if (!personData.contains(newPerson)) { 
       personData.add(newPerson); 

      }else{ 
       System.out.println("Duplicate!"); 
      } 


    //Show data 

     System.out.println("-- START OF LIST --"); 
    for (Persons person : personData){ 

     System.out.println(person.getID() + " " + person.getCategory()+ " " + person.getName() + " " + person.getLastname() + " "); 
    } 

} 

voici ma catégorie des personnes

public class Persons { 
private SimpleIntegerProperty id; 
private SimpleStringProperty name; 
private SimpleStringProperty lastname; 
private SimpleStringProperty category; 



public Persons(){} 
public Persons(int id, String category, String name, String lastname){ 
    this.id = new SimpleIntegerProperty(id); 
    this.name = new SimpleStringProperty(name); 
    this.lastname = new SimpleStringProperty(lastname); 
    this.category = new SimpleStringProperty(category); 


} 
public Persons(String name, String lastname){ 
    this.name = new SimpleStringProperty(name); 
    this.lastname = new SimpleStringProperty(lastname); 
} 

@Override 
public boolean equals(Object o){ 
    if (o == this) return true; 
    if (!(o instanceof Persons)){ 
     return false; 
    } 
    Persons persons = (Persons) o; 

    return persons.id.equals(id) && 
      persons.name.equals(name) && 
      persons.lastname.equals(lastname) && 
      persons.category.equals(category); 

} 


//SETTERS 
public void setID(int id) { 
    this.id = new SimpleIntegerProperty(id); 
} 
public void setName(String name) { 
    this.name = new SimpleStringProperty(name); 
} 
public void setLastname(String lastname) { 
    this.lastname = new SimpleStringProperty(lastname); 
} 
public void setCategory(String category) { 
    this.category = new SimpleStringProperty(category); 
} 

//GETTERS 

public int getID() { 
    return id.getValue(); 
} 

public String getName() { 
    return name.getValue(); 
} 

public String getLastname() { 
    return lastname.getValue(); 
} 
public String getCategory(){ 
    return category.getValue(); 
} 

// PROPERTIES 

public SimpleIntegerProperty idProperty(){ 
    return this.id; 
} 
public SimpleStringProperty nameProperty(){ 
    return this.name; 
} 
public SimpleStringProperty lastnameProperty(){ 
    return this.lastname; 
} 
public SimpleStringProperty categoryProperty(){ 
    return this.category; 
} 

}

+0

Salut, je pense que je l'ai eu. j'ai utilisé 'break' 'pour (int i = 0; i CuteGirlyGeek

Répondre

0

Ok, cela semble bon. juste une petite chose dans votre equals mise en œuvre:

@Override 
public boolean equals(Object o) { 
    if (o == this) return true; 
    if (!(o instanceof Persons)) { 
     return false; 
    } 
    Persons persons = (Persons) o; 

    // persons.id.equals() leads to the default implementation in Object 
    // --> instead use this one. 
    // The Property classes have their own isEqualTo method 
    // with get(), you will get your simple boolean from the returned BooleanBinding 
    return persons.id.isEqualTo(id).get() && 
     persons.name.isEqualTo(name).get() && 
     persons.lastname.isEqualTo(lastname).get() && 
     persons.category.isEqualTo(category).get(); 

} 

La valeur par défaut est égale à la mise en œuvre de l'objet compare juste si elle est la même instance. Et nous créons une nouvelle instance et vérifions avec contains (...) si la liste contient les Persons.

Voici tout le code que je l'habitude de le tester:

public class Main extends Application { 

    private ObservableList<String> listitems = FXCollections.observableArrayList("Visual Basic", "ASP.net", "JavaFX"); 
    private ObservableList<Persons> personData = FXCollections.observableArrayList(); 

    private TextField txtName = new TextField(); 
    private TextField txtLastName = new TextField(); 
    private Button btnSave = new Button("save"); 
    private ListView<String> listview = new ListView<>(); 
    private Label lblCategory = new Label(); 
    private Label lblIndex = new Label(); 

    public static void main(String[] args) { 
     launch(args); 
    } 

    @Override 
    public void start(Stage stage) { 
     listview.setItems(listitems); 
     listview.setOnMouseClicked(this::handleListClick); 
     btnSave.setOnAction(this::handleSave); 

     VBox vb = new VBox(new HBox(5, new Label("Index:"), lblIndex), 
      new HBox(5, new Label("Category:"), lblCategory), 
      new HBox(5, new Label("Name:"), txtName), 
      new HBox(5, new Label("Last name:"), txtLastName) 
     ); 

     BorderPane bp = new BorderPane(); 
     bp.setLeft(listview); 
     bp.setCenter(vb); 
     bp.setRight(btnSave); 

     Scene scene = new Scene(bp, 600, 400); 
     stage.setScene(scene); 
     stage.show(); 
    } 


    private void handleSave(ActionEvent event) { 
     Persons newPerson = new Persons(Integer.valueOf(lblIndex.getText()), lblCategory.getText(), txtName.getText(), txtLastName.getText()); 
     if (!personData.contains(newPerson)) { 
      personData.add(newPerson); 
     } else { 
      System.out.println("Duplicate!"); 
     } 

     System.out.println("-- START OF LIST --"); 
     for (Persons person : personData) { 
      System.out.println(person); 
     } 

    } 

    private void handleListClick(MouseEvent event) { 
     System.out.println("click"); 
     lblCategory.setText(listview.getSelectionModel().getSelectedItem()); 
     lblIndex.setText(String.valueOf(listview.getSelectionModel().getSelectedIndex())); 
    } 


    public class Persons { 
     SimpleIntegerProperty id; 
     SimpleStringProperty name; 
     SimpleStringProperty lastname; 
     SimpleStringProperty category; 

     Persons(int id, String category, String name, String lastname) { 
      this.id = new SimpleIntegerProperty(id); 
      this.name = new SimpleStringProperty(name); 
      this.lastname = new SimpleStringProperty(lastname); 
      this.category = new SimpleStringProperty(category); 
     } 

     @Override 
     public boolean equals(Object o) { 
      if (o == this) return true; 
      if (!(o instanceof Persons)) { 
       return false; 
      } 
      Persons persons = (Persons) o; 

      // persons.id.equals() leads to the default implementation in Object 
      // --> instead use this one. 
      // The Property classes have their own isEqualTo method 
      // with get(), you will get your simple boolean from the returned BooleanBinding 
      return persons.id.isEqualTo(id).get() && 
       persons.name.isEqualTo(name).get() && 
       persons.lastname.isEqualTo(lastname).get() && 
       persons.category.isEqualTo(category).get(); 

     } 

     @Override 
     public String toString() { 
      return "Persons{" + 
       "id=" + id + 
       ", name=" + name + 
       ", lastname=" + lastname + 
       ", category=" + category + 
       '}'; 
     } 
    } 

} 
+0

Merci monsieur Phil, je ne suis pas sûr d'avoir votre suggestion. Pouvez-vous poster l'exemple exact et où le placer? S'il vous plaît. J'ai essayé mais je n'ai pas eu ce que je voulais. :( – CuteGirlyGeek

+0

J'ai mis à jour ma réponse Essayez de comprendre comment fonctionne le concept de la méthode d'égalité – Phil

+0

Merci pour cela, cependant, Il accepte toujours l'entrée de l'utilisateur même s'il est en double Personnes newPerson = new Persons (Integer.valueOf (lblIndex. getText()), catégorie, txtName.getText(), txtLastName.getText()); si (personData.contains (newPerson)) { personData.add (newPerson);} ! else {System.out.println ("Dupliquer!"); } – CuteGirlyGeek