0

I have a problem with my MVC application that displays data in a JTable. Everything worked fine, but I decided to add a SwingWorker to retrieve data from the database.

My controller calls the model with data from the database. It looks like this.

Model.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());
    }

}

I add SwingWorker to getCategory class

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 just retrieves the data from the model:

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

The problem comes when you call SwingWorker in class Model.java

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
}

Error:-

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

I know SwingWorker returns nothing, because there is an error. I should write the code in the method done(), but I have no idea how to solve it.

2 Answers 2

2

execute does not have a return value so it can't be used in the way you are trying to use it. The idea of SwingWorker is that the task should be executed asynchronously so you need to rework your design.

The SwingWorker bears a result (the List<Category>) and you either need to:

  • put the result somewhere from inside the SwingWorker (such as with the publish mechanism)
  • or call get from the outside to wait for the task to finish and return.

Here is the tutorial for review: http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html

Quick example:

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();
}

If you want to populate the entire table at once then you can also publish a List after the loop instead of one Category at a time. process would receive a List<List<Category>> with a singular element.

Sign up to request clarification or add additional context in comments.

5 Comments

Ok. Thanks it works but in View people = model.getPeople(); is null.
What can I access to private List<Category> list; from View?
You don't access the private List in the SwingWorker, you pass a List in to modify, then access it from Model#getPeople. Or at least that's how it would be done in my example. If getPeople returns null then your code is different from what you've shown in your question. return new ArrayList<Category>(people); will never return null.
Ok. When I call function getPeople() - Model.java I does not get any data. Calling the function in view model.getPeople()
Okay, it could be a problem with the Category class or possibly the database. It's difficult for me to guess at from afar. If it worked before, compare the code side by side so that you can see what's different.
0

Sorry my mistake. From the view gets to model.getPeople (), but nothing is returned. I did a test:

But nothing is returned

 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();
}
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.