2016-11-22 6 views
1

ich zwei Arten von Klassen, die X-Klasse erweiternJavaFX benutzerdefinierte ComboBox mit generischer Klasse

public class A extends X 

und

public class B extends X 

Innerhalb meiner JavaFX-Anwendung muss es eine Combobox sein. Dieses Kombinationsfeld wird entweder mit den Klassen A oder B erstellt und verwendet die jeweilige toString() -Methode dieser Klasse zum Auffüllen. Um die Code-Duplizierung zu reduzieren.

Ich versuche, meine aktuelle Methode zur Erzeugung des comboBox zu ändern, so dass es einer ObservableList vom Typ A oder B.

protected ComboBox<? extends X> getComboBox(ObservableList<? extends X> list){ 
    ComboBox<? extends X> comboBox = new ComboBox<>(); 
    comboBox.setItems(list); 
    comboBox.setCellFactory(new Callback<ListView<? extends X>, ListCell<? extends X>>() { 
     @Override 
     public ListCell<Controller> call(ListView<Controller> param) { 

      return new ListCell<? extends X>(){ 
       @Override 
       public void updateItem(Class<? extends X> content, boolean empty){ 
        super.updateItem(content, empty); 
        if(!empty) { 
         setText(content.toString()); 
        } else { 
         setText(null); 
        } 
       } 
      }; 
     } 
    }); 
    return comboBox; 
} 

erlaubt Da sowohl die Klassen eine übergeordnete Klasse haben, ist es möglich, erreichen Sie etwas wie dieses (Und potenziell, aber nicht wesentlich, geben Sie es zurück, da es ursprünglicher Klassentyp ist)

@SillyFly - Ich rufe die Liste auf, die die Reflexionen Abhängigkeit verwendet. Es gibt alle Klassen eines bestimmten Typs (d A)

public ObservableList<A> getAList() { 
    Reflections reflection = new Reflections("com.classes.aClasses"); 
    ObservableList<A> classesList = FXCollections.observableArrayList(); 
    for (Class<? extends A> thisClass : reflection.getSubTypesOf(A.class)) { 
     try { 
      classesList.add(thisClass.newInstance()); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
    return classesList; 
} 
+0

Was ist 'Input'? Ist das die Basisklasse (die du vorher 'X' genannt hast)? – Itai

+0

@sillyfly korrigiert – Eunanibus

Antwort

1

Ich bin mir ziemlich sicher, dass die Standard-ListCell Implementierung verwendet toString Elemente zu machen, so dass eine Zelle Werkseinstellung überflüssig sein kann.

Wie für Ihre Frage - das Problem ist ComboBox<T> benötigt seine items Eigenschaft zu sein ObservableList<T>. Da Sie als Typparameter verwenden, kann der Compiler nicht wissen, ob dies derselbe Typ ist.

Was Sie tun müssen, ist das Verfahren ein generic type parameter geben:

protected <T extends X> ComboBox<T> getComboBox(ObservableList<T> list){ 
    ComboBox<T> comboBox = new ComboBox<>(); 
    comboBox.setItems(list); 
    // Setting a cell factory is probably redundant if you're only using toString... 
    return comboBox; 
} 

Beachten Sie, dass wir einen Typparameter T definieren und sie zwingen, eine Art zu sein, die X erstreckt. Alle generischen Variablen verwenden fortan diesen Typparameter, so dass der Compiler alle Übereinstimmungen kennen kann.

+0

Verstanden auf dem Redundanzaspekt. Ich denke, ich habe das früher aus verschiedenen Gründen implementiert, aber das ergibt jetzt keinen Sinn. jedoch die Methode, die die Liste zurückgibt (die in diesem Verfahren eingesetzt wird) ist: öffentliche ObservableList getAList() - Als ich das bekomme ich die Fehler ObservableList später anrufen kann nicht auf ObservableList Eunanibus

+0

angewendet werden Bitte fügen Sie die andere Methode hinzu und wie Sie die jeweilige Frage selbst aufrufen - es ist schwer zu folgen oder zu wissen, was schiefgelaufen ist, es wäre einfacher, sie mit einem vollständigen Beispiel zu verstehen. – Itai

+0

Ich habe dies zur ursprünglichen Frage für Sie hinzugefügt. Ich benutze das Reflection-Paket, da ich jede Klasse unter einem bestimmten Paket hinzugefügt habe. Im Paket com.animals würde ich beispielsweise dog.class, cat.class, rabbit.class hinzufügen. Das ist Absicht, denn ich möchte, dass jede Klasse in diesem Paket als Option hinzugefügt wird. – Eunanibus