2

I have GUI application with JDBC. One thread is for swing gui.

public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable() {

            public void run()
            {
                try {
                    runApp();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        });
    }

After starting the program displays my data from the database in a JTable.

public List<Category> getCategory() throws SQLException
    {
        List<Category> 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;

    }

I wonder how can I add a new thread so that all database operations run in a separate thread, not this thread swing.

lukassz
  • 127
  • 1
  • 2
  • 12
  • 2
    Yupp, have a look at [SwingWorker](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html). I might find an example too for your usecase. Though I need some itme for that :-) – nIcE cOw Aug 16 '14 at 10:15
  • Here is the [link](https://www.dropbox.com/s/r9cct4kxns0rr6i/database.zip), though I am using `Derby` as the database, which comes by default with Java Installation. I hope you know how to run this, else do let me know. You simply have to run it like: `java -classpath .;%JAVA_HOME%\db\lib\derby.jar example.JARCreationExample.java`. I hope you have set the `JAVA_HOME` variable too on your system :-) – nIcE cOw Aug 16 '14 at 10:25
  • 2
    [This tutorial](http://albertattard.blogspot.com/2008/09/practical-example-of-swing-worker.html) is good. – Volodymyr Levytskyi Aug 16 '14 at 10:52
  • Ok. I have application MVC, I call select table method in controller. When I start thread in controller or in model? – lukassz Aug 16 '14 at 11:16
  • 1
    @lukassz: I have updated the code in the [previous link](https://www.dropbox.com/s/bh1vw2vq2quyq3s), to actually adhere to Swing's single thread rule. Do check it out again, this time it will work without any errors of any sort, just run the `JAR` file./database.rar – nIcE cOw Aug 16 '14 at 12:25
  • When I click on link I see 404 error from Dropbox. – lukassz Aug 16 '14 at 12:33
  • @lukassz: Sorry my bad, here is that link for [database.rar](https://www.dropbox.com/s/bh1vw2vq2quyq3s/database.rar) – nIcE cOw Aug 16 '14 at 12:46
  • Ok. Thanks, I implement your solution to my code, but I'm doing something wrong. I added a SwingWorker to the class that selects data from the database (returns a list) ` people.addAll(personDAO.getCategory());` after add swingworker `people.addAll(new MySQLCategoryDAO(Job.SELECT).execute());` , then the list of charges, but I can not add the object. This is my project:https://www.dropbox.com/s/d9gpuoi2zqqtqrd/project.rar Model.java and MySQLCategoryDAO.java – lukassz Aug 16 '14 at 13:25
  • @lukassz we can have another question for that :) – joey rohan Aug 16 '14 at 13:27
  • 1
    @lukassz: Seems like I am not been able to understand you, on this one. But I did had a looked at the code, but I couldn't find, where exactly you added that to the table. You simply just called `getCategory()` inside `MySQLCategoryDAO` class, though you never did added anything to the `JTable`. – nIcE cOw Aug 16 '14 at 17:22
  • Yes, besause adding data to `JTable` is in View.java. In Model.java, function load() `people.addAll(personDAO.getCategory());` this line add data to list - function from MySQLCategoryDAO.java. When I add SwingWorker I change this line to `people.addAll(new MySQLCategoryDAO(Job.SELECT).execute());` `Job.SELECT` execute `getCategory()` but it does not work. Eclipse error `The method addAll(Collection extends Category>) in the type List is not applicable for the arguments (void)` I wrote clearly? – lukassz Aug 17 '14 at 01:51
  • 1
    @lukassz: Seems like a bit confusing to me, not been able to get a hold on the code. Just try to make a small thingy, which simply includes, what you wanted to achieve, do not incorporate that straight away in your project, just watch the flow. Simply lend the part of retreiving values from the database to the `Database` class instead of writing code everywhere. Never worked on `MySQL` before, so couldn't run it. A small example to understand the flow, will be highly appreciated. – nIcE cOw Aug 17 '14 at 04:41
  • I will try to mobile the base. `execute` returns nothing and I have to write properly method `done()`, unless the point. – lukassz Aug 17 '14 at 10:05
  • I say step by step. The `Controller` calls the model `model.load()`. The `load` creates a list and refers to a method that retrieves data from the database. `View` the data that gets collected `load` method. In the method that gets the database did swing worker. Calls swing Worker in AddAll in function `load` and gets an error because the same swing worker returns nothing and need to earn some extra method done, I do not know how to do it. My DATABASE https://www.dropbox.com/s/dmmtcfpcdsffer0/database.sql – lukassz Aug 17 '14 at 11:40
  • @lukassz: Instead of playing with references, why not create getter and setter methods, inside `Model`, that will help `Controller` to set the state, for the `Model`. If this was build using Derby I would have easily tested it, just finding it tough to make it work, and understand the flow. A simple small example, instead of the whole project, will be helpful, it seems. – nIcE cOw Aug 17 '14 at 12:06
  • Ideology is this: View.java calling Controller.java Controller calls the `getCategory`,which calls the` model.load () `. `model.load` (Model.java) retrieves data from the database and places them in the list of `private List people = new Vector (); `More specifically: `people.addAll(personDAO.getCategory ())` in view of downloading the data using the `people = model.getPeople () `and adds them in the loop for the `JTable`. In the file `MySQLCategoryDAO.java` did `SwingWorker`. I do not know how to put the data in the list (file `Model.java`) using `SwingWorker`. – lukassz Aug 17 '14 at 12:31
  • @nlcE cOw do you have any ideas? – lukassz Aug 17 '14 at 14:05
  • 1
    @lukassz: On my side it is working fine, I changed it to use, Derby, though I cann't say, if that is for sure, since, the language is not known to me, what is written on the `JButton`s. But `JTable` itself is showing the values, as seen on this [link](https://www.dropbox.com/s/gek2v8xg836mwc5/project.rar) – nIcE cOw Aug 17 '14 at 14:28
  • 1
    Yes, it works correctly because the commented out line should run SwingWorker `people.addAll (new MySQLCategoryDAO (Job.SELECT) .execute ());` Instead, it is the `people.addAll (personDAO.getCategory ());` and SwingWorker is not performed. The idea is to make the SwingWorker and add data to people.addAll – lukassz Aug 17 '14 at 14:40
  • When you turn on the program, SwingWorker is nowhere caused because the call was created confusion about któym I wrote, so commented out so you can see how it works. – lukassz Aug 17 '14 at 15:01
  • I post this problem in http://stackoverflow.com/questions/25350934/java-swingworker-load-data-from-database-to-list – lukassz Aug 17 '14 at 16:20
  • 1
    @lukassz: Seems like I found the answer. Though it is hard to understand as to why `MySQLCategoryDAO` is a part of `Model` and not `Controller`. Since it is a link between the `View` and the `Model`. I made three changes, __Firstly: inside `addCategory()` of `Conttroller`, I commented `view.loadData()`__, __Secondly: do watch the `load()` method of `Model`__ and __lastly `done()` and `doInBackground()` methods of `MySQLCategoryDAO`__ . Though still I could have explained a bit better in a smaller example.[Link](https://www.dropbox.com/s/gek2v8xg836mwc5/project.rar) – nIcE cOw Aug 18 '14 at 10:14
  • Thank you very much. You are great. It works beautifully. According to you MySQLCategoryDAO should be part of the controller so? I have another question. Is the work SwingWorker can be displayed in a JTable "load data"? – lukassz Aug 18 '14 at 10:36
  • However, there is a problem. Data from database are loaded twice. – lukassz Aug 18 '14 at 15:40
  • Ok. I had comment out `this.people.addAll(getPeople());` in Model.java – lukassz Aug 18 '14 at 15:46
  • 1
    @lukassz: I thought, I uploaded this file with this line commented, but seems like it's not :-) Glad you got it sorted by yourself :-) Moreover, since you never use to add __@__ and __nIcEcOw__ without spaces, that is why no message ever reached me. By chance, I visited this page thrice, and saw you were saying somethingy :-) – nIcE cOw Aug 18 '14 at 18:46
  • @nlcEcOw: Back to my earlier question. I wonder how to add a progress dialog for the duration of loading data into the JTable. Progress bar. I should implement in the `done()` method? – lukassz Aug 20 '14 at 11:36
  • 1
    @lukassz: Sorry for the late reply, seems like I missed this message somehow. My bad, it is surely my mistake this time. Though please have a look at [How to use Progress Bar](http://docs.oracle.com/javase/tutorial/uiswing/components/progress.html), seems like they just got an example for your usecase. – nIcE cOw Aug 22 '14 at 16:00

1 Answers1

2

Have a look at ExecutorService class for example.

ExecutorService exec = Executors.newFixedThreadPool(2);
exec.execute(new Runnable() { 
// Run your database thread

});
exec.shutdown();
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
COLD ICE
  • 840
  • 1
  • 12
  • 31
  • Ok. What do you think about this solution http://stackoverflow.com/questions/3489543/how-to-call-a-method-with-a-separate-thread-in-java – lukassz Aug 16 '14 at 10:29
  • 1
    @lukassz: At the end of retrieving values, the `JTable` must be updated on the `Event Dispatcher Thread - EDT`. So if you go for `SwingWorker` that thingy is something that won't give headaches to you, since the methods `process()/done()` put everythingy on the `EDT` by default. – nIcE cOw Aug 16 '14 at 10:32
  • @lukassz it better plus take nIcE cOw notes – COLD ICE Aug 16 '14 at 10:38