2011-08-15 108 views
2

我似乎沒有把握事件等的概念。在閱讀了一段時間關於如何實現監聽器之後,我遇到了Java教程,我應該擴展AbstractListModel以獲取數據事件觸發。由於某種原因,它仍然無法正常工作。ComboBoxModel事件不起作用

有什麼我做錯了嗎?

預計在addListDataListener(ListDataListener l)上運行什麼樣的代碼?因爲我也不明白。

public class CarComboBox extends AbstractListModel<Object> implements ComboBoxModel<Object> { 

    private JdbcRowSet jdbc; 
    private int size = 0; 
    private String selection; 

    public CarComboBox() { 
     try { 
      jdbc = new Query().getCarInfo(); 

      jdbc.beforeFirst(); 
      while (jdbc.next()) { 
       size++; 
      } 
      jdbc.beforeFirst(); 
     } 
     catch (SQLException ex) { 
      System.err.println(ex.toString()); 
     } 
    } 

    @Override 
    public void setSelectedItem(Object anItem) { 
     selection = (String) anItem; 
    } 

    @Override 
    public Object getSelectedItem() { 
     return selection; 
    } 

    @Override 
    public void addListDataListener(ListDataListener l) { 
    } 

    @Override 
    public void removeListDataListener(ListDataListener l) { 
    } 

    @Override 
    public int getSize() { 
    return size; 
    } 

    @Override 
    public String getElementAt(int index) { 
     try { 
      jdbc.absolute(index + 1); 
      return jdbc.getString(2); 
     } 
     catch (SQLException ex) { 
      System.out.println(ex.toString()); 
     } 
     return null; 
    } 
} 

而且到監聽器添加到CarComboBox我做的:

CarComboBox ccb = new CarComboBox(); 
ccb.addListDataListener(new ListDataListener() 
+0

您應該添加另一個標記指定GUI你使用的是什麼。這看起來不像Swing。 – toto2

+2

實際上,它是Swing ... – aymeric

+0

Dam - 另一個空的addListDataListener - 在網上任何地方似乎都沒有帶有工作的addListDataListener的代碼示例。 – Martin

回答

6

我猜你正在使用官方tutorial

但是,您不應該觸摸ListModel和ComboBoxModel。這些是您可能不需要的更高級功能。 本教程中的4個示例不使用ListModel和ComboBoxModel。

如果使用標準的JComboBox(無ListModel或ComboBoxModel),會發生什麼情況是當有人做出選擇時,會觸發ActionEvent。這個事件是由Swing神奇地解僱的;你不必擔心它是如何產生的。然而什麼是你的責任是有一些(零,一個或多個)對象能接收並做一些事情的動作事件:

public class MyClass implements ActionListener { 
    JComboBox comboBox = ...; 

    ... 
     // You must register explicitly every ActionListener that you 
     // want to receive ActionEvent's from comboBox. 
     // Here we register this instance of MyClass. 
     comboBox.addActionListener(this); 
    ... 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     if (e.getSource() instanceof JComboBox) { 
     System.out.println("MyClass registered an ActionEvent from a JComboBox."); 
     System.out.println("Selected: " + 
       ((JComboBox) e.getSource()).getSelectedItem()); 
     } 
    } 
} 

請注意,如果你沒有任何其他的動作事件的不同擺動解僱因爲您知道您的ActionEvent始終來自JComboBox,因此您可以跳過if (e.getSource() instanceof JComboBox)的組件 。

在我的例子JComboBox可裏面MyClass的,但它並不一定是:

JComboBox comboBox = ...; 
MyClass myClass = ...; 
comboBox.addActionListener(myClass); 
... 
comboBox.addActionListener(someOtherActionListener); 
4

你並不需要重寫addListDataListener()removeListDataListener()方法。 AbstractListModel已經照顧了聽衆。這裏是AbstractListModel.addListDataListener()實現:

public void addListDataListener(ListDataListener l) { 
    listenerList.add(ListDataListener.class, l); 
} 

抽象類的想法是,他們大部分的工作適合你。通常你只需要實現抽象方法。

+0

謝謝。這就解釋了爲什麼在任何地方都找不到「addListDataListener」的例子。你實際上並不需要自己實現它。 – Martin

3

XXListener和XXModel是一個硬幣的兩面:前者是觀察員,後者是可觀測。當監聽器想要獲知有關更改的通知時,它將向模型註冊自己。這是模型來

  • 負責管理其聽衆(也就是通常由AbstractXXModel已經處理,因爲已經@userWhateverNumber解釋;)
  • 火的通知,如果appropirate:這是一個自定義模式,必須走部分過去,你的情況

@Override 
public void setSelectedItem(Object item) { 
    selection = item; 
    fireContentChanged(this, -1, -1); 
} 

可以說(有大約:-)你往往沒有個人喜好需要自定義模型實現,但也可以重新使用提供的DefaultXXModels。在你的背景和假設的結果集的內容是不可改變的,可能是一種選擇,以填補在施工時間數據的默認模型,如

DefaultComboBoxModel model = new DefaultComboBoxModel(); 
forEachRowInResultSet { 
    model.addElement(resultSet.getString(2)); 
} 

如果,另一方面,內容的變化,然後你的模型執行無效反正:模型必須通知其偵聽器,只要有什麼東西改變

Object one = model.getElementAt(index); 
Object other = model.getElementAt(index) 
if (!one.equals(other)) { 
    listener must have received a contentsChanged 
} 
+0

這個很清楚,很容易理解,謝謝你提供一些背景信息。現在把整個事情放在背景中比較容易。 – Patrick