Multithreading with swing - java

I have a question about the use of threads in a gui application. Say (as a simplistic example) i have a swing application with a series of images. I have two threads i want to run that fetch an image of a parent respectively. (So for a given number of students, get a mother image and a father image from each server endpoint). The returned image of the father and the mother is then appended on to the image on screen so i have a series of images with a mother, father, mother, father for multiple students.
How can i schedule this in a multithreaded environment? Each call to get a mother or father image has to be in parallel and not block the displaying of the images on screen. Does the image displayed on the screen refresh after each thread returns an image? How will this be structured?

Start with Concurrency in Swing.
The absolute simplest approach might be to use a SwingWorker that has a list of items it needs to look up and allow it to process the list.
The problem with this is it will only run each request one at the other, making it a little slower then other options. The benefit of this is that it provides easy functionality to re-sync with the Event Dispatching Thread so that you can notify the UI or make changes to it safely.
Another option might be to use Executors, in particular a Thread Pool implementation.
This allows you to submit a number of tasks that should be executed at some time in the future, but allows you to control the number of threads that the process can use at any one time.
The drawback is that you become responsible for syncing the changes back to the UI yourself when you want to update the UI, using SwingUtilities.invokeLater
Now. You "could" use both.
Basically you would need to setup some kind of "request" class that would allow you to pass the relevant information to, for example, the "mother" and "father" servers, the original image and possibly some kind of callback interface that would tell you when the final image had being rendered.
The requester would build some kind of Runnable or Callable which would wrap a SwingWorker.
When executed, this "request task" would start the SwingWorker, allowing it to fetch the images, merge them and publish the results, which would notify the callback interface. The "request task" would then simply wait until SwingWorker#get returns before exiting.
As an idea...

Related

Can I do Swing operations at shutdown time?

This relates to this Java question.
Here's my problem. I've written an app that allows people to do a lot of data entry, typing into a lot of separate fields. To confirm the change in each field they can often hit Return (for a single line field) or control-S (for multi-line fields where Return would be valid input), but that's cumbersome, so I also allowed fields to save their content when they lose focus. So users can type-tab-type and it all goes smoothly.
Except if they change a field and then click on the application window exit X in the corner. They expect that this counts as losing focus and will save that last change. But the lost focus event doesn't happen and the change is lost.
I could add a Done button, which would have the side effect of moving focus and saving the last field, and then exiting. But I shouldn't have to. There's a X in the corner and it should do the right thing.
My first thought was
frame.addWindowListener(new java.awt.event.WindowAdapter() {
#Override
public void windowClosing(.....
because I thought from there I could publish() something to my SwingWorker to tell it call loseFocus on everything. No such luck; publish() is protected.
Basically I need to do one last operation on my various widgets when X is clicked. How do I?
Edit: I should note that each editable widget (dropdown, JTextPane, etc) has been extended to hold the actual relevant data. All the data for that widget, e.g. whether the value the user typed is valid, what it was before he edited it, etc. is in those extended class instances. There's no other place values are held; this isn't model-view-controller.
The reason for this is that widgets can get changed either by user actions or network messages; a message can come in that throws out an existing widget entirely and replaces it with one with new content. In other words, doInBackground is in a permanent read-loop, reading network update messages and publish()ing those update requests to process(). User action happens as usual, between calls to process().
Bottom line,there's no global data structure to go to at exit time to get values. They're all in dozens to hundreds of data structures managed by the swing worker thread.The app itself, outside that swing worker thread, doesn't even know what sort of values and widgets exist - all widgets are created, placed and destroyed by network messages from the server. The rest of the app (what little there is) couldn't safely get to the data if it wanted to, unless I implemented a whole lot of shared data and locking.
It all works flawlessly, and I'd rather not redesign it all for this one tiny shutdown case. It just never occurred to me that I couldn't publish an extra "shut down" message into the work queue for process() from outside that thread. (I mean thread safe queues are trivial to implement; why didn't they?)
If the answer is "you can't talk to swing at shut down", I'll live with it. I do have a potentially evil workaround - I could have x do nothing but send a message to the server, which could write back a "you should shut down message" which could do the rest. But that seems ungainly.
The short answer is, there isn't a good solution. I tried installing a shutdown hook and publishing a message to the swing thread to tell it to finish up, and then gave the shutdown thread a 500ms sleep to give process() time to happen. process() wasn't called. publish() alone apparently isn't enough, once shutdown starts.
Bottom line, don't put data you need to get at in swing threads. Global data and synchronized functions is the only way to go.

Threads in jMonkey and Nifty?

I have recently learnt that jMonkey operates on only a single thread which is its openGL render thread. However I'm not able to understand it completely. I can understand that it executes all update and initialize() calls on a single update loop but input should be independent of this update loop, otherwise it will become a polling mechanism.
What exactly happens when the jMonkey application starts. Three tasks that it needs to do is run a update loop, run initialize methods of app states once, do rendering and constantly cater to events? How does it manage all of this via a single thread?
What happens when I add a new app state in the initialize method of another app state?
In input handling input manager notifies the various listeners about events. How are nifty callback events say onClick() are handled on the same render loop?
Lastly in which order this listen- update-render loop runs and where we can find code related to it?
jME uses an approach that's very common in a lot of game engines (and also used in some other user interface libraries such as Swing).
Everything that the game engine does is done in one thread. This can be called the LWJGL thread but as jME can work with alternatives to LWJGL it's more generic to call it the Render Thread or just the jME Thread.
Everything is indeed done on the Render thread, and it does indeed use a polling mechanism. For example if you are holding down the "left" key then each frame the relevant control or app state will be called on the render thread and will move you left by an amount modified by tpf. Tpf is time-per-frame and is very important for keeping smooth movement and letting game systems run at the same speed independently of frame rate.
The only thing within jME3 that commonly uses a separate thread is the Physics Engine. That has a thread that it uses for doing the physics updates and then changes are pushed through to the Render thread using appropriate mechanisms. The system handles this for you though so it is not something you need to worry about.
The thread runs around a game loop. Each time around the loop it checks for things it needs to do (like enqueued tasks, initialize app states, render, etc. It calls update in each active Controller and control, etc). Once it has finished updating everything it then goes on to perform the render. All of this happens every single frame, but computers are so fast that it can still handle all of that and render the game at good frame rates.
That's an implementation detail that you shouldn't need to worry about except to know that it will definitely work. The adding actually gets queued up and handled in the next frame I think.
Everything is handled from the same loop. jME calls through to Nifty to allow Nifty to do its processing. As part of that processing Nifty detects the events and fires off the callback. This means that the callbacks are already coming in on the render thread so you can safely modify the scene graph. jME uses some specially written collections such as SafeArrayList to allow you to modify the scene graph at the same time as iterating over it.
Update, Render, Update, Render, etc. Events firing generally happens as part of the update process when an update is detected. To find the code start by looking in the Application class, you should be able to find the main game loop in there by tracing through from the start() call.
The jME3 Threading Tutorial covers a fair amount of this:
http://hub.jmonkeyengine.org/wiki/doku.php/jme3:advanced:multithreading

Should my custom events fire on GUI EDT or a "home-grown" EDT

I'm working on a project that does some intense math calculations (arrays of matrices, vectors, etc.), so naturally I'm splitting the work into jobs, and submitting them to a CompletionService to perform the work in parallel.
Each of the job objects can fire events to notify applications when the job starts, ends, progresses, and/or fails.
Currently, each of the jobs receive a handle to the entire list of event listeners, and simply iterate through, passing an event object to each one (in the same thread). This doesn't sit well with me, so I'd like to get other peoples' experience with doing this sort of thing with custom events/listeners.
Should I send my events to the GUI thread? Some of the listeners may or may not be GUI-related, and I'd like to not force users of my code to have to manually send their events onto the GUI thread, something like the following:
public class MyFooEventListener implements FooEventListener {
public void notifyJobStarted(FooEvent evt) {
// I want to avoid having users of my library write the following, right?
SwingUtilities.invokeLater(new Runnable(){
// update GUI here.
});
}
}
I wouldn't mind writing my own EventQueue, as this is for a research project in school, and I suppose it would be a good exercise in concurrency. Just trying to figure out what the "proper" way of implementing an event-driven system is, how to properly fire events, etc. Links to articles/tutorials and howtos are also greatly appreciated.
Thanks!
EDIT:
My event model has multiple event types, such as JobStartedEvent, JobEndedEvent, JobProgressEvent, etc. Is this a bad approach? Should I have a single event type, and if so, how do I pass information to the listeners that is not common to all events? Example: I want to pass a double in the range [0-1] for the progress event, but that is not applicable for an event like JobFailureEvent. What's the best approach to handling this?
I could put the extra information in the "source" object itself, but my source objects are the Job objects themselves, and it doesn't sit well with me to "leak" references to the job object, especially while it is running:
FooJob jobObject = (FooJob)event.getSource();
int progressPercent = jobObject.getCurrentProgress() * 100;
progressLabel.setText(progressPercent + "%");
No. Emit your events on whatever thread needs to raise them and leave it up to the users of your subsystem to decide how they wish to handle them. If they wish to message the results to a GUI, fine, if not, they can do whatever they want, eg. queue them to another thread. Just document 'Events are raised on an internal thread and event handlers must not block'.
Anything else puts constraints on users that they may well not want, as you say.
there are many ways to distribute events, each with their own pros and cons. if the consumer is not necessarily the GUI, then you definitely should not tie yourself to the awt EDT. unless you know for sure how the event consumers are going to work i would start simple and go from there. simple being: synchronously notify each consumer. if that ends up delaying the main task, then you should think about asynchronous notification. if the consumer is ultimately the GUI, then the consumer's notification method should be responsible for calling SwingUtilities.invokeLater.
Only threads that directly impact the GUI should be on the EDT. If you have other threads you need synchronized, just use the synchronized keyword (either on the method or on an object)
Spring has event handling and you can define custom events http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/beans.html#context-functionality-events.

Implementing java FixedTreadPool status listener

It's about an application which is supposed to process (VAD, Loudness, Clipping) a lot of soundfiles (e.g. 100k). At this time, I create as many worker threads (callables) as I can put into memory, and then run all with a threadPool.invokeAll(), write results to file system, unload processed files and continue at step 1. Due to the fact it's an app with a GUI, i don't want to user to feel like the app "is not responding" while processing all soundfiles. (which it does at this time cause invokeAll is blocking). I'm not sure what is a "good" way to fix this. It shall not be possible for the user to do other things while processing, but I'd like to show a progress bar like "10 of 100000 soundfiles are done". So how do I get there? Do I have to create a "watcher thread", so that every worker hold a callback on it? I'm quite new to multi threading, and don't get the idea of such a mechanism.
If you need to know: I'm using SWT/JFace.
You could use an ExecutorCompletionService for this purpose; if you submit each of the Callable tasks in a loop, you can then call the take method of the completion service - receiving tasks one at a time as they finish. Every time you take a task, you can update your GUI.
As another option, you could implement your own ExecutorService that is also an Observable, allowing the publication of updates to subscribing Observers whenever a task is completed.
You should have a look at SwingWorker. It's a good class for doing lengthy operations whilst reporting back progress to the gui and maintaining a responsive gui.
Using a Swing Worker Thread provides some good information.

Swing "blocking", I think I need to thread, but not sure how much

I have a little java app to effectively "tail" an arbitrary collection of files defined in an ini file. My "LogReader" class extends JFrame, and does the heavy lifting; reading the collection of file paths into a vector, and then iterating over the vector, reading each file and adding the last X lines of each to a text areas on the tabs of a JTabbedPane. The process of building the vector and iterating over the files is kicked off by clicking a JButton, via an ActionListener.
The reading of the files worked fine (and still does), but the process of reading 20-some files, some growing as large as 30MB, takes some time. To help pass that time, I decided to add a progress screen, which says "Now reading file #3 of 26: c:\logs\superduper1.log", and so on. So I created another class, "SplashScreen", also extending JFrame, and added a JLabel that would indicate the progress. The SplashScreen class has an update() method, which just does a setText() on the JLabel.
The ActionListener on the JButton calls RefreshLogs(), which looks something like:
vctFileStrings.clear();
tpMain.removeAll();
frmSplash.update("Loading Configuration"); //Update the label on the Splash Screen instance
BuildVectorOfLogs(strConfFile); //Read the collection of files into the vector
frmSplash.update("Reading Logs");
ReadLogs(); //read the files, updating the Splash Screen as we go
and then ReadLogs() iterates over the vector, reading the files and building the TabbedPane.
What I noticed, though, is that when RefreshLogs() is called from within the ActionListener, the Splash Screen doesn't update. However, if I add RefreshLogs() to the constructor of the first frame, the splash screen works as expected (updates progress on each file). After some experimenting and reading, I think that I need to create a worker thread that reads the files, while updating the splash screen in the event-dispatch queue.
My questions are:
- Is my thought correct? Is there some simple alternative to implementing threading that would allow me to update the splash screen from the method called by the ActionListener?
- If this would be best accomplished using threading, what scope of the activity would I need to thread? Would I need to put all of the file I/O activities into their own thread? Should I put the GUI activities (label updates) in their own thread, so they occur separately from the JButton click event?
I would say: yes, your thoughts on offloading the reading of large files to a separate thread are correct. You should never perform long tasks on the Event Dispatch Thread, since while that thread is busy, the GUI will be unresponsive, and you application will feel slow.
This sounds like good case for SwingWorker. This class allows you to perform slow requests (such as disk or network access) on a separate thread, with progress updates being fed back to the GUI with the EDT. SwingWorker looks after all complexities of switching between threads. All you have to do is implement your business logic in the appropriate places.
Sun has a tutorial on SwingWorker.
Yes, you should put your time intense reading into a separate thread. Now you do everything in the event-dispatching thread (EDT), which would update your GUI but is busy reading your data.
You can use SwingWorker for this. Have a look at Using a Swing Worker Thread which looks like what you need.
One suggestion for you, to figure out how to do this, and in case you are using NetBeans or have access to NetBeans, is to look at the default Java Desktop Application template. It creates a pre-wired desktop app with progress bar built into a status bar, that will automatically get updated when any "Action" code gets executed. It leverages the Action API which is also pre-wired to run in a background thread.
By looking at that auto-generated code you'll be able to properly and easily implement it in your own.

Categories

Resources