2009-04-13 7 views
15

내 GUI에 다른 클래스의 ArrayList 내용을 표시하는 드롭 다운 상자가 있습니다. GUI의 다른 곳에서 ArrayList에 새 객체를 추가 할 수 있으므로 업데이트시기를 알아야하므로 드롭 다운 메뉴를 새로 고칠 수 있습니다. 내가 수집 할 수있는 두 가지 옵션은 ArrayList 클래스를 확장하여 내 자신의 changeListener를 추가하거나 문제의 ArrayList를 포함하는 클래스를 관찰 가능하도록 확장하는 것입니다.리스너 또는 옵저버를 사용해야합니까?

어느 것이 더 적절한 해결책입니까?

+1

glazed Lists 당신이 JComboBox를 참조하고 체크 아웃? 그렇다면 ComboBoxModel 및 해당 구현을 살펴볼 것입니다. – Avrom

답변

10

두 솔루션 (본질적으로 "관찰자"패턴 동일한 루트 디자인 패턴의 구현입니다 전자의 경우에는 ArrayList 자체를 "관찰 가능"하게 만들고, 후자에서는 배열 목록을 사용하는 도메인 객체를 "관찰 가능"하게 만듭니다.

내 경향은 후자를 수행하는 것입니다. 도메인 개체를 관찰 가능하게 만듭니다. 이것은 주로 도메인 객체 (GUI가 업데이트되어야하는)에 대해 바뀔 수있는 다른 것들이 있기 때문입니다. 이미 관찰 가능하다면 이미 설정되어 있습니다.

java.util.Observable을 엄격하게 확장 할 필요는 없습니다. 디자인 패턴을 구현하지 않고 구현할 수 있습니다.

+0

이것은 가장 쉬운 방법처럼 보이지만, 다른 모든 답변을 주셔서 감사합니다. – Simonw

9

Java의 Observable 구현은 거의 사용되지 않으며 Swing과 잘 작동하지 않습니다. 대신 EventListener을 사용하십시오.

특히 GUI의 다른 곳에서 목록의 내용을 관리 할 때 AbstractListModel을 확장하지 않거나 DefaultListModel을 직접 사용하지 않는 이유가 있습니까? 그런 다음 콤보 상자에서 동일한 ListModel 인스턴스에 위임하는 ComboBoxModel을 사용하여 자체 구현을 추가하여 선택 상태를 추적 할 수 있습니다.

는이 같은 마음 뭔가있다 (하지만 난 그것을 테스트하지 않은)에 의해 정의 된

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

항상 확장자보다 구성이 더 좋습니다 (내 참조는 효과적인 자바와 개인적인 경험입니다). extends ArrayList는 불변 클래스를 위반하지 않는다는 단순한 약속입니다. 또한 확장중인 특정 목록 구현에 사용자를 바인딩합니다.

0

GUI design pattern으로 전환 할 수 있습니다. 또는 제한된 구현을 구성하십시오. ..

그것은 적어도 두 가지 방법이 있습니다 그것은

이 GUIView라는 새로운 클래스를 만듭니다 형의 ArrayList의 매개 변수가 X가 어떤 meaningfull 이름되고있는 방법 DrawXArrayList을 (가지고있는 GUI 양식 인터페이스를 만들기 : UpdateXArrayList을하고, RegisterForm

응용 프로그램을 초기화

GUI를 양식 GUIView를 구현하는 클래스에 자신을 등록한다. 폼에 GUIView 표시 구현하는 클래스를 확인해야합니다.

당신의 GUI 형태로 어떤이의 ArrayList를 업데이트

그것으로 UpdateXArrayList 전화가 그것이하는 마지막 일. Th 그런 다음 GUIView를 구현하는 클래스의 UpdateXArrayList 메소드가 업데이트 된 arraylist를 전달하는 DrawXArrayList를 호출합니다. GUIFormInterface를 구현하는 폼 클래스의 DrawXArrayList는 ArrayList를 표시하는 컨트롤을 업데이트해야합니다.

이것은 관찰자 및 수신기 설정과 비교할 때 많은 단계처럼 보입니다.다양한 사용자 동작이 관측자 - 수신기 패턴 이후 UI에 미치는 영향을보다 효과적으로 제어 할 수 있습니다. 또한 코드에서 사용자 작업과 UI 업데이트 간의 상호 작용을 문서화했습니다.

2

왜 바인딩을 사용합니까? 귀하의 목록에 GUI 위젯 바인딩

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

. 변경 사항은 두 객체간에 투명하게 전파됩니다. WritableList (ArrayList를 직접 사용하는 경우)와 같은 적절한 관찰 가능 모델로 모델을 래핑해야합니다.

0

응용 프로그램에 새 항아리를 추가 할 수 있습니다,