2016-05-14 3 views
2

У меня есть Лицо [] с тремя лицами (p1, p2, p3). Класс лица имеет два атрибута имя и email.Совместное использование одной модели между двумя JComboBoxes

Я хочу добавить все имена Person [] в один JComboBox и все письма в другой JComboBox.

Я использовал следующий код.

Person p1 = new Person("Smith", "[email protected]"); 
    Person p2 = new Person("Tom", "[email protected]"); 
    Person p3 = new Person("John","[email protected]"); 

    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() метод вроде следующего.

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.

Вопрос: как я могу добавить все имена Person [] в один JComboBox и все письма в другом JComboBox , используя тот же ComboBoxModel.

ответ

5

Используйте один экземпляр ComboBoxModel и два экземпляра JComboBox, каждый из которых имеет одинаковую модель. Пусть каждый JComboBox имеет пользовательский renderer, который отображает желаемый атрибут Person для этого JComboBox.

В приведенном ниже примере, каждый комбо получает свой собственный экземпляр одного визуализатора, который реализует strategy pattern, передавая 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)); 

image

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", "[email protected]"), 
      new Person("Bethe", "[email protected]"), 
      new Person("Gammow", "[email protected]")}); 
     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); 
    } 
} 
+1

Спасибо за подробное объяснение .... вы мне очень помогли :-) –