This week's book giveaway is in the OCAJP 8 forum. We're giving away four copies of OCA Java SE 8 Programmer I Study Guide and have Edward Finegan & Robert Liguori on-line! See this thread for details.
Hello, My application requires some file processing. As soon as the user selects a file from a file chooser, some I/O processing takes place on the file in a separated class to get it ready to be presented on the gui. I defined an openFile() method that the mouseListener on the button calls...
The problem is while the file is being processed a section, that is the same size as the filechooser, is cut from my gui. I have a colored panel and when this happens the panel section turns gray making it appear that a piece of the panel has been cut out. From what I have read, this is a producer/consumer scenario. The openFile method is producing a file that the processor method needs to consume. I have read about the SwingWorker class and that this would be a good solution. How can I implement this so the processor waits for the file to be produced before it starts to process the file, within the same method? Should the openFile and processFile be 2 different methods? Is this even related to the gui flickering issue? Thank you. [ February 18, 2004: Message edited by: Chris Ramsey ]
I presume that your method openFile() method is being called from the event dispatching thread, ie. from some button handler code. All events are handled by the event dispatching thread, including instructions to repaint the form. What has essentially happened is that by opening a large file for processing you have hijacked that thread. Repaints which would have been queued to redraw that missing part of the form once it closed are not being actions because your processFile(...) method is being run in the event thread. What you are descriving is not really a producer/consumer scenario. When performing costly long operations it is nearly always a good idea to spawn a worker thread, do the work in that thread and then use a mechanism to invoke across threads to cause the GUI to be updated. SwingWorkerThread, which is not part of the standard SwingAPI is a nice little class that can help you out in such cases. You can find out all about it at this page which details how to use the SwingWorkerThread or here from the Swing Tutorial. Essentially it is a subclass of java.lang.Thread that allows you to detail your long running operation in a method called construct(), which will be run in its own thread, and then, when the thread runs to completion code that is provided in the method finished() is run from the event dispatching thread (using a call such as SwingUtilities.invokeLater(...)). Code which updates GUI state should always be called from the event dispatching thread, this is a central tennant of Swing (and most other UI toolkits) and using the SwingWorkerThread makes this simple for you.
Joined: Sep 15, 2003
Thank you Jason for responding. You clarified a lot of things for me. Since the post I have tried to changed some things along the lines of your suggestion. Since this is the bulk of the processsing I will need to do I want to make sure this procedure is as efficient as possible. Currently this is the way I am doing the processing in the Process class. I know I should not be creating a new Thread everytime this method is run, but not quite sure how to do this without creating one.
This is the flow in the UI class. This seems to work a little better, but with large files the gui repaint still seems to get blocked. I thought with this approach the processor.mapFile(file) would not be called until after the file was selected and the gui is updated.
I call the method in the listener like this...
I tried putting the opening of the file in the construct() method of a SwingWorker class and then calling the processor.loadFile() in the finished() method, but I got the same results. Is this a good approach or am I still way off? Thanks for your time. [ February 23, 2004: Message edited by: Chris Ramsey ] [ February 23, 2004: Message edited by: Chris Ramsey ]