2012-08-03 97 views
2

嗨我正在使用一个表,其中两列即仪器和方法。点击一个按钮,我会在每个单元格中添加一行组合框作为编辑器。另外,这些组合框会有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); 
    } 
} 

我很新的摆动。请帮助我。

添加一些带硬编码值的示例代码。如果你运行这个,你会明白我的问题。以这种方式进行测试。 1.从第一列第一行中选择一个值,然后从另一列中选择值。 2.在第二行做相同的操作,现在检查第一行的第二列。所有的值将根据第二行的选择重新加载。 这是我面临的问题。下面的代码复制并编辑从以下链接 ​​

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

回答

5

谢谢你的新代码。这非常有帮助。

我和你的examlpe一起玩,并将其改写为与编辑器正常工作。

注意以下部分:

  1. 测试。我删除subComboBox,你不需要在这里。我删除mainComboBox的actionListener。
  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(); 
     } 
     } 
} 
+0

您认为哪些事件?已在'AbstractCellEditor'中实现的EditingStopped和editingCancelled – Nestor 2012-08-09 07:00:08

+0

我看着它。所有我发现当comboBox改变其选择的项目时,会触发'stopCellEditing'。我同意,如果我将它添加到代码中会更好。 – Nestor 2012-08-09 07:27:44

+0

谢谢..它工作正常。编辑器组合框的项目状态更改事件没有被触发 – Nila 2012-08-09 09:48:40

3

首先,你需要doen't调用setCellEditor()setCellRenderer()每次当你添加一行。创建表后,必须调用此方法一次。

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

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

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

+0

我试过了。但是我仍然得到了最近加载的最新组合框的值。我新摇摆。我不喜欢所有的东西。 :-( – Nila 2012-08-07 04:10:09

+0

好的,再试一次,让我们在你的应用程序中指定一些点1.在comboInstrument中设置的项目对所有行设置相同2.在comboMethod中设置的项目是否仅依赖于选定的仪器值 – Nestor 2012-08-07 08:31:38

+0

是仪器和方法也是可编辑的,像新仪器或新方法一样也可以添加 – Nila 2012-08-07 10:50:17