在两个JComboBox之间共享相同的模型

我有一个有三个人的人[] (p1,p2,p3)。 Person类有两个属性nameemail

我想在一个JComboBox中添加Person []的所有名称,在另一个JComboBox中添加所有电子邮件。

我使用了以下代码。

Person p1 = new Person("Smith", "smith@mail.com"); Person p2 = new Person("Tom", "tom@gmail.com"); Person p3 = new Person("John","john@mail.com"); Person[] per_arr = new Person[] { p1, p2, p3}; JFrame frame = new JFrame(); JPanel panel = new JPanel(); JComboBox combo1 = new JComboBox(); JComboBox combo2 = new JComboBox(); for (Person p : per_arr) { combo1.addItem(p.getName()); combo2.addItem(p.getEmail()); } panel.add(combo1); panel.add(combo2); frame.setContentPane(panel); frame.pack(); frame.setVisible(true); 

但我不想这样使用。 我想使用具有相同型号的两个combobox。 我尝试使用DefaultComboBoxModel和Override getElementAt()方法,如下所示。

 public class MyModel extends DefaultComboBoxModel { public MyModel(Object[] items) { super(items); } @Override public Object getElementAt(int index) { if (super.getElementAt(index) instanceof Person) { return (Person)super.getElementAt(index); } else { return null; } } 

}

上面的ComboBoxModel只给我Person对象。

问题是我如何在一个JComboBox中添加Person []的所有名称,并使用相同的ComboBoxModel在另一个JComboBox中添加所有电子邮件。

使用ComboBoxModel一个实例和两个JComboBox实例,每个实例具有相同的模型。 让每个JComboBox都有一个自定义渲染器 ,显示该JComboBox所需的Person属性。

在下面的示例中,每个组合获取其实现策略模式的单个渲染器的自己的实例,传递一个Function ,在调用渲染器时选择正确的属性:

 DefaultComboBoxModel model = new DefaultComboBoxModel(…); JComboBox combo1 = new JComboBox<>(model); combo1.setRenderer(new PersonRenderer(Person::getName)); JComboBox combo2 = new JComboBox<>(model); combo2.setRenderer(new PersonRenderer(Person::getEmail)); 

图片

 import java.awt.Component; import java.awt.EventQueue; import java.awt.FlowLayout; import java.util.function.Function; import javax.swing.DefaultComboBoxModel; import javax.swing.DefaultListCellRenderer; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JList; /** * @see http://stackoverflow.com/a/37222598/230513 */ public class ComboRendererTest { private void display() { JFrame f = new JFrame("Test"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setLayout(new FlowLayout()); DefaultComboBoxModel model = new DefaultComboBoxModel(new Person[]{ new Person("Alpher", "alpher@example.com"), new Person("Bethe", "bethe@example.com"), new Person("Gammow", "gammow@example.com")}); JComboBox combo1 = new JComboBox<>(model); combo1.setRenderer(new PersonRenderer(Person::getName)); JComboBox combo2 = new JComboBox<>(model); combo2.setRenderer(new PersonRenderer(Person::getEmail)); f.add(combo1); f.add(combo2); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); } private static class PersonRenderer extends DefaultListCellRenderer { Function personAttribute; public PersonRenderer(Function personAttribute) { this.personAttribute = personAttribute; } @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { JLabel l = (JLabel) super.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus); Person p = (Person) value; l.setText(personAttribute.apply(p)); return l; } } private static class Person { private final String name; private final String email; public Person(String name, String email) { this.name = name; this.email = email; } public String getName() { return name; } public String getEmail() { return email; } } public static void main(String[] args) { EventQueue.invokeLater(new ComboRendererTest()::display); } }