2012-09-08 62 views
3

在解決了previous問題後,我可以使用一個填充多個組合框並使用SwingWorker。現在我想通過使用一個映射(如果可能)來填充/更新多個組合框和包含在gui應用程序的不同面板中的列表和表。 JavaDoc中,我看到這兩個DefaultListModelDefaultComboBoxModel延長AbstractListModel,所以我改變了地圖從SwingWorker通過使用一個映射更新多個組合,列表和表格

Map<String, DefaultComboBoxModel> 

Map<String, AbstractListModel> 

,然後傳遞給SwingWorker。下面的代碼工作,它可以通過使用這一個地圖來填充許多組合和列表。

SSCCE:

public class TestPanel extends JPanel { 

    private final Map<String, AbstractListModel> map = new HashMap<String, AbstractListModel>(); 

    private TestPanel() { 
     setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); 
     JComboBox combo1 = new JComboBox(); 
     JComboBox combo2 = new JComboBox(); 
     JList list1 = new JList(new DefaultListModel()); 
     JList list2 = new JList(new DefaultListModel()); 
     add(combo1); 
     add(combo2); 
     add(new JLabel("LIST 1:")); 
     add(list1); 
     add(new JLabel("LIST 2:")); 
     add(list2); 
     map.put("ComboBox1", (DefaultComboBoxModel)combo1.getModel()); 
     map.put("ComboBox2", (DefaultComboBoxModel)combo2.getModel()); 
     map.put("List1", (DefaultListModel)list1.getModel()); 
     map.put("List2", (DefaultListModel)list2.getModel()); 
     new MyWorker(map).run(); 
    } 

    public static void main(String[] args) { 
     javax.swing.SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       JFrame frame = new JFrame(); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setContentPane(new TestPanel()); 
       frame.setSize(200, 300); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    private class MyWorker extends SwingWorker<Void, Object[]> { 
     private final int COMBO_BOX_MODEL = 1; 
     private final int LIST_MODEL = 2; 
     private final Map<String, AbstractListModel> map; 

     public MyWorker(Map<String, AbstractListModel> map) { 
      this.map = map; 
     } 

     @Override 
     protected Void doInBackground() throws Exception { 
      // just a random way to fill the combos and the lists 
      for (int i = 0; i < 20; i++) { 
       Object[] cell = new Object[3]; 
       if (i>=0 && i<=4) { 
        cell[0] = "ComboBox1"; 
        cell[1] = COMBO_BOX_MODEL; 
       } else if (i>=5 && i<=9) { 
        cell[0] = "ComboBox2"; 
        cell[1] = COMBO_BOX_MODEL; 
       } else if (i>=10 && i<=14) { 
        cell[0] = "List1"; 
        cell[1] = LIST_MODEL; 
       } else if (i>=15 && i<=20) { 
        cell[0] = "List2"; 
        cell[1] = LIST_MODEL; 
       } 
       cell[2] = "value " + i; 
       publish(cell); 
      } 
      return null; 
     } 

     @Override 
     protected void process(List<Object[]> chunks) { 
      for (Object[] chunk : chunks) { 
       if (chunk[1] == Integer.valueOf(COMBO_BOX_MODEL)) { 
        DefaultComboBoxModel model = (DefaultComboBoxModel)map.get(chunk[0]); 
        model.addElement(chunk[2]); 
       } 
       else if (chunk[1] == Integer.valueOf(LIST_MODEL)) { 
        DefaultListModel model = (DefaultListModel)map.get(chunk[0]); 
        model.addElement(chunk[2]); 
       } 
      } 
     } 
    }; 

} 

問題1:雖然上面的代碼工作,我不喜歡它的外觀(尤其是檢查在process()方法)。有沒有更好的和/或更聰明的方式來做這件事?

問題2:有沒有辦法通過一個地圖,使SwingWorker更新也隨着連擊和名單表,?自從DefaultTableModel擴展AbstractTableModel以來,我找不到方法,它與地圖使用的AbstractListModel不同。

我希望我很清楚,任何幫助將不勝感激。

回答

4
  1. 您的數據源無疑具有與Java不同的類型系統;將這些類型與Java類型相匹配的代碼不會更漂亮,但至少你已經封裝了它。 enum可能會有所幫助。

  2. 是的,您可以擴展AbstractTableModel並通過委託給默認實現來實現其他接口。有一個輪廓here。您必須決定這樣的瓶頸在您的應用程序中是否有意義。

    public class SharedModel extends AbstractTableModel 
        implements ComboBoxModel, ListModel 
    

附錄:另一種方法是寫三種模式(MyTableModelMyListModelMyComboBoxModel),每個引用一個公共數據模型。

你的意思是一個通用接口是由三個模型實現的嗎?

是的,這是由類實現的接口,說ApplicationDataModel,讀取數據庫爲內部格式。然後,客戶模型可以要求ApplicationDataModel獲得每個需要履行其自身接口合同的數據。

+0

謝謝,這就是我想要的。由於SharedModel擴展了AbstractTableModel,因此無法將其轉換爲DefaultComboBoxModel或DefaultListModel。因此,必須將檢查移入SharedModel,我應該根據組件類型(組合或列表)添加兩個版本的方法(如addElement)。或者至少這是我的理解。我對麼?如果是的話,那麼你是對的瓶頸。SharedModel可能會變得複雜,試圖決定使用哪個版本。 – Rempelos

+0

我不知道我明白這一點。你的意思是製作一個由三種模型實現的通用界面嗎? – Rempelos

+0

明白了,這是更好的我認爲 – Rempelos

相關問題