My application is using JOptionPane
s at some points for input of information.
At the same time that JOptionPane
is shown, changes can happen on the GUI that are made from other clients over the network. These can be text on JTextArea
, or nodes changing on JTree
.
Does that mean that I need to create the JOptionPane
on a new thread so that I will not have problems on the changes made during JOptionPane
is active?
I looked on a few places on internet but I did not get a clear answer.
p.s JOptionPane
is created when a user clicks on a button.
Swing is single threaded, so the option of 'using another thread' is simply not an option. However, that does not mean your components can not be updated while the option pane is shown. See below for an example. I added a System.out call to illustrate that the JOptionPane call is blocking, but due to the Swing timer I can append text to my JTextArea (on the EDT).
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.Timer;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class UpdateOptionPane {
private static void showUI(){
final JFrame testFrame = new JFrame( "TestFrame" );
final JTextArea textArea = new JTextArea( );
testFrame.add( new JScrollPane( textArea ), BorderLayout.CENTER );
Timer timer = new Timer( 1000, new ActionListener() {
@Override
public void actionPerformed( ActionEvent e ) {
textArea.append( "bla" );
}
} );
timer.setRepeats( true );
timer.start();
JButton button = new JButton( "Click me" );
button.addActionListener( new ActionListener() {
@Override
public void actionPerformed( ActionEvent e ) {
System.out.println("Before option pane");
JOptionPane.showMessageDialog( testFrame, "A message dialog" );
System.out.println("After option pane");
}
} );
testFrame.add( button, BorderLayout.SOUTH );
testFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
testFrame.pack();
testFrame.setVisible( true );
}
public static void main( String[] args ) {
EventQueue.invokeLater( new Runnable() {
@Override
public void run() {
showUI();
}
} );
}
}