Creating JFrame in a new Thread(new messageloog) - java

Hi
i am trying to create multi JFrames but I want each one to has its own Thread (message loop) ,so when one JFrame freezes the others will keep working
i tried to create each jframe from different Threads, but they are still working in the "AWT-EventQueue-0" thread.
i come from a dotnet background. so when i want to do this scenario in a winForms app i usually call
Application.run(new form())
from a new thread
can u please tell me how to do this in java ?
thanks in advance!

There is only UI thread in Java, no matter how many frames you open. I would suggest you to execute the long running operation within a thread.
public void actionPerformed(ActionEvent e)
{
new Thread(new FrameRunnable()).start();
}
public class FrameRunnable implements Runnable
{
public void run()
{
// Do stuff here
}
}
Hope this will help.

Read the section from the Swing tutorial on Concurrency to understand how the Event Dispatch Thread works. All updates to GUI components must be done on the EDT. If you have long running tasks, you can use a SwingWorker or a separate Thread along with SwingUtilities.invoke(...) later to add code to the EDT.

Create a new thread for each JFrame generated. Take note of your Thread variables and pass it around on your Runnable.

Related

java threads or swingWorker and gui good practice

I had a little issue, I wanted to do something in a thread and after it finishes to open a new GUI window. I found a couple of solutions:
Is to make a thread and inside the thread do my work and line after that update my GUI, to me this way feels not good, because I feel that updating my GUI through a thread who wasn't meant for updating GUI isn't the best idea.
new Thread(() -> {
doSomethingsHere()
updateGui();
}).start();
Using a SwingWorker which was built exactly for this, however takes a lot of lines and doing it couple of times might make my code a bit messy.
public void doThingsInBackground() {
SwingWorker<Void,Void> SwingWorker = new SwingWorker<Void, Void>(){
protected Void doInBackground(){
doSomethingsHere()
return (Void) new Object();
}
protected void done(){
updateGui();
}
};
SwingWorker.execute();
}
Using a thread and a listener, like a custom event that when the thread ends the event runs, which for some reason feels the best for me.
My question is, which is the best "good practice"?
SwingUtilities.invokeLater(Runnable); or SwingWorker is the way to go. Updating UI from Thread will not work, as UI events need to be processed in EDT (event dispatch thread) - main thread.
SwingUtilities.invokeLater(Runnable); dispatches runnable to EDT to be processed. SwingWorker is doing the same when process(List) or done() are invoked.

Should Swing GUI application be controlled from Event Dispatcher or main thread?

I've read a few books about Java. In all of them there was at least one chapter teaching GUI programming. In all of them, creating a simple form application was following this logic:
MyFrame.java
public class MyFrame extends JFrame
{
JButton button1;
public MyFrame()
{
button1 = new JButton("Click here.");
}
}
FrameTest.java:
public class FrameTest
{
public static void main(String[] args)
{
MyFrame myFrame = new MyFrame();
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myFrame.setSize(600, 600);
myFrame.setVisible(true);
}
}
Basically, just subclass JFrame to create a form and declare as instance variables the other components and initialize those components in the constructor. And then create another test class, instantiate the frame subclass in that class and call some of its methods to make it visible.
But in concurrency lessons I've learned that we have a main thread which runs main() in every application we create. As far as I know, when we use Swing in order to create GUI applications we have another thread (Event Dispatcher Thread). So if i am not mistaken, in every Swing based GUI application there are at least two threads. This makes every GUI application multithreaded. And in some articles and tutorials that I've read, it says that Swing doesn't support multithreading therefore all GUI components should be created and modified only in Event Dispatcher Thread otherwise Thread Interference and Memory Inconsistency Errors may arise.
Even in the simplest example in Wikipedia (http://en.wikipedia.org/wiki/Swing_%28Java%29), it's made like this via invokeLater method.
So which one is the true approach? Where am I wrong?
ALL interactions with any UI/Swing component MUST be done for within the context of the EDT
When starting an application, you should ensure that you are executing within the EDT BEFORE you try and create/interact with any Swing component.
Simply put, you should use something like...
EventQueue.invokeLater(new Runnable() {
public void run() {
// Now in the event dispatching thread
}
});
If you need to run long running task or perform any blocking task, you should execute it in a separate thread. SwingWorker is a good choice in most cases as it provides some simple mechanisms for re-syncing code to the event dispatching thread.
Take a read through
Initial Thread
Will the real Swing Single Threading Rule please stand up?
So, the short answer is, yes, all Swing based code should be accessed/modified/interacted with from the context of the EDT
So if i am not mistaken, in every Swing based GUI application there
are at least two threads
Yes. One is main thread and other is EDT(Event Dispatch Thread).
This makes every GUI application multithreaded.
Yes. But in that case , the other thread is not interacting with the GUI component.
Swing doesn't support multithreading therefore all GUI components
should be created and modified only in Event Dispatcher Thread
otherwise Thread Interference and Memory Inconsistency Errors may
arise.
Yes , Absolutely true. This means that at a time only one Thread should interact with the given GUI component.
A Swing programmer deals with the following kinds of threads:
Initial threads, the threads that execute initial application code.
The event dispatch thread, where all event-handling code is executed. Most code that interacts with the Swing framework must also execute on this thread.
Worker threads, also known as background threads, where time-consuming background tasks are executed.
The programmer does not need to provide code that explicitly creates
these threads: they are provided by the runtime or the Swing
framework. The programmer's job is to utilize these threads to create
a responsive, maintainable Swing program.

Java bug on Mac OSX? [duplicate]

I am trying to create a program to perform a simple task and produce an output every x seconds. I also want the program to run until I decide to manually close the program.
I have been attempting to implement this using a Swing timer, as I believe this is the best way. The problem is I'm not sure how to keep the program going once the main method has finished executing. So for example I have:
static ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
try {
//do stuff
} catch (Exception e) {
e.printStackTrace();
}
}
};
public static void main(String[] args) throws Exception{
Timer timer = new Timer(3000, taskPerformer);
timer.start();
}
which just finishes execution immediately. I can dodge the problem by putting the current thread of execution to sleep Thread.currentThread().sleep(..), but this feels like a botch job, and will be ultimately be finite in duration. I can also do while(true), but I believe this is bad practice.
My question is how to get the desired persistence behavior, and if there is a better way than using Swing timers.
Thanks.
A Swing Timer will stay alive as long as the EDT is alive, usually this is done by having a Swing GUI present and visible (this creates a non-daemon thread that persists until the GUI exits). If you don't need a Swing GUI, then don't use a Swing Timer. Perhaps instead use a java.util.Timer, and don't exit the main method til you give the word (however you plan to do that).
Use java.util.Timer instead. The associated thread will not run as a daemon.

does swing view needs synchronized methods if its set by new threads in controller

There is actually more than 1 question.
Given Model View and Controller. (Mine are coupled a lot - View knows its Controller, and Controller knows View.)
Does new threads in Controller can be fired in basic manner - with the new Runnable(){ (...) run(){}} or it is required to do in some "swing way", to make it properly? Maybe with Timer or invokeLater()?
Second thing is - assuming that new thread has started - when it operates directly on view, setting some JTextFields (and so on) - do methods such as setThatTextFieldWithNewValue(msg) need to be synchronized as a result of being called from need thread? If so - is there any better approach that gives less coupling and less spend time thinking about needed synchronization?
there are a few ways how is possible to create, manage and notify MVC, for better help sooner post an SSCCE
Runnable#Thread is very confortable, stable and clear way, but I'd suggest to wrap all output to the Swing GUI into invokeLater, including thread safe methods as setText, append e.g. are ..
as Kumar Vivek Mitra (+1) metioned there is SwingWorker, but required deepest knowledge about Java essential classes, some trouble are there with exceptions recycle how to get exception from SwingWorker
about MVC maybe will help you my similair question
Swing is not Thread-Safe
1. The UI thread is the Event Dispatcher Thread, which is responsible for the Gui work.
2. Try working with Non-Ui threads outside the UI thread.
3. Yes offcourse you can fire a thread from within the UI thread, but its advisable to keep it out of
the UI thread, else the GUI may seems non-responsive.
(ie. the Non-UI work on the Non-UI thread OUT of the UI thread which is responsible for the UI Work)
4. Well there is a swing way too... use SwingWorker, this handles the synchronization between UI and Non-UI thread.
Edited part:
// PLEASE NOTE ITS NOT GOOD TO ADD COMPONENTS DIRECTLY ON THE FRAME/JFRAME, BUT I AM DOING THIS JUST TO SHOW, WHAT I MEANT.
public class MyClass extends JFrame{
private final JButton b;
public MyClass(){
this.setSize(300,300);
this.setComponent();
this.setHandler();
}
public void setComponent(){
b = new JButton("Click");
this.add(b);
}
public void setHandler(){
b.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
// Do whatever you want...
}
});
}
public static void main (String[] args) {
EventQueue.invokeLater(new Runnable(){ // UI THREAD
public void run(){
MyClass s = new MyClass();
s.setVisible(true);
}
});
}
}
Main method is short lived in Swing, The main method() schedules the Construction of GUI to the Event Dispatcher Thread (EDT), and then quits. So its EDT responsibility to handle the GUI. So its always advisable to keep the Non-UI work on the Non-UI thread away from EDT.
Anything in swing has to run on the EventQueue. If you have a method called from swing it will already be running there (as in an Action listener). If you don't know if you're on the event queue, EventQueue.isDispatchThread() will tell you. When you know you're not, reference a swing class or method using EventQueue.invokeLater() or invokeAndWait if you need to see results. (This must be done from the main method.)
Be very careful about this; you have to check your code. If not, my experience is that the swing UI will be just a little bit flakey, with the occasional unreproducable oddity. There's no easy way around eyeballing each line of code.
Actually, there is. Do everything on the EventQueue, then you won't have to worry. You're probably not doing a whole lot of work outside swing anyway. If you are, it's probably worth the loss of speed to avoid multithreading problems. If your non-swing work is extensive but simple, use the SwingWorker class. It gives you an extra thread under highly controlled conditions and should save you a lot of grief.
Your classes (View and Controller) are independent of threads, and should work just fine all running in one thread. Don't confuse classes and threads. (I'll admit, I'd be tempted to have the Controller firing off threads in all directions, but you have to be prepared to be very careful and know everything there is to know about multithreading.)
If you do multithread, the EventQueue can be a bit handy because you don't have to protect fields referenced only there--it's an island of single threading in a dangerous sea. On the other hand, don't do any synchronization there; you'll block your UI. You can launch threads from there and you may have to just to avoid blocking. (Once you start multithreading, it's hard to stop.)
The easiest way would be:
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
// Run your code here.
}
});
For more complex tasks (send process chunks to ui thread, respond to jobFinished):
new SwingWorker<String, String>() {
#Override
protected void done() {
}
#Override
protected void process(List<String> arg0) {
}
#Override
protected String doInBackground() throws Exception {
}
}.execute();

Updating Swing component from another thread with invokeLater or SwingWorker

I'm developing a small app, which would have Swing GUI. App is doing IO task in another thread, when that thread finishes GUI should be updated acordingly to reflect thread's operation result. Class running in a (worker, non-GUI) has object passed to it in contructor which would be used for updating GUI, so I don't need to put GUI stuff in a non-GUI class, but rather pass object for updating GUI to that class.
As I understand form reading here, (thread/swing) safe options for updating (changing) Swing GUI would be to use javax.swing.SwingUtilities.invokeLater(), javax.swing.SwingUtilities.invokeLaterWait() and/or javax.swing.SwingWorker() which basically are doing the same thing.
This all threading issue with Swing is a little confusing for me, and yet I need to use threads to do anything meaningful in GUI apps and not hung GUI while processing in EDT, so what interests me for now is this:
Are invokeLater and invokeLaterWait like sending message to EDT and waiting for it do it when it finishes processing messages that were before that call?
is it correct from Swing thread safety aspect, to do something like this:
interface IUPDATEGUI {
public void update();
}
// in EDT/where I can access components directly
class UpdateJList implements IUPDATEGUI {
public void update() {
// update JList...
someJList.revalidate();
someJList.repain();
}
}
class FileOperations implements Runnable {
private IUPDATEGUI upObj;
List<File> result = new ArrayList<File>; // upObject is accessing this
public void FileOperations(IUPDATEGUI upObj) {
this.upObj = upObj;
}
private void someIOTask() {
// ...
// IO processing finished, result is in "result"
}
public void run() {
someIOTask();
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
upObj.update(); // access result and update JList
}
}; );
}
}
In case this isn't correct then how should this be done?
If I could, I would prefer to use invokeLater instead of SwingWorker if possible, because I wouldn't need to change my whole class and it's somehow more neat/distinct me (like sending a message in Win32 apps).
Thanks in advance.
Using invokeLater() and invokeAndWait() passes the Runnable parameter into the queue awaiting execution in the EDT. So calling invokeLater() will cause the Runnable to execute in the EDT when the EDT is able to process the request. invokeAndWait() simply waits (in the calling thread) until this execution takes place.
Using SwingWorker is ideal if you want to do background tasks that notify the EDT either at the end of execution or in intermediate states. An example would be to pass the current progress of a process to a JProgressBar.
For your example it seems that SwingWorker is a better choice but if you don't want to change your code too much then calling invokeLater() when the process is done will be just fine.
I'd recommend not using the invokeAndWait until java 7. I found a spurious wake-up on this method that can cause really painful bugs. For me it led to some really rare and hard to debug null pointer exceptions.
http://bugs.sun.com/view_bug.do?bug_id=6852111
It's fixed as of java 7 b77.
invokeLater is fine. This puts the call into the AWT event queue, so that it will get executed in the EDT in due course. Your program will continue running, and does not wait for your callable to get called.

Categories