在两个JComboBox之间共享相同的模型 [英] Sharing same model between two JComboBoxes

查看:136
本文介绍了在两个JComboBox之间共享相同的模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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



我使用了以下代码。

 人p1 =新人(史密斯,smith @mail.com); 
人p2 =新人(Tom,tom@gmail.com);
人p3 =新人(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 和覆盖 getElementAt()方法,如下所示。

 公共类MyModel扩展DefaultComboBoxModel< Object> {

public MyModel(Object [] items){
super(items);
}

@Override
public Object getElementAt(int index){
if(super.getElementAt(index)instanceof Person){
return(Person )super.getElementAt(索引);
} else {
返回null;
}
}

}



上面的ComboBoxModel只给我Person对象。



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

解决方案

使用 ComboBoxModel的一个实例和两个 JComboBox 的实例,每个实例都具有相同的模型。让每个 JComboBox 都有一个自定义

  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/372​​22598/230513
* /
公共类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),
新人(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);
}

私有静态类PersonRenderer扩展DefaultListCellRenderer {

函数< 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);
人p =(人)价值;
l.setText(personAttribute.apply(p));
返回l;
}
}

私有静态类人员{

私人最终字符串名称;
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);
}
}


I have a Person [ ] with three Persons (p1,p2,p3). Person class has two attributes name and email.

I want to add all names of Person[] in one JComboBox and all emails in another JComboBox.

I used the following code.

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

But I don't want to used like this. I'd like to use the two combo boxes with the same model. I tried with DefaultComboBoxModel and Override getElementAt() method like the following.

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

}

The above ComboBoxModel give me only the Person objects.

The Question is how can I add all names of Person[] in one JComboBox and all emails in another JComboBox using same ComboBoxModel .

解决方案

Use one instance of ComboBoxModel and two instances of JComboBox, each having the same model. Let each JComboBox have a custom renderer that displays the desired Person attribute for that JComboBox.

In the example below, each combo gets its own instance of a single renderer that implements the strategy pattern, passing a Function<Person, String> that selects the correct attribute when the renderer is called:

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

这篇关于在两个JComboBox之间共享相同的模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆