代码之家  ›  专栏  ›  技术社区  ›  Rempelos

SwingWorker使用一个映射更新多个组合、列表和表

  •  3
  • Rempelos  · 技术社区  · 13 年前

    遵循 previous 问题已经解决,我可以用 SwingWorker 使用一个 HashMap 。现在,我想通过使用一个映射(如果可能的话)来填充/更新gui应用程序的不同面板中包含的多个组合框AND列表AND表。在javadocs中,我看到 DefaultListModel DefaultComboBoxModel 延伸 AbstractListModel ,所以我更改了地图

    Map<String, DefaultComboBoxModel>
    

    Map<String, AbstractListModel>
    

    然后将其传递给 摇摆工人 .下面的代码有效,它可以通过使用这一个映射来填充许多组合和列表。

    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:有没有办法 摇摆工人 通过使用一个地图来更新表格以及组合和列表?从那以后我就找不到路了 DefaultTableModel 延伸 AbstractTableModel 不同于 抽象列表模型 地图使用的。

    我希望我是清楚的,任何帮助都将不胜感激。

    1 回复  |  直到 8 年前
        1
  •  4
  •   Community Mohan Dere    8 年前
    1. 毫无疑问,您的数据源具有与Java不同的类型系统;将这些类型与Java类型相匹配的代码不会更漂亮,但至少您已经封装了它。一 enum 可能会有所帮助。

    2. 是的,你可以延长 AbstractTableModel 并且通过委托给默认实现来实现其他接口。有一个大纲 here 。您必须决定这样的瓶颈在您的应用程序中是否合理。

      public class SharedModel extends AbstractTableModel
          implements ComboBoxModel, ListModel
      

    附录:备选方案是编写三个模型( MyTableModel , MyListModel , MyComboBoxModel )每个引用一个公共数据模型。

    你指的是由三个模型实现的通用接口吗?

    是的,一个由类实现的接口,比如 ApplicationDataModel ,将数据库读取为内部格式。然后,客户模型可以询问 应用程序数据模型 每个数据都需要履行自己的接口合同。