Синхронизированный JList и JComboBox?

В Java Swing, как лучше всего синхронизировать JList и JComboBox с точки зрения данных, т. Е. Иметь один и тот же список элементов в любой момент времени? По сути, если я добавляю элементы в один (или удаляю элементы из него), другой должен автоматически отражать изменения.

Я пытался сделать следующее, но, похоже, это не работает:

JList list = new JList();
JComboBox comboBox = new JComboBox();
DefaultListModel listModel = new DefaultListModel();
// add items to listModel...
list.setModel(listModel);
comboBox.setModel(new DefaultComboBoxModel(listModel.toArray()));

person Vicky Chijwani    schedule 08.02.2011    source источник


Ответы (2)


Ваши модели — ListModel для списка и ComboboxModel для поля со списком — должны быть синхронизированы.

В общем случае это означало бы написание специальной реализации моделей, но в вашем случае вам повезло: DefaultComboBoxModel фактически реализует ListModel, так что вы просто можете использовать один и тот же объект модели для обоих ваших компонентов.

JList list = new JList();
JComboBox comboBox = new JComboBox();
DefaultComboBoxModel listModel = new DefaultComboBoxModel();
// add items to listModel...
list.setModel(listModel);
comboBox.setModel(listModel);
person Paŭlo Ebermann    schedule 08.02.2011
comment
Не могу поверить, что не подумал об этом даже после изучения API. Это сработало отлично. Большое спасибо за твою помощь! - person Vicky Chijwani; 09.02.2011
comment
Аккуратно для синхронизации элементов, но есть ли простой способ также синхронизировать выбранный элемент? - person HpTerm; 15.02.2012
comment
@HpTerm: не так просто. Comboboxmodel сама управляет выбором, а у списка есть отдельная ListSelectionModel. Вы можете создать подкласс DefaultComboboxmodel, реализующий ListSelectionModel, или использовать прослушиватели для синхронизации состояния выбора (но будьте осторожны, чтобы избежать бесконечных циклов). (И вы должны установить режим выбора SINGLE_SELECTION.) - person Paŭlo Ebermann; 15.02.2012
comment
Спасибо за ответ. Мне нужен только SINGLE_SELECTION. Я безуспешно пытался использовать привязки в Netbeans. Теперь у меня есть рабочее решение, но это скорее обходной путь. Вот почему я спрашивал себя, есть ли у кого-то другой способ сделать это, чего я не знал. Спасибо. - person HpTerm; 16.02.2012
comment
Кстати, спасибо за объяснение того, что модель со списком по умолчанию реализует модель списка. Я изо всех сил пытался использовать 2 разные модели и синхронизировать их, так намного проще. Более того, выполнение того, что вы показали, значительно упростило мой обходной путь синхронизации выбранного элемента. - person HpTerm; 16.02.2012

Вы можете сделать так, чтобы они использовали одну и ту же модель, возможно, DefaultComboBoxModel, поскольку она реализует ListModel и, следовательно, должна работать как для JComboBox, так и для JList. Например:

 import java.awt.Dimension;
 import java.awt.GridLayout;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;

 import javax.swing.*;

 public class ShareComboModel {
      private static final int TIMER_DELAY = 2000;

      public static void main(String[] args) {
           SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                     createGui();
                }
           });
      }

      private static void createGui() {
           String[] data = {"Fe", "Fi", "Fo", "Fum"};

           final DefaultComboBoxModel model = new DefaultComboBoxModel(data);

           JComboBox combobox = new JComboBox(model);
           JList jlist = new JList(model);

           new Timer(TIMER_DELAY, new ActionListener() {
                private int count = 0;
                public void actionPerformed(ActionEvent e) {
                     model.addElement("count: " + count);
                     count++;
                }
           }).start();

           JPanel comboPanel = new JPanel();
           comboPanel.add(combobox);

           JPanel listPanel = new JPanel();
           listPanel.add(new JScrollPane(jlist));          

           JPanel panel = new JPanel(new GridLayout(1, 0));
           panel.add(comboPanel);
           panel.add(listPanel);
           panel.setPreferredSize(new Dimension(400, 200));

           JFrame frame = new JFrame("App");
           frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
           frame.getContentPane().add(panel);
           frame.pack();
           frame.setLocationRelativeTo(null);
           frame.setVisible(true);
      }
 }
person Hovercraft Full Of Eels    schedule 08.02.2011