2012-08-03 100 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