4

我在控制器类中设置了组合框的模型

cboCategory.setModel(new ModernDefaultComboBoxModel(model.getProductCategories()));

productCategories是一个List。只是扩展的模型。StringModernDefaultComboBoxModelDefaultComboBoxModel

public class ModernDefaultComboBoxModel extends DefaultComboBoxModel{
    public ModernDefaultComboBoxModel(List<String> elements){
        super(elements.toArray());
    }
}

现在在我的模型中,productCategories从数据库中填充SwingWorker

SwingWorker<Void, String> worker = new SwingWorker<Void, String>() {
    @Override
    protected Void doInBackground() throws Exception {
        //query and resultset stuff
        while (rs.next()) {
            publish(rs.getString(1));
        }
        //cleanup stuff
    }
    @Override protected void process(List<String> chunks){
        List<String> oldCategories = new ArrayList<String>(productCategories);
        for(String cat : chunks){
            productCategories.add(cat);
        }
        fireModelPropertyChange(PRODUCT_CATEGORIES, oldCategories, productCategories);
    }
    @Override
    protected void done(){
        //some stuff
    }
};
worker.execute();

您会看到每一个publish,它都会向其侦听器触发一个属性更改事件(fireModelPropertyChange只是 的一个包装器firePropertyChange)。

现在在我的模型监听器中,

@Override
    public void propertyChange(PropertyChangeEvent evt) {
        String propName = evt.getPropertyName();

        //some branching for the other models

        else if(ProductModel.PRODUCT_CATEGORIES.equals(propName)){
            List<String> newVal = (List<String>)evt.getNewValue();

            //notify the model of the combobox that the data is changed, so refresh urself
        }

        //some stuff
    }

我陷入了ModelListener需要通知组合框模型中的数据已更改的视图中。我有同样的情况,JTableJTable我可以fireTableRowsInserted从它实现的模型中调用AbstractTableModel

实际上,在 中AbstractListModel有一种方法fireContentsChanged,但与 中不同JTable,此方法受到保护,因此我无法访问它。

我知道我可以创建一个实例,ModernDefaultComboBoxModel然后调用setModel组合框的方法来刷新组合框,但我只是想知道是否有一种像JTable

4

1 回答 1

2

JComboBoxListDataListener为了听它自己的实现ComboBoxModel。对您的任何更改都DefaultComboBoxModel应该调用 中的相关fireXxxx()方法AbstractListModel,并且JComboBox应该看到更改。只需更新组合的模型process()

附录:这是一个更新模型的最小示例。在 上设置断点model.addElement(),调试,单击Add,然后进入方法以查看对 的调用fireIntervalAdded(),随后会更新视图。

JFrame f = new JFrame("ComboWorkerTest");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLayout(new GridLayout(0, 1));
final JComboBox jcb = new JComboBox(new Integer[]{value});
f.add(new JButton(new AbstractAction("Add") {
    @Override
    public void actionPerformed(ActionEvent e) {
        DefaultComboBoxModel model = (DefaultComboBoxModel) jcb.getModel();
        model.addElement(++value);
    }
}));
f.add(jcb);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
于 2013-04-14T11:05:18.107 回答