动态组合框问题

时间:2012-08-03 10:53:25

标签: java swing jtable jcombobox

您好我正在使用两列即仪器和方法的表。单击一个按钮,我将在每个单元格中添加一行作为编辑器的组合框。此外,那些组合框将具有actionlistener。就像我选择乐器时一样,应该改变方法组合框列表。我只使用两个组合框,每次添加行时我都会实例化它。我的问题是每当我添加一个新行时,现有的行组合都会重新加载最新的值。这意味着,即使我以不同方式实例化它,组合框也是唯一的。动态创建组合框的方法是什么,它应该具有自己的值。在下面发布我的代码供您参考。

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

2 个答案:

答案 0 :(得分:5)

感谢您提供新代码。这非常有帮助。

我和你的考试一起玩并重写它以便与编辑合作。

注意以下部分:

  1. 测试。我删除了subComboBox,你不需要它。我删除了mainComboBox的actionListener。
  2. MyComBobBoxEditor。我实现了方法getTableCellEditorComponent()。这是编辑器中的主要方法。在这个方法中,我检查当前行中选择了哪个乐器,并为特定乐器准备编辑器组合框。
  3. 此示例尚未包含可编辑的组合框。但我希望它会对你有所帮助。

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

答案 1 :(得分:3)

首先,每次添加行时都不需要调用setCellEditor()setCellRenderer()。创建表后必须调用此方法一次。

其次,添加行时不应创建组合框。更好的方法是在MyComboBoxEditor.getCellEditorComponent()方法中创建组合框。

我认为你的问题导致MyComboBoxEditor的执行错误。 当您创建新行时,您将替换表中所有单元格的现有TableCellEditor和现有组合框编辑器,而不仅仅是添加。 TableCellEditor按需为每个单元格提供编辑器组件。它必须为特定单元格准备编辑器组件并将其返回。但我想你的MyComboBoxEditor会向每个单元格返回相同的组件。 你能提供MyComboBoxEditor的代码来确定吗?

看看这个question。我希望它会有所帮助。