【问题标题】:populate multiple combobox with same model but select diff使用相同的模型填充多个组合框,但选择差异
【发布时间】:2013-08-12 21:06:07
【问题描述】:

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

ComboHBoy.setModel(defaultComboBoxModel);
ComboHGirl.setModel(defaultComboBoxModel);
ComboDHBoy.setModel(defaultComboBoxModel);
ComboDHGirl.setModel(defaultComboBoxModel);

【问题讨论】:

    标签: java swing jcombobox listselectionlistener comboboxmodel


    【解决方案1】:

    仅使用ListModel 来管理您的数据并创建一个基于ListModelComboboxModel 适配器。这个ComboboxModel 只会添加选择功能。请记住,ComboboxModel 扩展了 ListModel。所以很容易适应接口。

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

    例如:

    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);
                }
            }
    
        }
    
    }
    

    然后就这样使用它

    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 中的数据,并且您有不同的选择模型。

    也可以看看The MVC pattern and SWING

    【讨论】:

      【解决方案2】:

      这是因为它们都引用了同一个model,任何model的变化都会影响到所有其他的combo。

      除了每个组合框都有自己的DefaultComboBoxModel之外,没有办法解决这个问题。

      private  DefaultComboBoxModel hBoyModel= new DefaultComboBoxModel();
      private  DefaultComboBoxModel hGirlModel= new DefaultComboBoxModel();
      //....
      ComboHBoy.setModel(hBoyModel);
      ComboHGirl.setModel(hGrilModel);
      //....
      

      【讨论】:

      • depends of,(懒于测试或比较)René Link 的回答
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多