I am trying to implement a GUI in java but I am beginner in swing. I want to make something clear. I read that in order to keep the GUI responsive I should use the SwingWorker class to do the task in a separate thread. Ok so far.
No I have a model with around 15 methods that are remote methods. Each method returns different object type as a result than the others.
In my view the user presses a button and the appropriate method in the model is called. Without using the swingworker the GUI froze. My question is, am I supposed to create 15 subclasses of Swingworker threads and create a NEW instance of each as needed according to user's actions? Is my understanding correct? Is there a standard way for this or what I say is a correct approach?
Thanks!
Have a look at this: Simple Background Tasks.
It seems you have two concerns. Firstly, regarding the amount of code required when using SwingWorker: you do need to create a subclass of SwingWorker for each action, but that doesn't mean they need to be top-level, named classes, or in their own files. They can be anonymous classes, as shown in the article, so that the code is within your GUI's event-handling code.
Secondly, regarding instantiation of SwingWorker objects: you can't reuse a SwingWorker, but since the jobs are being executed as a result of user activity (e.g. clicking a button), you shouldn't encounter any performance problems with instantiating new objects each time.
By all means, SwingWorkers get the job done. In my experience, I haven't liked using the SwingWorkers for just one little job. I prefer to spawn off a thread, and have that thread ask the EventDispatch thread to update the GUI. Only the EventDispatch thread should update the UI, though there are a few exceptions.
I would suggest reading about threads in threads in Swing.
Though threading can get heavy, and maybe this solution would not work for you in all cases, if a seperate thread needs to spark a change in GUI, use something like,
java.awt.EventQueue.invokeLater(new Runnable()
{
public void run()
{
// this codes runs on the event dispatch thread
// update the ui here.
}
});
Related
My background is mainly in JavaScript, where functions are first-class objects and I can pass them around easily as callbacks. That is very much the way of JavaScript.
Now I am attempting to build a simple Java app. The problem at hand is to (1) use Swing to let the user browse to a file to open, and then (2) do some stuff with it. Let's say I have a method like this
void doStuff(File file) {
//stuff
}
that needs to run on the file chosen by the user. In JavaScript, the doStuff function would simply be passed as a callback. How would one do this in Java?
I'm aware that it is possible to do callbacks in Java by, say, making a Callback interface with a void run() method. But is that idiomatic? How should this kind of thing be done? How would an experienced Java programmer choose to do it?
Also, when I use callbacks, it looks like nearly everything happens on the Event Dispatch Thread. I suppose I could, from the EDT, create a new third thread, but it seems like my doStuff function should be executing on the main thread. And I can't figure out any way to make that happen. Nor do I know if it's necessary or desirable to make it happen.
Put simply, "do stuff" will parse and import data from the file.
Since this involves file or resource input, then it should not be done on the EDT. The best solution IMO would be to
do the importing and parsing within the doInBackground() method of a SwingWorker
add a PropertyChangeListener to the SwingWorker
have this listener listen to the worker's state property, specifically for a new value of SwingWorker.StateValue.DONE
in this listener, you'll then be notified when the worker has completed its task. You'll want to be sure to call get() on the SwingWorker when its done, so you can get any end value that you want it to produce, and so you can capture and respond to any and all exceptions that might have occurred during its run.
For more on this, please check out the tutorial -- Lesson: Concurrency in Swing
Do you suggest using SwingWorker mainly so that this process doesn't take place on the EDT, thereby locking up the user interface?
Yes. Any thread would serve that purpose though, but the main advantage of using the SwingWorker is because while it will run the process in a background thread, it also has great mechanisms for providing end and interim results on the EDT, as well as built-in functionality to monitor progress.
I've recently started learning and exploring the basics of GUI programming in Java.
Having been programming for a while I have only done backend work or work and as a result the closest I've gotten to user interfaces is the command console (embarrassing I know).
I'm using Swing and as far as I can gather that means by extension I am also using AWT.
My question is based on this piece of code:
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new frame.setVisible(true);
}
} );
I have been researching this for a while as I wanted to fully understand this strange piece of code and have come across the term 'Event-Dispatching Thread' multiple times. Correct me if I'm wrong but as I understand it; it has to do with using multiple threads and how Java Swing interprets those threads. I gather as well that the above code is used to make sure all the threads are 'safe' before it creates the window, hence the invokeLater?
I have read that:
"You can only call methods that operate on the frame from the Event-Dispatching Thread"
and that only under certain circumstances can you call methods that operate on the frame from the main method.
Can somebody please clarify to me what exactly the Event-Dispatching Thread is?
How it relates to multiple threads of execution and how those threads are not safe to be called from the main method? Also why do we need this invokeLater?
Can we not just create the window as any other object?
I've hit a bit of a road block in my research as I'm not grasping these relations and ideas.
A side note is that I like to base my knowledge on in-depth understanding as I believe this leads to the best overall outcome and as a result the best programs. If I understand in-depth how something works then you can use the tips and tweaks effectively rather than just parroting them back in to code, so please don't be afraid to give me some extra in-depth explanations and broaden my knowledge.
Thank you.
The event dispatch thread is a special thread that is managed by AWT. Basically, it is a thread that runs in an infinite loop, processing events.
The java.awt.EventQueue.invokeLater and javax.swing.SwingUtilities.invokeLater methods are a way to provide code that will run on the event queue. Writing a UI framework that is safe in a multithreading environment is very difficult so the AWT authors decided that they would only allow operations on GUI objects to occur on a single special thread. All event handlers will execute on this thread and all code that modifies the GUI should also operate on this thread.
Now AWT does not usually check that you are not issuing GUI commands from another thread (The WPF framework for C# does do this), meaning it's possible to write a lot of code and be pretty much agnostic to this and not run into any problems. But this can lead to undefined behavior, so the best thing to do, is to always ensure that GUI code runs on the event dispatch thread. invokeLater provides a mechanism to do this.
A classic example is that you need to run a long running operation like downloading a file. So you launch a thread to perform this action then, when it is completed, you use invokeLater to update the UI. If you didn't use invokeLater and instead you just updated the UI directly, you might have a race condition and undefined behavior could occur.
Wikipedia has more information
Also, if you are curious why the AWT authors don't just make the toolkit multithreaded, here is a good article.
EventDispatchThread (EDT) is special thread reserved only for Swing GUI and *Swing's related events e.g. create/change/update Swing JComponents, more for asked questions here and here
all output to the GUI from BackGround Tasks, Runnable#Thread must be wrapped into invokeLater(), from synchronized Objects into invokeAndWait();
I'm student and I'm working on project with few of my friends. My task is to make something like class library. Classes in this library should provide API for my friend who must make GUI part of application. GUI could be made by any toolkit (Swing, JavaFX, SWT, AWT, all should work, in fact, it should work even if there is no GUI). I need to make class that waits for data to arrive from network. I don't know when data will arrive, and UI must be responsive during waiting, so I put that in different thread. Now problem is how to make GUI respond when data arrive. Well, I tought that this is asynchronous event and GUI should register event handlers, and I should call that methods when event happens. I proposed this solution:
interface DataArrivedListener{
void dataArrived(String data);
}
class Waiter{
private DataArrivedListener dal;
public void setDataArrivedListener(DataArrivedListener dal){
this.dal = dal;
}
void someMethodThatWaitsForData(){
// some code goes here
data = bufRdr.readLine();
//now goes important line:
dal.dataArrived(data);
// other code goes here
}
}
My question is:
Should I replace "important" line with something like this:
java.awt.EventQueue.invokeLater(new Runnable(){
#Override
public void run(){
dal.dataArrived(data);
}
});
Or something like:
javafx.Platform.runLater(new Runnable(){
#Override
public void run(){
dal.dataArrived(data);
}
});
Or maybe I should do something completely different?
Problem is that I'm not sure which of this will work for any type of UI. If it's GUI, dataArrived() could potentialy make changes to GUI and no matter what type of GUI it is, this changes should be drawn on screen properly. I also think that it is better if I do "invoke this code later" so that my someMethodThatWaitsForData() method could trigger event and continue on with it's on work.
I appreciate your help.
Here's an Event Listener article I wrote a while back. The article explains how you write your own event listeners.
You're correct in that you want to write your own event listeners if you want your library to work with any GUI.
I'm most familiar with Swing, so yes, you'll have GUI code that looks like this:
button.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent event){
dal.buttonPressed(data);
}
});
If you want it to be completely agnostic to what GUI is being used the only real solution is to let the receiver handle it in dataArrived. Since every toolkit has its own implementation all you can really do to make it work with any toolkit is to disregard it. Otherwise what you will actually end up with is a list of "supported toolkits" and a case for each one.
If you just want dataArrived to be executed away from someMethodThatWaitsForData then you could make your own dispatch thread or make a new thread each time.
If you want to be truly independent of any front-end system, I would recommend creating two threads. The first is your Waiter, which will just listen for events and put them into a Queue of some sort (see the "All Known Implementing Classes" section). The second will invoke the data listener or listeners whenever the queue is not empty.
The concept of invoking a Runnable in the background is kind of deprecated since the invention of the concurrent package. The main reason that this was done in earlier days, is that the GUI code needs to be executed in a different thread, to guarantee that it stays responsive, even if the main thread is busy doing some calculations, but actual multi-threading was still in its very early days. The resulting invokeLater concept works, but comes with a strong creation overhead. This is especially annoying if you frequently have to do minor things, but each time you need to create an entire new Runnable, just to get that event into the Swing thread.
A more modern approach should use a thread-safe list, like a LinkedBlockingQueue. In this case any thread can just throw the event into the queue, and other listener/GUI-Event-handlers can take them out asynchronously, without the need of synchronization or background Runnables.
Example:
You initialize a new Button that does some heavy calculation once it is pressed.
In the GUI thread the following method is called once the button is clicked:
void onClick() {
executor.submit(this.onClickAction);
}
Where executor is an ExecutorService and the onClickAction a Runnable. As the onClickAction is a Runnable that was submitted once during Button creation, no new memory is accessed here. Let's see what this Runnable actually does:
void run() {
final MyData data = doSomeHeavyCalculation();
dispatcher.dispatch(myListeners, data);
}
The dispatcher is internally using the LinkedBlockingQueue as mentioned above (the Executor uses one internally as well btw), where myListeners is a fixed (concurrent) List of listeners and data the Object to dispatch. On the LinkedBlockingQueue several threads are waiting using the take() method. Now one is woken up as of the new event and does the following:
while (true) {
nextEvent = eventQueue.take();
for (EventTarget target : nextEvent.listeners) {
target.update(nextEvent.data);
}
}
The general idea behind all this, is that for once you utilize all cores for your code, and in addition you keep the amount of objects generated as low as possible (some more optimizations are possible, this is just demo code). Especially you do not need to instantiate new Runnables from scratch for frequent events, which comes with a certain overhead. The drawback is that the code using this kind of GUI model needs to deal with the fact that multi-threading is happening all the time. This is not difficult using the tools Java gives to you, but it is an entire different way of designing your code in the first place.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have finished a GUI app. I have four classes: Main, UserWindow, Task1, Task2. Main class contains a boolean variable buttonStartPressed. Main method starts an instance of the UserWindow class, and waits until the user presses the Start button. As user presses the Start button ( in the UserWindow) the ActionListener assigns true to the static boolean buttonStartPressed and the Main method continues.
Main.java
public static void ......
static boolean buttonStartPressed = false;
...........
while (!buttonStartPress) {
Thread.sleep(50);
}
Task1 t1 = new Task1();
.....
}
}
It works fine, however I do not like the while loop. I feel that this is not the conventional way to write an application. There is another way: i could combine Main and UserWindow classes, and the result of the ActionListener (buttonPressed) would be the start of the Task1. But, on the other hand, I think that Main class and UserWindow classes should be separate from each other.
Yeah, that's wrong. You shouldn't have busy loops....anywhere.
Do you even need the buttonStartPressed variable? Why would you be interested in knowing if it has been pressed, isn't the main idea to perform some action when the button is pressed?
You should create the Task1 in your actionPerformed() method, and depending on what you're trying to do, start a thread that'll perform the task (or just run it in the EDT if it's really fast to do, so it won't freeze the GUI).
Swing (and almost every GUI toolkit) has a dedicated thread. This thread, the Event Dispatch Thread, is started when you first need it. This is generally when you setVisible a JFrame. This thread is a giant loop, whose role is to consume input events and repaint events and to run some logic accordingly.
In your case, you actually have two threads. The first is the main thread and the second is the EDT. Your main thread is doing a busy wait. The code of your actionListener is executed in the EDT as soon as the user presses the button.
You are using a boolean variable as a way to make your two threads communicate. Using some shared memory is indeed one possible way of doing inter-thread communication.
Now, as you suspected you should avoid doing busy waits. It uselessly consumes CPU time, it disturbs the other threads each time it wakes up, and it has an inevitable reaction delay.
Communicating using shared memory is generally bad, too. It is a too low-level way of communicating, and it is often done wrong. Access to a piece of data from two threads must be protected by a locking mechanism. Even a data as simple as a boolean can bite you, as there is no guarantee that if one thread writes to it, the other one will see the modification. In your example, the boolean should be at least declared volatile to have this guarantee.
So, adding the volatile keyword, your solution works : you have an EDT who is happily doing its stuff, and when the user clicks the button, the main thread executes Task1. The first question to ask yourself is : is Task1 a time-consuming task ? Indeed, the simplest solution would be to run Task1 in the EDT, by calling it from actionListener. Be warned that executing some code in the EDT freezes the GUI. If Task1 lasts for less than 100ms, the user won't even notice the freeze, and there is no point in executing it in another thread. If you are worried about coupling your GUI class with your "task" class, then you should just use the observer pattern to prevent a direct dependency.
If the task is time-consuming and you don't want your GUI to freeze, then you should use multiple threads. One solution is the one you implemented. It is somewhat limited, because you only have one main thread, but it works. Your problem now is to make those threads communicate. A really common pattern in inter-thread communication is to use a blocking queue. This is also a shared piece of data, but it is designed to be used by multiple threads. One thread (EDT) writes to it (add()), and the other reads from it (take()) and blocks until something has been written. This may seem overkill for your simple example, but it is a very convenient way of sharing data between threads. The objects written to the blocking queue can be anything ; for example they can represent commands to execute.
A more conventional way of executing a time-consuming function from the GUI is to create or use a dedicated thread when you need to. This can be done using low-level APIs (Thread) or using higher level ones (ExecutorService), both being quite easy to use. Again, use the observer pattern if you want to decouple the GUI action from the thread creation.
I apologize if this wall of text does not offer a simple answer to your question, but there are many things to consider when we mix GUI and threads. I hope it will be useful for you, to understand what your other options are.
I'm building a little software in Java, with a GUI.
I have an algorithm which runs continuously (Almost 24/7) (I have a stop/start button in GUI)
This algorithm should update a list and show a log on the GUI.
The question is- should I create a separate class or thread for this procedure (algorithm),
1) If the answer is yes - Should I transfer the GUI elements that I should update as parameters to that procedure? Would it cause problems updating the GUI?
2) If not - how should I design it?
Many thanks in advance!
You should use for heavy task SwingWorker, is designed for this situations. Here you have a nice article why do we need SwingWorker?.
You need this cause if your algorithm take for example 5 secs and you run in the same thread as gui, it's gonna to freeze your view until finish.
BTW all gui-components must be updated in the Event Dispatch Thread, so you don't have to update them in another thread cause they don't be updated.
The question is- should I create a separate class or thread for this
procedure (algorithm),
Yes, this is a common practice to do so.
Should I transfer the GUI elements that I should update as parameters
to that procedure? Would it cause problems updating the GUI?
You do not really required to pass anything. The only thing you need to enure is that all interactions with ui elements are done within ui thread (to avoid concurrency issues). Usually this is done by creating runnable that does ui-related job and passing it to UI framework you are using to be scheduled in ui thread.