在两个 JComboBoxes 之间共享相同的模型
Sharing same model between two JComboBoxes
我有一个 Person [ ] 和三个 Persons (p1,p2,p3)。 Person class 有两个属性 name 和 email.
我想在一个 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 对象。
问题是如何使用相同的 ComboBoxModel 在一个 JComboBox 中添加 Person[] 的所有名称,在另一个 JComboBox 中添加所有电子邮件。
使用一个 ComboBoxModel
实例和两个 JComboBox
实例,每个实例都具有相同的模型。让每个 JComboBox
都有一个自定义 renderer,显示 JComboBox
所需的 Person
属性。
在下面的示例中,每个组合都有自己的单个渲染器实例,该渲染器实现 strategy pattern, passing a Function<Person, String>
,在调用渲染器时选择正确的属性:
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
*/
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);
}
}
我有一个 Person [ ] 和三个 Persons (p1,p2,p3)。 Person class 有两个属性 name 和 email.
我想在一个 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 对象。
问题是如何使用相同的 ComboBoxModel 在一个 JComboBox 中添加 Person[] 的所有名称,在另一个 JComboBox 中添加所有电子邮件。
使用一个 ComboBoxModel
实例和两个 JComboBox
实例,每个实例都具有相同的模型。让每个 JComboBox
都有一个自定义 renderer,显示 JComboBox
所需的 Person
属性。
在下面的示例中,每个组合都有自己的单个渲染器实例,该渲染器实现 strategy pattern, passing a Function<Person, String>
,在调用渲染器时选择正确的属性:
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
*/
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);
}
}