【问题标题】:Java SwingWorker load data from database to ListJava SwingWorker 将数据从数据库加载到 List
【发布时间】:2014-08-17 15:58:46
【问题描述】:

我的 MVC 应用程序在 JTable 中显示数据时遇到问题。一切正常,但我决定添加一个 SwingWorker 来从数据库中检索数据。

我的控制器使用数据库中的数据调用模型。它看起来像这样。

模型.java

    public class Model {

    private List<Category> people = new Vector<Category>();

    public List<Category> getPeople() {
        return new ArrayList<Category>(people);
    }

    public void load() throws Exception {
        people.clear();
        DAOFactory factory = DAOFactory.getFactory(DAOFactory.MYSQL);
        CategoryDAO personDAO = factory.getCategoryDAO();
        people.addAll(personDAO.getCategory());
    }

}

我将 SwingWorker 添加到 getCategory 类

MySQLCategodyDAO.java

public class MySQLCategoryDAO extends SwingWorker<Void, Vector<Object>> implements CategoryDAO{

    private Job job;
    private List<Category> cat;

    public MySQLCategoryDAO(Job job){
        this.job = job;
    }

    @Override
    protected Void doInBackground() throws Exception {
        // TODO Auto-generated method stub

        if(job == Job.SELECT){
            getCategory();
            System.out.println("Table selected");
        }       
        return null;
    }   
    @Override()
    public void done(){


    }

    public List<Category> getCategory() throws SQLException
    {
        cat = new ArrayList<Category>();
        Connection conn = Database.getInstance().getConnection();

        System.out.println(conn);

        String sql = "select id, name from kategorie";
        Statement selectStatement =  conn.createStatement();

        ResultSet results = selectStatement.executeQuery(sql);

        while(results.next())
        {
            int id = results.getInt("id");
            String name = results.getString("name");

            Category category = new Category(id, name);
            cat.add(category);
        }

        results.close();
        selectStatement.close();

        return cat;

    }
}

View 只是从模型中检索数据:

        people = model.getPeople();
        for (Category person : people) {
            tablemodel
                    .addRow(new Object[] { person.getId(), person.getName() });
        }

当你在类 Model.java 中调用 SwingWorker 时,问题就来了

public void load() throws Exception {
    people.clear();
    DAOFactory factory = DAOFactory.getFactory(DAOFactory.MYSQL);
    CategoryDAO personDAO = factory.getCategoryDAO();
    people.addAll(new MySQLCategoryDAO(Job.SELECT).execute());  - ERROR
}

错误:-

The method addAll(Collection<? extends Category>) in the type List<Category> is not applicable for the 
     arguments (void)

我知道 SwingWorker 没有返回任何内容,因为存在错误。我应该在方法done()中编写代码,但我不知道如何解决它。

【问题讨论】:

    标签: java swing


    【解决方案1】:

    execute 没有返回值,因此不能以您尝试使用它的方式使用。 SwingWorker 的想法是任务应该异步执行,因此您需要重新设计。

    SwingWorker 产生结果(List&lt;Category&gt;),您需要:

    • 将结果放在 SwingWorker 内部的某个位置(例如使用发布机制)
    • 或从外部调用get等待任务完成并返回。

    这里是复习教程:http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html

    快速示例:

    class MySQLCategoryDAO extends SwingWorker<Void, Category> {
    
        // ...
    
        private List<Category> list; // do not modify inside doInBackground
    
        MySQLCategoryDAO(Job job, List<Category> list) {
            this.list = list;
    
            // ...
        }
    
        @Override
        protected Void doInBackground() {
    
            // ...
    
            while(results.next()) {
                int id = results.getInt("id");
                String name = results.getString("name");
    
                publish(new Category(id, name)); // publish results to the EDT
            }
    
            // ...
    
            return null;
        }
    
        @Override
        protected void process(List<Category> chunks) {
            list.addAll(chunks); // add results to the list on the EDT
    
            // add to the JTable (?)
        }
    }
    
    public void load() throws Exception {
        people.clear();
        DAOFactory factory = DAOFactory.getFactory(DAOFactory.MYSQL);
        CategoryDAO personDAO = factory.getCategoryDAO();
    
        // just execute
        new MySQLCategoryDAO(Job.SELECT, people).execute();
    }
    

    如果您想一次填充整个表格,那么您还可以在循环之后发布一个列表,而不是一次发布一个类别。 process 将收到带有单数元素的 List&lt;List&lt;Category&gt;&gt;

    【讨论】:

    • 好的。谢谢它有效,但在视图中people = model.getPeople(); 为空。
    • 我可以从 View 访问什么private List&lt;Category&gt; list;
    • 你在 SwingWorker 中不访问私有 List,你传入一个 List 进行修改,然后从Model#getPeople 访问。或者至少在我的示例中就是这样。如果 getPeople 返回 null 那么您的代码与您在问题中显示的不同。 return new ArrayList&lt;Category&gt;(people); 永远不会返回 null。
    • 好的。当我调用函数 getPeople() - Model.java 时,我没有得到任何数据。调用视图中的函数model.getPeople()
    • 好的,可能是 Category 类或数据库的问题。我很难从远处猜测。如果它以前有效,请并排比较代码,以便您了解有什么不同。
    【解决方案2】:

    对不起,我的错误。 从视图获取到 model.getPeople(),但没有返回任何内容。我做了一个测试:

    但是什么都没有返回

     public class Model {
    
            private List<Category> people = new Vector<Category>();
    
            public List<Category> getPeople() {
    
                for (Category person : people) {
                    System.out.println(person.getName()); //no data
                }
                return new ArrayList<Category>(people);
            }
        public void load() throws Exception {
        people.clear();
        DAOFactory factory = DAOFactory.getFactory(DAOFactory.MYSQL);
    
        new MySQLCategoryDAO(Job.SELECT,people).execute();
    }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-06-07
      • 2011-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-30
      • 2014-01-07
      相关资源
      最近更新 更多