2016-09-27 9 views
6

Mam dwa obiekty ListView s, allStudentsList, które już są w nim zapełnione, currentStudentList nie ma żadnych. Moim celem, gdy użytkownik wybierze element w allStudentList, jest przeniesienie tego elementu do currentStudentList. Zrobiłem to poprzez umieszczenie słuchacza w modelu wyboru allStudentList.Jak przenosić elementy między dwoma ListViews z przesłuchiwaczem zmian JavaFX

Otrzymuję IndexOutOfBoundsException i nie jestem pewien, dlaczego tak się dzieje. Z testowania wydaje się, że problem ten jest izolowany do ostatnich 4 linii tej metody, ale nie jestem pewien dlaczego.

allStudentsList.getSelectionModel().selectedItemProperty() 
     .addListener((observableValue, oldValue, newValue) -> { 
      if (allStudentsList.getSelectionModel().getSelectedItem() != null) { 

       ArrayList<String> tempCurrent = new ArrayList<>(); 
       for (String s : currentStudentList.getItems()) { 
        tempCurrent.add(s); 
       } 

       ArrayList<String> tempAll = new ArrayList<>(); 
       for (String s : allStudentsList.getItems()) { 
        tempAll.add(s); 
       } 

       tempAll.remove(newValue); 
       tempCurrent.add(newValue); 

       // clears current studentlist and adds the new list 
       if (currentStudentList.getItems().size() != 0) { 
        currentStudentList.getItems().clear(); 
       } 
       currentStudentList.getItems().addAll(tempCurrent); 

       // clears the allStudentList and adds the new list 
       if (allStudentsList.getItems().size() != 0) { 
        allStudentsList.getItems().clear(); 
       } 
       allStudentsList.getItems().addAll(tempAll); 
      } 
     }); 
+0

Która linia rzuca wyjątek? –

+0

allStudents.getItems(). Clear(); – Philayyy

+0

allStudentsList.getItems(). AddAll (tempAll); – Philayyy

Odpowiedz

3

Jak szybko naprawić można owinąć części kodu, które modyfikują list artykuł w Platform.runLater(...) bloku:

Platform.runLater(() -> { 
    // clears current studentlist and adds the new list 
    if (currentStudentList.getItems().size() != 0) 
     currentStudentList.getItems().clear(); 

    currentStudentList.getItems().addAll(tempCurrent); 
}); 

Platform.runLater(() -> { 
    // clears the allStudentList and adds the new list 
    if (allStudentsList.getItems().size() != 0) 
     allStudentsList.getItems().clear(); 

    allStudentsList.getItems().addAll(tempAll); 
}); 

Problem polega na tym, że nie można zmienić wybór podczas zmiany wybór jest przetwarzany . Po usunięciu wszystkich elementów za pomocą allStudentsList.getItems().clear();, wybór zmieni się (wybrany indeks będzie -1), wspomniany warunek zostanie spełniony. To właśnie blokuje użycie bloku Platform.runLater(...) przez "odłożenie" modyfikacji.

Ale całe obsługi mogą być wymieniane z

allStudentsList.getSelectionModel().selectedItemProperty().addListener((obs, oldValue, newValue) -> { 
    if (newValue != null) { 

     Platform.runLater(() -> { 
      allStudentsList.getSelectionModel().select(-1); 
      currentStudentList.getItems().add(newValue); 
      allStudentsList.getItems().remove(newValue); 
     }); 
    } 
}); 

ustawia wybrany indeks -1: nic nie jest zaznaczone w ListView aby uniknąć zmiany na inną pozycję przy usuwaniu aktualnego jednego (zrobiono to w sposób dorozumiany w twojej wersji poprzez wyczyszczenie listy), następnie dodaje aktualnie wybrany element do "wybranej listy", a następnie usuwa bieżący element z "listy wszystkich elementów". Wszystkie te działania są zawijane w wymienionym bloku Platform.runLater(...).

+1

Idealny, działa na leczeniu! Pozdrawiam za wyjaśnienie – Philayyy

Powiązane problemy