Wait for Swing GUI to close before continuing - java

I am writing an app that requires the user to enter some data into a Swing GUI which the app will then use. After the user enters the data, there is no longer any need for the GUI as the app will then write some data to files.
The General idea is this:
launchGui();
closeGui();
continueWithComputation();
I understand that Swing uses a few threads in the background which I understand is why the program doesn't block until the GUI is closed.
Is it possible in any way to wait for the GUI to close (single JFrame closed with dispose()) before continuing with continueWithComputation()?

Wait for Swing GUI to close before continuing
Use a modal dialog. See the following for further details:
How to Make Dialogs
How to Use Modality in Dialogs

Is it possible in any way to wait for the GUI to close (single JFrame closed with dispose()) before continuing with continueWithComputation()?
user actions add WindowListener
from code to call JFrame#setVisible(false), then you can running continueWithComputation(), you have to close this JVM by System.exit(0), otherwise stays in PC's RAM untill restarted or power-off

I just had a similar problem, but without a closeGui() method and came up with this relatively short code snippet, using a WindowListener and some Java synchronization:
AtomicBoolean closed = new AtomicBoolean(false);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosed(WindowEvent e) {
synchronized(closed) {
closed.set(true);
closed.notify();
}
super.windowClosed(e);
}
} );
frame.setVisible(true);
synchronized(closed) {
while (!closed.get()) {
closed.wait();
}
}
// executes after the Frame has been disposed

My suggestion is to open the JFrame GUI as Modal and then everything will wait until it disappears from the screen. As JFrame cannot be set as modal you have to open the GUI frame as JDialog. I am using:
public class frameMain extends JDialog{
be sure that into the constructor you use:
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
Wherever you need to start the GUI frame you should use:
frameMain frm= new frameMain ();
frm.setModal(true);
frm.setVisible(true);

Related

doClick() not disposing frame

I have a button with an action listener that disposes than reopens a frame. If I physically click the button it works as expected, the frame closes and the same one opens again.
I also have this action linked up with a doClick() in a timer. When the action occurs it opens a new frame without disposing of the other one. The timer works perfectly by itself.
What is the reason for this and how can I fix it? Is it a problem with the timer or calling it through the doClick?
I am relatively new to all this so this may be a simple question. Thanks
Button code:
frmStart s = new frmStart();
s.setVisible(true);
this.dispose();
doClick code (change is boolean):
Timer t = new Timer();
t.schedule(new TimerTask() {
#Override
public void run() {
if(change) {
btnReload.doClick();
}
}
}, 400);
With what you have provided, my best guess is to have you switch you Timer import from util.Timer to javax.swing.Timer
Then you would instantiate it like so:
Timer t = new Timer(400, (e)->{
if(change)
btnReload.doClick();
});
Then start it
t.start();
It isn't a good idea, and sometimes won't even work, to interact with swing objects outside the Swing Thread. When using javax.swing.Timer it runs the defined functionality within the Swing Thread
Dispose does not kill the frame. Quote:
Releases all of the native screen resources used by this Window, its
subcomponents, and all of its owned children. That is, the resources
for these Components will be destroyed, any memory they consume will
be returned to the OS, and they will be marked as undisplayable.
The frame itself is alive until the GC kicks in. And the GC does nothing because the timer is still active. So you should dispose the frame and then cancel the timer.

Focussing in Java swing

I'm developing an application using java swing. When I click a button, I want another window to be opened. This works fine. But it is possible to alt+tab to the original window and then interact with it even after the new window is open. Is there any way not to let the user focus the original window after the new window appears? By window I'm referring to Jframe/Jdialog.
Assuming the instance of your main JFrame window is called mainWindow:, the following code will prevent switching the focus.
// the second parameter makes the dialog modal and will prevent
// switching the focus to the mainWindow
JDialog dialog = new JDialog(mainWindow, true);
...
dialog.setVisible(true);
Documentation on JDialog: http://docs.oracle.com/javase/6/docs/api/javax/swing/JDialog.html
You may try to use a JDialog instead of JFrame and pass the instance of JFrame to JDialog constructor
You may also try to check
frame.setAlwaysOnTop(true);
or may be like this:-
frame.toFront();
frame.setState(Frame.NORMAL);

JDialog Freezes on Loss of Focus?

I have a program I'm working on that is supposed to facilitate the making of texture maps by allowing you to edit individual textures in the map. I have several places where I use JDialog's for things like input of the tile-size of a map, the initial size of a new map, and one that simply has a button on it that the user presses when he or she is done editing the selected textures with an external program (such as photoshop or paint.) However, any time one of these JDialog's is up, if the program loses focus it becomes completely unresponsive. Here's my code for the JDialog that pops up when you're editing selected textures externally:
JDialog editing = new JDialog(mainFrame, "Externally Editing");//mainFrame is the name of the JFrame containing everything.
JPanel pnl = new JPanel();
editing.setLayout(new BorderLayout());
pnl.setPreferredSize(new Dimension(150, 60));
editing.add(pnl);
editing.pack();
JButton button = new JButton("Done Editing");
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
editng = false;//Obviously, a boolean that I have outside of this method.
}
});
pnl.add(button);
Thread.sleep(100);
editing.setVisible(true);
while(editng){System.out.print("");}//Doing nothing while the user is externally editing.. Unfortunately, if I don't have "System.out.print("");" it doesn't work.. Oh, Java..
new Thread(new Runnable(){public void run(){editing.dispose();}}).start();//Gotta dispose of it in a separate thread since AWT isn't Thread-safe... Ugh..
I would assume that it freezes in the AWT Thread that it creates/has for the JDialog, while my thread is just waiting for the button to be pressed.. Which can't happen because the JDialog is frozen.
Make your dialog modal. Your application will stop processing until the dialog is closed
Why this bogus roundabout? Simply dispose the dialog in the listener.

How to properly hide a JFrame

I have a very simple JFrame window that contains one button: No.
In the main function I set setVisible(true); my JFrame and in the No button listener I want to close the window so I set the visibility to false: setVisible(false); and after that I do System.exit(0); in order to prevent possible memory leaks when running the program many times.
I have two questions:
Do I really need to System.exit(0); in the above case?
If I have this JFrame as a popup window, I can't really use System.exit(0); because this will terminate the whole program. So how can I properly close the popup window and stay in the main JFrame window? (Now I close it only by setVisible(false); and when I do it several times through the program execution, the program turns very slow).
use CardLayout
if is there real reason for another popup container
use JDialog with parent to JFrame, with setModal / ModalityTypes
create only one JDialog and to reuse this one JDialog by getContentPane#removeAll()
use JOptionPane for simple users interaction
put both together, above two points, to use CardLayout for popup JDialog with parent to JFrame, notice after switch from one card to another could be / is required to call JDialog.pack()
setVisible will cause slowdown
dispose will cause slowdown
System.exit will close entire JVM
Therefore, you should reuse a single JFrame or JDialog.
In the button's ActionListener, invoke frame.setVisible(false);. Then instead of creating a new frame just do frame.setVisible(true);. If you want to change the contents of the frame, there is the function frame.getContentPane().removeAll();.
Just add this: JFrame.setDefaultCloseOperation(DISPOSE_ON_CLOSE).
Note: The default option for JFrame is HIDE_ON_CLOSE.
You can use the dispose() method of the JFrame class to close the frame and release all resources associated with it, including its child components.

how do i close a frame yet open a new frame?

how do i close a frame yet open a new frame?
i have a frame, (help)
when i click on my menu item
i want to open (mainForm)
exit from help.
new mainForm().setVisible(true);
System.exit(0);
i know this closes the whole program however how do i get it to only close the current frame
thanks
If you no longer want to use the frame you could use frame.dispose()
If you just want to hide it use frame.setVisible(false).
If you extended a Frame and are trying to close it from within use this.dispose or this.setVisible(false).
You should rethink your requirments. For the user, it would be best to have both the program and the help window visible at the same time. Closing the main window when showing the help screen and vice versa is really, really bad for usability - you shouldn't do it. We've had window-based GUIs for almost 30 years now - showing several windows on screen at the same time is what they're for!
Let's say you created your frame as so:
JFrame mainframe = new JFrame("Radio Notes");
//show Frame
mainframe.setVisible(true);
//close the frame
mainframe.dispose();
I think you should hide the frame you do not wish shown with setVisible(false). System.exit(0) stops the JVM ending the entire program.
In short, the semantics of setVisible has nothing to do with starting / stopping the application.
If you want to start an entire new application you'd have to look at Runtime.exec(). I don't really know if you can close the parent process (the Help application) with exit() though.
try setting the default close operation for the JFrame like so.
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
Then implement a WindowListener that performs the actions you want when a window closing event is fired.

Categories