2009-04-13 22 views
15

Tôi có một hộp thả xuống trong GUI của tôi, hiển thị nội dung của một ArrayList trong một lớp khác. Đối tượng mới có thể được thêm vào ArrayList ở nơi khác trong GUI, vì vậy tôi cần biết khi nào nó được cập nhật, vì vậy tôi có thể làm mới menu thả xuống. Từ những gì tôi có thể thu thập, hai lựa chọn của tôi là mở rộng lớp ArrayList để cho phép tôi thêm changeListener của riêng mình vào nó, hoặc để làm cho lớp có chứa ArrayList trong câu hỏi mở rộng quan sát được.Tôi có nên sử dụng Trình nghe hoặc Quan sát viên không?

Giải pháp nào thích hợp hơn?

+1

Bạn đang đề cập đến một JComboBox? Nếu vậy, tôi sẽ nhìn vào ComboBoxModel và triển khai của nó. – Avrom

Trả lời

10

Hai giải pháp cơ bản triển khai của các mẫu thiết kế cùng một gốc (các "Observer" mẫu theo quy định của Gang of Four.) Trong trường hợp trước đây, bạn đang làm cho bản thân ArrayList "có thể quan sát", trong trường hợp thứ hai bạn đang tạo đối tượng miền sử dụng danh sách mảng "có thể quan sát được".

Xu hướng của tôi sẽ là làm điều sau: làm cho đối tượng miền có thể quan sát được. Điều này chủ yếu là vì cuối cùng bạn có thể có những thứ khác có thể thay đổi về đối tượng miền (mà GUI sẽ được cập nhật.) Nếu nó đã được quan sát, bạn đã được thiết lập.

Lưu ý rằng bạn không hoàn toàn phải mở rộng java.util.Observable - bạn có thể triển khai mẫu thiết kế mà không làm điều đó.

+0

Điều này có vẻ là cách dễ nhất, Cảm ơn tất cả các câu trả lời khác mặc dù. – Simonw

9

Việc triển khai Observable trong Java hiếm khi được sử dụng và không liên kết tốt với Swing. Sử dụng một số EventListener để thay thế.

Cụ thể, có lý do không để mở rộng AbstractListModel hoặc thậm chí sử dụng DefaultListModel trực tiếp khi quản lý nội dung của danh sách "ở nơi khác trong GUI"? Sau đó, hộp kết hợp của bạn có thể sử dụng một ComboBoxModel đại biểu cho cùng một trường hợp ListModel, thêm việc triển khai của chính nó để theo dõi trạng thái lựa chọn.

tôi có trong tâm trí một cái gì đó như thế này (nhưng tôi đã không kiểm tra nó):

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

Luôn thích thành phần hơn phần mở rộng (tham chiếu của tôi là java hiệu quả và kinh nghiệm cá nhân của tôi). việc mở rộng ArrayList chỉ đơn giản là một lời hứa rằng bạn sẽ không vi phạm bất kỳ lớp bất biến nào. Nó cũng liên kết bạn với việc triển khai danh sách cụ thể mà bạn đang mở rộng.

0

Bạn có thể chuyển sang sử dụng GUI design pattern. Hoặc xây dựng triển khai có giới hạn.

Tạo một giao diện mẫu giao diện mà có một DrawXArrayList phương pháp (với X là một số tên đầy ý nghĩa Nó có một tham số kiểu ArrayList

Tạo một lớp mới gọi là GUIView Nó có ít nhất hai phương pháp:.. UpdateXArrayList, và RegisterForm

Khi bạn khởi tạo ứng dụng của bạn có form GUI tự đăng ký với lớp thực hiện GUIView. làm cho lớp thực hiện GUIView nhìn thấy được bằng hình thức.

Khi bất cứ điều gì trong mẫu GUI của bạn cập nhật ArrayList có nó gọi UpdateXArrayList như điều cuối cùng nó làm. e UpdateXArrayList phương pháp trong lớp thực hiện GUIView sau đó sẽ lần lượt gọi DrawXArrayList đi qua danh sách array cập nhật. DrawXArrayList trong lớp biểu mẫu thực hiện GUIFormInterface sau đó sẽ thực hiện các bước cần cập nhật điều khiển hiển thị ArrayList.

Mặc dù điều này có vẻ như nhiều bước so với thiết lập người quan sát và người nghe.Bạn có nhiều quyền kiểm soát hơn đối với các hành động của người dùng khác nhau ảnh hưởng đến giao diện người dùng như thế nào sau đó là mẫu người quan sát người nghe. Ngoài ra, bạn đã ghi lại, trong mã, sự tương tác giữa hành động của người dùng và các cập nhật cho giao diện người dùng.

2

Tại sao không sử dụng các ràng buộc?

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

Liên kết tiện ích GUI của bạn với Danh sách. Thay đổi sẽ đẩy lùi giữa hai đối tượng một cách minh bạch. Hãy chắc chắn để bọc mô hình của bạn với một quan sát thích hợp, chẳng hạn như WritableList (nếu sử dụng ArrayList trực tiếp).

0

Nếu bạn có thể thêm lọ mới vào ứng dụng, hãy kiểm tra glazed Lists

Các vấn đề liên quan