2011-08-15 112 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