关于Java:使用相同的模型填充多个组合框,但选择diff

populate multiple combobox with same model but select diff

ComboBox出现问题,我用相同的模型填充了多个ComboBox es,但是当我运行程序并从一个ComboBox中选择一个值时,其余部分会选择相同的值。

1
2
3
4
ComboHBoy.setModel(defaultComboBoxModel);
ComboHGirl.setModel(defaultComboBoxModel);
ComboDHBoy.setModel(defaultComboBoxModel);
ComboDHGirl.setModel(defaultComboBoxModel);

这是因为它们都引用了相同的模型,因此对模型的任何更改都会影响所有其他组合。

除了每个组合框都有自己的DefaultComboBoxModel,没有其他方法可以解决此问题。

1
2
3
4
5
6
private  DefaultComboBoxModel hBoyModel= new DefaultComboBoxModel();
private  DefaultComboBoxModel hGirlModel= new DefaultComboBoxModel();
//....
ComboHBoy.setModel(hBoyModel);
ComboHGirl.setModel(hGrilModel);
//....


仅使用ListModel来管理数据,并创建基于ListModelComboboxModel适配器。此ComboboxModel将仅添加选择功能。请记住,ComboboxModel扩展了ListModel。因此很容易修改接口。

唯一棘手的部分是处理更新事件。

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
public class ListAdapterComboboxModel implements ComboBoxModel {

    private ListModel dataModel;
    private Object selectedObject;
    private DataModelListDataListenerAdapter listDataListenerAdapter;

    public ListAdapterComboboxModel(ListModel ListModel) {
        dataModel = ListModel;
        this.listDataListenerAdapter = new DataModelListDataListenerAdapter();
        dataModel.addListDataListener(listDataListenerAdapter);
    }

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

    public Object getElementAt(int index) {
        return dataModel.getElementAt(index);
    }

    public void addListDataListener(ListDataListener l) {
        listDataListenerAdapter.addListDataListener(l);
    }

    public void removeListDataListener(ListDataListener l) {
        listDataListenerAdapter.removeListDataListener(l);
    }

    public void setSelectedItem(Object anObject) {
        if ((selectedObject != null && !selectedObject.equals(anObject))
                || selectedObject == null && anObject != null) {
            selectedObject = anObject;
            ListDataEvent e = new ListDataEvent(this,
                    ListDataEvent.CONTENTS_CHANGED, -1, -1);
            listDataListenerAdapter.delegateListDataEvent(e);
        }
    }

    public Object getSelectedItem() {
        return selectedObject;
    }

    private class DataModelListDataListenerAdapter implements ListDataListener {

        protected EventListenerList listenerList = new EventListenerList();

        public void removeListDataListener(ListDataListener l) {
            listenerList.remove(ListDataListener.class, l);
        }

        public void addListDataListener(ListDataListener l) {
            listenerList.add(ListDataListener.class, l);

        }

        public void intervalAdded(ListDataEvent e) {
            delegateListDataEvent(e);
        }

        public void intervalRemoved(ListDataEvent e) {
            checkSelection(e);
            delegateListDataEvent(e);
        }

        public void contentsChanged(ListDataEvent e) {
            checkSelection(e);
            delegateListDataEvent(e);
        }

        private void checkSelection(ListDataEvent e) {
            Object selectedItem = getSelectedItem();
            ListModel listModel = (ListModel) e.getSource();
            int size = listModel.getSize();
            boolean selectedItemNoLongerExists = true;
            for (int i = 0; i < size; i++) {
                Object elementAt = listModel.getElementAt(i);
                if (elementAt != null && elementAt.equals(selectedItem)) {
                    selectedItemNoLongerExists = false;
                    break;
                }
            }
            if (selectedItemNoLongerExists) {
                ListAdapterComboboxModel.this.selectedObject = null;
            }
        }

        protected void delegateListDataEvent(ListDataEvent lde) {
            ListDataListener[] listeners = listenerList
                    .getListeners(ListDataListener.class);
            for (ListDataListener listDataListener : listeners) {
                listDataListener.contentsChanged(lde);
            }
        }

    }

}

然后像这样使用它

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class ComboboxModelTest extends JFrame{

    public static void main(String[] args) {
        ComboboxModelTest comboboxModelTest = new ComboboxModelTest();
        comboboxModelTest.pack();
        comboboxModelTest.setVisible(true);
    }

    public ComboboxModelTest() {
        Container contentPane = getContentPane();
        contentPane.setLayout(new FlowLayout());

        DefaultListModel defaultListModel = new DefaultListModel();
        defaultListModel.addElement("Element 1");
        defaultListModel.addElement("Element 2");

        ComboBoxModel firstComboboxModel = new ListAdapterComboboxModel(defaultListModel);
        ComboBoxModel secondComboboxModel = new ListAdapterComboboxModel(defaultListModel);
        JComboBox jComboBox1 = new JComboBox(firstComboboxModel);
        JComboBox jComboBox2 = new JComboBox(secondComboboxModel);

        contentPane.add(jComboBox1);
        contentPane.add(jComboBox2);
    }
}

然后,您只需要在一个ListModel中管理数据,就可以拥有不同的选择模型。

也请看一下MVC模式和SWING。