java-SwingWorker使用一张地图更新多个组合,列表,表格
作者:互联网
在解决了previous个问题之后,我可以使用一个HashMap使用SwingWorker填充多个组合框.现在,我想使用一张地图(如果可能)填充/更新gui应用程序不同面板中包含的多个组合框AND列表AND表.在javadocs中,我看到DefaultListModel和DefaultComboBoxModel都扩展了AbstractListModel,所以我将Map从
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不同,因此我找不到方法.
我希望我很清楚,任何帮助将不胜感激.
解决方法:
>毫无疑问,您的数据源具有与Java不同的类型系统.将这些类型与Java类型进行匹配的代码不会太漂亮,但是至少您已经将其封装了.枚举可能会有所帮助.
>是的,您可以通过委托给默认实现来扩展AbstractTableModel并实现其他接口.轮廓为here.您必须确定这样的瓶颈在您的应用程序中是否有意义.
public class SharedModel extends AbstractTableModel
implements ComboBoxModel, ListModel
附录:替代方法是编写三个模型(MyTableModel,MyListModel,MyComboBoxModel),每个模型都引用一个公共数据模型.
Do you mean a common interface that is implemented by three models?
是的,由类(例如ApplicationDataModel)实现的接口将数据库读取为内部格式.然后,客户端模型可以向ApplicationDataModel索要每个数据,以实现各自的接口协定.
标签:swingworker,hashmap,swing,java 来源: https://codeday.me/bug/20191031/1979354.html