【问题标题】:Sharing same model between two JComboBoxes在两个 JComboBoxes 之间共享相同的模型
【发布时间】:2016-05-14 04:08:32
【问题描述】:

我有一个 Person [ ] 和三个 Person (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<String> combo1 = new JComboBox<String>();
    JComboBox<String> combo2 = new JComboBox<String>();

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

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

public class MyModel extends DefaultComboBoxModel<Object> {

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[] 的所有名称,在另一个 JComboBox 中添加所有电子邮件使用相同的 ComboBoxModel

【问题讨论】:

    标签: java swing jcombobox comboboxmodel


    【解决方案1】:

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

    在下面的示例中,每个组合都有自己的单个渲染器实例,该实例实现了strategy pattern,并在调用渲染器时传递了一个选择正确属性的Function&lt;Person, String&gt;

    DefaultComboBoxModel model = new DefaultComboBoxModel(…);
    JComboBox<String> combo1 = new JComboBox<>(model);
    combo1.setRenderer(new PersonRenderer(Person::getName));
    JComboBox<String> 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<String> combo1 = new JComboBox<>(model);
            combo1.setRenderer(new PersonRenderer(Person::getName));
            JComboBox<String> 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<Person, String> personAttribute;
    
            public PersonRenderer(Function<Person, String> 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);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2022-01-06
      • 1970-01-01
      • 2010-10-22
      • 1970-01-01
      • 2019-10-08
      • 2016-06-15
      • 1970-01-01
      • 2017-10-30
      • 1970-01-01
      相关资源
      最近更新 更多