Проблема с динамическим полем со списком

Привет, я использую таблицу, в которой два столбца, а именно инструмент и метод. По нажатию кнопки я добавлю строку с полем со списком в качестве редактора в каждую ячейку. Кроме того, в этом поле со списком будет прослушиватель действий. Например, когда я выбираю инструмент, список методов должен измениться. Я использую только два поля со списком и создаю их каждый раз, когда добавляю строку. Моя проблема заключается в том, что всякий раз, когда я добавляю новую строку, существующие комбинации строк перезагружаются с последним значением. Это означает, что поля со списком уникальны, хотя я создаю их по-разному. Как можно динамически создать поле со списком, которое должно иметь собственные значения. Размещение моего кода ниже для справки.

addItem.addActionListener(new ActionListener() {

        public void actionPerformed(ActionEvent arg0) {
            comboInstrument = new CeNComboBox();
            comboMethod = new CeNComboBox();
            TableColumn instrumentColumn = table.getColumn("Instrument Used");
            TableColumn methodColumn = table.getColumn("Method Title");
            comboInstrument.removeAllItems();
            listInstruments = analyticalUtil.getInstruments(listAnalysisSummaryPrefs);
            iterateInstruments = listInstruments.iterator();
            while(iterateInstruments.hasNext()){
                comboInstrument.addItem(iterateInstruments.next());
            }
            dtm.addRow(new Object[]{" "," "});
            comboInstrument.setEditable(true);
            instrumentColumn.setCellEditor(new MyComboBoxEditor(comboInstrument));
            instrumentColumn.setCellRenderer(new MyComboBoxRenderer());
            comboMethod.setEditable(true);
            methodColumn.setCellEditor(new MyComboBoxEditor(comboMethod));
            methodColumn.setCellRenderer(new MyComboBoxRenderer());

            comboInstrument.addActionListener(new ActionListener(){
                public void actionPerformed(ActionEvent argEvent){
                    comboInstrumentActionPerformed();
                }
            });
            comboMethod.addActionListener(new ActionListener(){
                public void actionPerformed(ActionEvent argEvent){
                    comboMethodActionPerformed();
                }
            });
        }
    });

MyComboBoxEditor.java

public class MyComboBoxEditor extends DefaultCellEditor {



    public MyComboBoxEditor(JComboBox combobox) {
        super(combobox);
    }
}

Я очень новичок в Swing. Пожалуйста, помогите мне.

Добавлен пример кода с жестко заданными значениями. Если вы запустите это, вы поймете мою проблему. Протестируйте таким образом. 1. Выберите значение из первого столбца, первой строки и выберите значение из другого столбца. 2. Сделайте то же самое во второй строке и теперь проверьте второй столбец первой строки. Все значения будут перезагружены на основе выбора, сделанного для второй строки. Это проблема, с которой я сталкиваюсь. Приведенный ниже код скопирован и отредактирован из следующей ссылки JComboBox Action listener

private static final long serialVersionUID = 1L;
        private JComboBox mainComboBox;
        private JComboBox subComboBox;
        private Hashtable<Object, Object> subItems = new Hashtable<Object, Object>();

        public Testing() {
            String[] items = {"","Select Item", "Color", "Shape", "Fruit", "Size"};
            mainComboBox = new JComboBox(items);
            mainComboBox.addActionListener(this);
            mainComboBox.addItemListener(this);
            mainComboBox.setEditable(true);
            //prevent action events from being fired when the up/down arrow keys are used
            //mainComboBox.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
//          getContentPane().add(mainComboBox, BorderLayout.WEST);
            subComboBox = new JComboBox();//  Create sub combo box with multiple models
            subComboBox.setPrototypeDisplayValue("XXXXXXXXXX"); // JDK1.4
            subComboBox.addItemListener(this);
//          getContentPane().add(subComboBox, BorderLayout.CENTER);
            String[] subItems1 = {"Select Color", "Red", "Blue", "Green"};
            subItems.put(items[1], subItems1);
            String[] subItems2 = {"Select Shape", "Circle", "Square", "Triangle"};
            subItems.put(items[2], subItems2);
            String[] subItems3 = {"Select Fruit", "Apple", "Orange", "Banana"};
            subItems.put(items[3], subItems3);
            String[] subItems4 = {"Select Size", "Big", "Middle", "Small"};
            subItems.put(items[4], subItems4);
            DefaultTableModel model = new DefaultTableModel(new String[]{"Instrument Used","Method Title"},0);
            JTable table = new JTable(model);
            table.getColumn("Instrument Used").setCellEditor(new MyComboBoxEditor(mainComboBox));
            table.getColumn("Instrument Used").setCellRenderer(new MyComboBoxRenderer());
            table.getColumn("Method Title").setCellEditor(new MyComboBoxEditor(subComboBox));
            table.getColumn("Method Title").setCellRenderer(new MyComboBoxRenderer());
            model.addRow(new String[]{""});
            model.addRow(new String[]{""});
            getContentPane().add(table, BorderLayout.CENTER);
        }

        public void actionPerformed(ActionEvent e) {
            String item = (String) mainComboBox.getSelectedItem();
            JOptionPane.showMessageDialog(null, "Action Performed "+item);
            Object o = subItems.get(item);
            if (o == null) {
                subComboBox.setModel(new DefaultComboBoxModel());
            } else {
                subComboBox.setModel(new DefaultComboBoxModel((String[]) o));
            }
        }

        public void itemStateChanged(ItemEvent e) {
            if (e.getStateChange() == ItemEvent.SELECTED) {
                if (e.getSource() == mainComboBox) {
                    if (mainComboBox.getSelectedIndex() != 0) {
                        FirstDialog firstDialog = new FirstDialog(Testing.this,
                                mainComboBox.getSelectedItem().toString(), "Please wait,  Searching for ..... ");
                    }
                } 
            }
        }

        private class FirstDialog extends JDialog {

            private static final long serialVersionUID = 1L;

            FirstDialog(final Frame parent, String winTitle, String msgString) {
                super(parent, winTitle);
                //setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
                JLabel myLabel = new JLabel(msgString);
                JButton bNext = new JButton("Stop Processes");
                add(myLabel, BorderLayout.CENTER);
                add(bNext, BorderLayout.SOUTH);
                bNext.addActionListener(new ActionListener() {

                    public void actionPerformed(ActionEvent evt) {
                        setVisible(false);
                    }
                });
                javax.swing.Timer t = new javax.swing.Timer(1000, new ActionListener() {

                    public void actionPerformed(ActionEvent e) {
                        setVisible(false);
                    }
                });
                t.setRepeats(false);
                t.start();
                setLocationRelativeTo(parent);
                setSize(new Dimension(400, 100));
                setVisible(true);
            }
        }

        public static void main(String[] args) {
            JFrame frame = new Testing();
            frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }

person Developer404    schedule 03.08.2012    source источник


Ответы (2)


Спасибо за новый код. Это очень полезно.

Я играю с вашим примером и переписываю его для правильной работы с редактором.

Обратите внимание на следующие части:

  1. Тестирование. Я удаляю subComboBox, он здесь не нужен. Я удаляю actionListener для mainComboBox.
  2. MyComBobBoxEditor. Я реализую метод getTableCellEditorComponent(). Это основной метод в редакторе. В этом методе я проверяю, какой инструмент выбран в текущей строке, и подготавливаю поле со списком редактора для конкретного инструмента.

Этот пример еще не включает редактируемые поля со списком. Но я надеюсь, что это будет полезно для вас.

public class Testing extends JFrame implements ItemListener{
    private static final long serialVersionUID = 1L;
        private JComboBox mainComboBox;
        private Hashtable<Object, Object> subItems = new Hashtable<Object, Object>();

        public Testing() {
            String[] items = {"","Select Item", "Color", "Shape", "Fruit", "Size"};
            mainComboBox = new JComboBox(items);
            mainComboBox.addItemListener(this);
            mainComboBox.setEditable(true);
            String[] subItems1 = {"Select Color", "Red", "Blue", "Green"};
            subItems.put(items[2], subItems1);
            String[] subItems2 = {"Select Shape", "Circle", "Square", "Triangle"};
            subItems.put(items[3], subItems2);
            String[] subItems3 = {"Select Fruit", "Apple", "Orange", "Banana"};
            subItems.put(items[4], subItems3);
            String[] subItems4 = {"Select Size", "Big", "Middle", "Small"};
            subItems.put(items[5], subItems4);
            DefaultTableModel model = new DefaultTableModel(new String[]{"Instrument Used","Method Title"},0);
            JTable table = new JTable(model);
            table.getColumn("Instrument Used").setCellEditor(new DefaultCellEditor(mainComboBox));
            //table.getColumn("Instrument Used").setCellRenderer(new MyComboBoxRenderer());
            table.getColumn("Method Title").setCellEditor(new MyComboBoxEditor());
            //table.getColumn("Method Title").setCellRenderer(new MyComboBoxRenderer());
            model.addRow(new String[]{""});
            model.addRow(new String[]{""});
            getContentPane().add(table, BorderLayout.CENTER);
        }

       public void itemStateChanged(ItemEvent e) {
            if (e.getStateChange() == ItemEvent.SELECTED) {
                if (e.getSource() == mainComboBox) {
                    if (mainComboBox.getSelectedIndex() != 0) {
                        FirstDialog firstDialog = new FirstDialog(Testing.this,
                                mainComboBox.getSelectedItem().toString(), "Please wait,  Searching for ..... ");
                    }
                } 
            }
        }

        private class FirstDialog extends JDialog {

            private static final long serialVersionUID = 1L;

            FirstDialog(final Frame parent, String winTitle, String msgString) {
                super(parent, winTitle);
                //setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
                JLabel myLabel = new JLabel(msgString);
                JButton bNext = new JButton("Stop Processes");
                add(myLabel, BorderLayout.CENTER);
                add(bNext, BorderLayout.SOUTH);
                bNext.addActionListener(new ActionListener() {

                    public void actionPerformed(ActionEvent evt) {
                        setVisible(false);
                    }
                });
                javax.swing.Timer t = new javax.swing.Timer(1000, new ActionListener() {

                    public void actionPerformed(ActionEvent e) {
                        setVisible(false);
                    }
                });
                t.setRepeats(false);
                t.start();
                setLocationRelativeTo(parent);
                setSize(new Dimension(400, 100));
                setVisible(true);
            }
        }

        public static void main(String[] args) {
            JFrame frame = new Testing();
            frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }

    class MyComboBoxEditor extends AbstractCellEditor implements TableCellEditor, ItemListener {

            private JComboBox editorComboBox;

            public MyComboBoxEditor() {
                editorComboBox = new JComboBox();
            editorComboBox.addItemListener(this);
            }

            public Object getCellEditorValue()
            {
                return editorComboBox.getSelectedItem();
            }

            public Component getTableCellEditorComponent(JTable table,
                    Object value,
                    boolean isSelected,
                    int row,
                    int column)
            {
                // which instrument is selected?
                String instrument = (String) table.getValueAt(row, 0);
                String[] methods = (String[]) subItems.get(instrument);
                editorComboBox.setModel(new DefaultComboBoxModel(methods));
                editorComboBox.setSelectedItem(value);
                return editorComboBox;
            }

        public void itemStateChanged(ItemEvent e)
        {
            stopCellEditing();
        }
        }
}
person Nestor    schedule 07.08.2012
comment
Какие события вы имеете в виду? EditingStopped и editingCancelled уже реализованы в AbstractCellEditor. - person Nestor; 09.08.2012
comment
Я посмотрел на это. Все, что я нахожу, это огонь stopCellEditing, когда comboBox изменил выбранный элемент. Я согласен, будет лучше, если я добавлю это в код. - person Nestor; 09.08.2012
comment
Спасибо .. Он работает нормально. Событие изменения состояния элемента для поля со списком редактора не запускается - person Developer404; 09.08.2012
comment
Извините, я не понимаю, что вы имеете в виду здесь Событие изменения состояния элемента для поля со списком редактора не запускается. Вам нужен дополнительный слушатель столбца метода редактирования, остановленного? Если это так, добавьте еще один ItemListener в editorComboBox. Или добавьте CellEditorListener к MyComboBoxEditor и добавьте свой код в его метод editingStopped(). - person Nestor; 09.08.2012
comment
В зависимости от выбранного метода мне нужно изменить другую текстовую область. Итак, для этого я пытаюсь использовать событие itemstatechanged, чтобы получить выбранный элемент в поле со списком редактора. - person Developer404; 09.08.2012
comment
Большое спасибо. Я понял. Я использую как editor.editorComboBox.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if(editor.editorComboBox.getSelectedItem()!=null) JOptionPane.showMessageDialog(null, editor. editorComboBox.getSelectedItem().toString());} }); - person Developer404; 09.08.2012

Во-первых, вам не нужно вызывать setCellEditor(), setCellRenderer() каждый раз, когда вы добавляете строку. Этот метод должен быть вызван один раз после создания таблицы.

Во-вторых, вы не должны создавать поле со списком при добавлении строки. Лучше всего создать поле со списком в методе MyComboBoxEditor.getCellEditorComponent().

Я предполагаю, что причиной ваших проблем является неправильная реализация MyComboBoxEditor. Когда вы создаете новую строку, вы заменяете существующие TableCellEditor и существующие редакторы со списком для всех ячеек в таблице, а не только для добавления. TableCellEditor предоставить компонент редактора для каждой ячейки по запросу. Он должен подготовить компонент редактора для конкретной ячейки и вернуть его. Но я полагаю, что ваш MyComboBoxEditor возвращает один и тот же компонент в каждую ячейку. Можете ли вы предоставить код MyComboBoxEditor, чтобы убедиться?

Посмотрите на этот вопрос. Я надеюсь, что это будет полезно.

person Nestor    schedule 03.08.2012
comment
Я пытался. Но все же я загружаю последние значения для последнего поля со списком. Я новичок в свинге. Я не делаю все вещи. :-( - person Developer404; 07.08.2012
comment
В порядке. Попробуй снова. Давайте укажем некоторую точку в вашем приложении. 1. Элементы, установленные в comboInstrument, одинаковы для всех строк? 2. Пункты, установленные в comboMethod, зависят только от выбранного значения инструмента? - person Nestor; 07.08.2012
comment
да. Вы обряд. В зависимости от выбранного инструмента будут загружены методы. Инструмент и метод также доступны для редактирования. Также может быть добавлен новый инструмент или метод. - person Developer404; 07.08.2012
comment
Хорошо. Другой вопрос. Если я добавляю новый инструмент или метод в какую-то строку, должен ли он отображаться в полях со списком в других строках? Появляется как возможное значение, а не как выбранное? конечно. - person Nestor; 07.08.2012
comment
Нет, это не требуется. Потому что значения поля со списком будут извлечены из базы данных для инструмента. Поэтому, когда он нажимает «Сохранить», новый добавленный инструмент должен появиться в каждой строке. - person Developer404; 07.08.2012