2009-04-13 16 views
15

Mam pole rozwijane w moim GUI, który pokazuje zawartość ArrayList w innej klasie. Nowe obiekty można dodać do tablicy ArrayList w innym miejscu interfejsu GUI, więc muszę wiedzieć, kiedy jest ona aktualizowana, aby można było odświeżyć menu rozwijane. Z tego co mogę zebrać, moje dwie opcje to rozszerzenie klasy ArrayList, aby umożliwić mi dodanie do niej własnego changeListener lub uczynienie klasy, która zawiera przedmiot ArrayList, możliwym do zaobserwowania.Czy powinienem używać odbiornika lub obserwatora?

Jakie byłoby bardziej odpowiednie rozwiązanie?

+1

Czy odnosząc się do JComboBox? Jeśli tak, to zajrzę do ComboBoxModel i jego implementacji. – Avrom

Odpowiedz

10

Oba rozwiązania są zasadniczo implementacje tego samego wzorca projektowego korzeń (dalej „Observer” wzór zdefiniowany przez Gang Czterech). W pierwszym przypadku tworzysz obiekt ArrayList jako "obserwowalny", w tym ostatnim tworzysz obiekt domeny, który używa listy tablic "obserwowalne".

Moja skłonność polegałaby na zrobieniu tego drugiego: uczynienie obiektu domeny możliwym do zaobserwowania. Dzieje się tak przede wszystkim dlatego, że możesz ostatecznie mieć inne rzeczy, które mogą się zmienić w obiekcie domeny (dla których GUI powinien zostać zaktualizowany). Jeśli jest już zauważalny, jesteś już ustawiony.

Pamiętaj, że nie musisz koniecznie przedłużać java.util.Observable - możesz zaimplementować wzór projektu bez robienia tego.

+0

To wydaje się najłatwiejszy sposób, dziękuję za wszystkie inne odpowiedzi. – Simonw

9

Implementacja Observable w Javie jest rzadko używana i nie współpracuje dobrze ze Swingiem. Zamiast tego użyj EventListener.

Czy istnieje powód, aby nie przedłużać AbstractListModel lub nawet używać DefaultListModel bezpośrednio podczas zarządzania zawartością listy "w innym miejscu interfejsu GUI"? Wtedy twoje pole kombi może użyć numeru ComboBoxModel, który deleguje do tej samej instancji ListModel, dodając własną implementację, aby śledzić stan zaznaczenia.

mam na myśli coś takiego (ale nie mam go przetestować):

final class MyComboBoxModel 
    extends AbstractListModel 
    implements ComboBoxModel 
{ 

    private final ListModel data; 

    private volatile Object selection; 

    MyComboBoxModel(ListModel data) { 
    /* 
    * Construct this object with a reference to your list, 
    * which contents are managed somewhere else in the UI. 
    */ 
    this.data = data; 
    data.addListDataListener(new ListDataListener() { 
     public void contentsChanged(ListDataEvent evt) { 
     fireContentsChanged(this, evt.getIndex0(), evt.getIndex1()); 
     } 
     public void intervalAdded(ListDataEvent evt) { 
     fireContentsChanged(this, evt.getIndex0(), evt.getIndex1()); 
     } 
     public void intervalRemoved(ListDataEvent evt) { 
     fireContentsChanged(this, evt.getIndex0(), evt.getIndex1()); 
     } 
    }); 
    } 

    public void setSelectedItem(Object selection) { 
    this.selection = selection; 
    fireContentsChanged(this, 0, data.getSize() - 1); 
    } 

    public Object getSelectedItem() { return selection; } 

    public int getSize() { return data.getSize(); } 

    public Object getElementAt(int idx) { return data.getElementAt(idx); } 

} 
1

Zawsze wolisz kompozycję niż rozszerzenie (moim odniesieniem jest efektywna Java i moje osobiste doświadczenie). rozszerzenie ArrayList jest po prostu obietnicą, że nie naruszysz żadnej z klas niezmienników. Wiąże również użytkownika z konkretną implementacją listy, którą rozszerzasz.

0

Można przełączyć na używanie GUI design pattern. Lub skonstruuj ograniczoną implementację.

utworzyć interfejs GUI formularz, który ma DrawXArrayList metodą (z X jedne meaningfull nazwa Ma parametry typu ArrayList

utworzyć nową klasę o nazwie GUIView Posiada co najmniej dwie metody:.. UpdateXArrayList i RegisterForm

Podczas inicjalizacji aplikacji mają GUI Formularz zarejestrować się z klasą realizacji GUIView. Bądź klasę wykonawczą GUIView widoczne na formularzu.

Kiedy coś w formularzu GUI aktualizuje ArrayList mieć go nazwać UpdateXArrayList jako ostatnia rzecz, jaką robi Metoda UpdateXArrayList w klasie implementującej GUIView następnie wywoła DrawXArrayList przekazując zaktualizowaną listę tablic. DrawXArrayList w klasie formularzy implementującej interfejs GUIFormInterface podejmie kroki, aby zaktualizować kontrolkę wyświetlającą ArrayList.

Chociaż wydaje się, że jest to dużo kroków w porównaniu do konfiguracji obserwatora i słuchacza.Masz większą kontrolę nad tym, jak różne działania użytkownika wpływają na interfejs użytkownika, a następnie na schemat obserwatora-słuchacza. Ponadto udokumentowałeś w kodzie interakcję między działaniem użytkownika a aktualizacjami interfejsu użytkownika.

2

Dlaczego nie używać wiązań?

http://wiki.eclipse.org/index.php/JFace_Data_Binding

Bind widżet GUI do listy. Zmiany będą przezroczyście przenosić między dwoma obiektami. Pamiętaj, aby zawinąć model z odpowiednim obserwowalnym obiektem, takim jak WritableList (jeśli korzystasz bezpośrednio z ArrayList).

Powiązane problemy