• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

JButtons should start Threads whit synchronized handling of a JTable model

 
Ranch Hand
Posts: 40
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I have a simple Swing Gui with 1 JTable, a Searchbutton and a Deletebutton. So I can search content in a MySql DB, show the result in a JTable, mark some rows, and delete the marked rows. So far so good. Now I want that each Klick should start a Thread. Here are the relevant source code snippets:





If I click fast on the button, I get:
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 9 >= 0

What is wrong, and how can I do it right?
 
Bartender
Posts: 4179
22
IntelliJ IDE Python Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The TableModel is not Thread Safe, so you have to be careful with using it in multiple threads. So there are a few things to consider:
1) Preventing multiple threads from modifying the TableModel at one time.
-- The simple solution to this is to disable any of the user interface when the first request is made. For example, the first thing that happens in the actionPerformed method is to disable the button which caused the action. This prevents the user from pressing the button again. Of course at the end of the process you will have to re-enable the button. You should also disable all other buttons which modify the TableModel.

2) Preventing incomplete reads during updates.
-- Since the TableModel is not Thread Safe, your GUI could try to read the model for display purposes while rows are getting written to it. This could lead to displaying garbage data. I would suggest you use a SwingWorker to fix this. You need to push all the calls which update the TableModel into the EventDispatchThread, while keeping all the long DB work outside of it. With SwingWorker, you would put the DB Processing in the doInBackround(). You would put the model update (model.addRow(...)) into the process() method. In the doInBackground() method, when you want to update the GUI with a new row, you call publish() with the data to put into the new row. Finally, in the done() method is where you would do all the GUI clean up (like re-enabling the buttons).
 
Matt Kurz
Ranch Hand
Posts: 40
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Steve Luke wrote:The TableModel is not Thread Safe, so you have to be careful with using it in multiple threads. So there are a few things to consider:
1) Preventing multiple threads from modifying the TableModel at one time.
-- The simple solution to this is to disable any of the user interface when the first request is made. For example, the first thing that happens in the actionPerformed method is to disable the button which caused the action. This prevents the user from pressing the button again. Of course at the end of the process you will have to re-enable the button. You should also disable all other buttons which modify the TableModel.


If I do not work with threads, everything freezes, until the clicked button has finished it's work. So why should I disable all other buttons?


2) Preventing incomplete reads during updates.
-- Since the TableModel is not Thread Safe, your GUI could try to read the model for display purposes while rows are getting written to it. This could lead to displaying garbage data. I would suggest you use a SwingWorker to fix this. You need to push all the calls which update the TableModel into the EventDispatchThread, while keeping all the long DB work outside of it. With SwingWorker, you would put the DB Processing in the doInBackround(). You would put the model update (model.addRow(...)) into the process() method. In the doInBackground() method, when you want to update the GUI with a new row, you call publish() with the data to put into the new row. Finally, in the done() method is where you would do all the GUI clean up (like re-enabling the buttons).


Hmm. Sounds much more difficult than expected. I will read about these stuff. Hope to find good examples. Nevertheless: There is no easy way, like a flag for the first thread, that not other thread should be started, until the first thread sets the flag back?
 
Steve Luke
Bartender
Posts: 4179
22
IntelliJ IDE Python Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Matt Kurz wrote:
If I do not work with threads, everything freezes, until the clicked button has finished it's work. So why should I disable all other buttons?



If you don't use threads buoy don't have to worry about two threads modifying the model at once. If you do use threads you have to prevent that from happening. The best way is to disable the buttons because it both makes it safe and notifies the user. You don't have to disable all buttons, just those that modify the table.


Hmm. Sounds much more difficult than expected. I will read about these stuff. Hope to find good examples. Nevertheless: There is no easy way, like a flag for the first thread, that not other thread should be started, until the first thread sets the flag back?



You should read more on it. You could set a simple flag but there are issues about it's visibility, and it won't prevent problems associated with trying to display which may be partially formed as the table gets built. You will end up with glitchy displays.
 
Ranch Hand
Posts: 300
Eclipse IDE Firefox Browser Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

if you want to use a variable or flag to see if some other thread already working , you need to make it volatile so that no thread caches its value and always gets value from main memory.
 
reply
    Bookmark Topic Watch Topic
  • New Topic