2017-07-19 5 views
0

Ich habe eine ListView und es hat eine ChangeListener zu seiner selectedItemProperty() hinzugefügt. Es ist irgendwie möglich, den Hörer zu entkräften, wenn im Innern des Hörers eine Bedingung truefor Beispiel ist:JavaFx: ungültig ChangeListener

listView.getSelectionModel().selectedItemProperty().addListener(
      (observable, oldValue, newValue) -> { 
       if (thereIsUnsavedData()) { 
        // invalidate somehow so to don't change from item A to B 
       } else{ 
        // load the content of the newValue 
       } 
      }); 

Ich konnte machen, dass nichts tun, wenn die Bedingung erfüllt ist, ändert aber immer noch die Auswahl in listView, und das ist nicht die Lösung zu listView.getSelectionModel(). select (oldValue); weil es den Zuhörer wieder triggert. Irgendeine Idee?

Edit:

So sehe ich es einige Missverständnisse, lässt sie so klären:

Wenn der Benutzer klickt auf ein anderes Element in der listView, die nicht die aktuelle und auf der aktuellen Ansicht ist nicht gespeicherten Daten sind , dann erscheint ein Dialog und fragt den Benutzer: Es sind nicht gespeicherte Daten möchten Sie fortfahren? mit Ja/Nein Antworten. Wenn der Benutzer wählte Ja dann ist alles in Ordnung, lassen Sie ihn die Ansicht ändern, aber wenn er Nein wählte dann sollte die tatsächliche Ansicht gehalten werden. Daher ist jeder Vorschlag, die Elemente zu deaktivieren, in meinem Fall falsch. Ich fand hier eine Lösung ist, aber ich bin nicht sicher, es optimal ist oder nicht:

private ChangeListener<Item> changeListener = 
     (observable, oldValue, newValue) -> { 
      if (thereAreUnsavedData()) { 
       listView.getSelectionModel().selectedItemProperty().removeListener(getListener()); 
       Platform.runLater(() -> { 
        listView.getSelectionModel().select(oldValue); 
        listView.getSelectionModel().selectedItemProperty().addListener(getListener()); 
       }); 
      } else { 
       loadSelected(newValue); 
      } 
     }; 
+0

Betrachtet SelectionModel.selectedItem ist eine [schreibgeschützte Eigenschaft] (http://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/SelectionModel.html#selectedItemProperty), ich nicht denke du kannst seinen Wert beeinflussen. Beachten Sie außerdem, dass das Ändern des Verhaltens eines Standardsteuerelements die Benutzer frustrieren kann. – VGR

+0

Ich möchte seinen Wert nicht ändern, sondern nur aufhören, von einem Element zu einem anderen zu wechseln, wenn eine Bedingung wahr ist, wie Sie in der Frage sehen können. – Sunflame

+0

Sie könnten auch Ihr eigenes 'SelectionModel' schreiben, um die Auswahl" unsave data "unmöglich zu machen. – Jibbow

Antwort

0

So gibt es zwei Lösungen würde ich nicht empfehlen:

  • Verwenden listView.getSelectionModel().select(oldValue); setzen Sie sich auf den alten Wert, aber melde den Listener vorher ab und registriere ihn danach wieder.
  • Alternatively verwenden Sie auch listView.getSelectionModel().select(oldValue);, aber setzen Sie ein Flag, das Sie überprüfen, wenn es den Hörer erneut auslöst.

Beide Lösungen sind fehleranfällig.

Daher würde die Lösung, die ich empfehlen würde, den Benutzer daran hindern, eine Auswahl zu treffen, die derzeit keinen Sinn ergibt, indem das Element in der Liste entfernt oder besser deaktiviert wird. Dies würde die Benutzerfreundlichkeit Ihrer Anwendung verbessern, da die Benutzer nicht frustriert sind, wenn ihre Auswahl rückgängig gemacht wird.

+0

Ich habe etwas ähnliches gemacht, das Sie im ersten Punkt erwähnt haben, also entferne ich den Listener vor '.select()' und füge ihn wieder zurück. Ich habe 'Dialog' mit einer Nachricht so etwas wie: Die Daten wurden nicht gespeichert Möchten Sie fortfahren? mit Ja/Nein Antworten, und wenn der Benutzer Nein trifft, dann möchte ich die Auswahl in der ListView nicht ändern. – Sunflame

+0

Aber ich denke, es sollte eine bessere Lösung dafür geben. – Sunflame

+1

Aus Gründen der Benutzerfreundlichkeit würde ich den Artikel deaktivieren, wenn die Auswahl nicht sinnvoll ist. Überprüfen Sie zum Beispiel [hier] (http: // stackoverflow.com/questions/43998613/javafx-listview-disable-a-spezifizierte-element-of-the-list) für wie dies zu erreichen ist. Wenn die Auswahl zu einer Änderung führt, bei der einige Daten verloren gehen, möchten Sie sich die Daten im Hintergrund merken. Wenn der Benutzer zur vorherigen Auswahl zurückkehrt, verwenden Sie diese Daten erneut. Wie ich schon sagte, möchten Sie vielleicht Ihre Benutzeroberfläche Design überdenken. – mik