Closing a java program properly when JDialog is the main window - java

I have a JDialog as the main window in my application (originally it was a JFrame but it showed in the taskbar which I didn't want).
Currently I am doing:
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
and when I click an exit button:
frame.dispose();
But the process still seems to hang around in the background
JFrame had JFrame.EXIT_ON_CLOSE which seemed to do what I wanted.
How can I close my application properly?

You need to add a WindowListener that will do System.exit(0) when the dialog closes.
JDialog dialog = ...;
dialog.addWindowListener(new WindowAdapter() {
#Override public void windowClosed(WindowEvent e) {
System.exit(0);
}
});
Of course, the System.exit(0) after you hit the Exit button (that was suggested elsewhere in this thread) is still needed.

You can add
System.exit(0);
where you want the program to end, maybe immediately after the dispose() line.

consider using JWindow(un-decoretad by defalut), but that's little bit complicating fact, that JWindow required initializations from JFrame (just must exist, nothing else) as parent
better would be add WindowListener and all Events/Actions would be redirected/managed this way

You know that the EXIT_ON_CLOSE field is also inherited by JDialog, right?
As mentioned by #camickr, EXIT_ON_CLOSE is not a valid value for the setDefaultCloseOperation method of the JDialog class. As stated by the API,
Sets the operation that will happen by default when the user initiates
a "close" on this dialog. You must specify one of the following
choices:
DO_NOTHING_ON_CLOSE (defined in WindowConstants): Don't do anything; require the program to handle the operation in the
windowClosing method of a registered WindowListener object.
HIDE_ON_CLOSE (defined in WindowConstants): Automatically hide the dialog after invoking any registered WindowListener objects.
DISPOSE_ON_CLOSE (defined in WindowConstants): Automatically hide and dispose the dialog after invoking any registered WindowListener objects.
If EXIT_ON_CLOSE is passed as an argument, an IllegalArgumentException will be thrown.

For me worked only with windowClosing event:
dialog.addWindowListener(new WindowAdapter()
#Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});

you can try this below amazing source code -
JDialog dialog = (JDialog) container;
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.setModal(false);
dialog.setVisible(false);
dialog.dispose();
Runtime.getRuntime().exit(1);
this above said will shut off the process as well as after disposing the JDialog container, also one more benefit is there, if this JDialog is running above any other JFrame or JDialog, so the parent will not terminate but if this JDialog is running on its own, then the process will get terminated completely, Enjoy.

Related

Optional way to close a dialog window

I'm using a custom JFrame to implement a simple dialog in a Java application I'm working on.
After the user pushes the 'Apply' button in the window, it should close.
What would be the most conventional way to do this? Is setVisible(false) inside the class the best way? Is there any way more recommended?
To close a window in Swing like JFrame or JDialog you have two options.
Call dispose()
Just call dispose() method:
public void dispose()
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.
For instance:
frame.dispose();
dialog.dispose();
Dispatch a WINDOW_CLOSING event
You can dispatch a new WindowEvent like this:
frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
dialog.dispatchEvent(new WindowEvent(dialog, WindowEvent.WINDOW_CLOSING));
If the window has attached a WindowListener it will be notified. If the frame's (or dialog's) default close operation is set then this action will be performed. The possible close operations are:
DO_NOTHING_ON_CLOSE (defined in WindowConstants): Don't do anything;
require the program to handle the operation in the windowClosing
method of a registered WindowListener object.
HIDE_ON_CLOSE (defined in WindowConstants): Automatically hide the
frame after invoking any registered WindowListener objects.
DISPOSE_ON_CLOSE (defined in WindowConstants): Automatically hide and
dispose the frame after invoking any registered WindowListener
objects.
EXIT_ON_CLOSE (defined in JFrame and not available for JDialog): Exit the application using the System exit method. Use this only in applications.
It depends on what you're trying to achieve. Setting the window to not visible will simply hide it but it will still be running in the background (JFrame/InternalFrame). You can use JDialog (See JOptionPane as an example) to create temporary frames which are truly closed when clicking on one of the buttons. You can also retrieve the selected option when the user closed the window (here : Javadoc). You can also forcibly close a window by firing an event to close it, like so:
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(
new WindowEvent(frame, WindowEvent.WINDOW_CLOSING)
)
Inside an actionlistener for example.
There are multiple operations which can be performed when you close a JFrame.
Suppose you have a JFrame
JFrame frame = new JFrame();
This one exits the JVM when closed.
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
This one just hides the JFrame.
frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
This one disposes the JFrame.
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
When the last displayable window within the Java virtual machine (VM) is disposed of, the VM may terminate
And the default is do nothing.
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

Second JFrame closes first

two JFrames,
JFrame Main; // Main JFrame
JFrame Sub; //Second JFrame that is initialized from within Main via a JMenuItems ActionListener.
mainMenuItem.setActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
try{
Sub subFrame = new Sub();
subFrame.setVisible(true);
}catch(Exception e){}
}
});
}
The problem is whenever i close the second JFrame (Sub) it closes the first aswell.
Both JFrames have:
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Is that part of the problem?
EXIT_ON_CLOSE means to exit the program immediately (System.exit()) when the frame is closed.
You probably want to set this to DISPOSE_ON_CLOSE, then add a WindowListener and close the program only if both frames have been closed.
(Or, perhaps you want only the main frame to have EXIT_ON_CLOSE)
Yes. JFrame.EXIT_ON_CLOSE by definition exits the application. For your second Frame use DISPOSE_ON_CLOSE or HIDE_ON_CLOSE.
Hope this helps!
You state:
JFrame Sub; //Second JFrame that is initialized from within Main via a JMenuItems ActionListener.
This suggests you've a design problem:
Your 2nd "frame" shouldn't even be a JFrame since it is not behaving as a separate independent main program window.
Instead it's acting as a dialog since it is dependent on and shown from a parent window, the main JFrame. So make the secondary window a JDialog not a JFrame, and all these problems will go away.
You will need to consider whether it should be a modal dialog where the main window is not accessable to the user while the dialog is open, or a non-modal dialog.
Having said that, you may even be better off using one window/JFrame and swapping views via a CardLayout.
Please read this link: The Use of Multiple JFrames, Good/Bad Practice?, and in particular please have a look at Andrew Thompson's community wiki answer.

Automatically close non-modal dialogs after specified time in swing 1.5

In Swing for Java 1.5 I want to create a dialog, which allows the user to do other things in background. I want this dialog to have one button, with which you can close the dialog. If the user doesn't close the dialog within X seconds, it should close itself. In both cases a routine has to be done after the dialog has been closed.
I tried to use Swing Timer with a modal dialog and it works. But, as I noticed above, I need a non-modal dialog. When I set the modal-Property to false, the dialog disappears immediately.
Does someone know, why this happens?
JOptionPane pane = new JOptionPane (text, JOptionPane.WARNING_MESSAGE);
pane.setOptions(new String[]{"Close"});
final JDialog dialog = pane.createDialog(frame, title);
//dialog.setModal(false);
Timer timer = new Timer(time, new ActionListener() {
public void actionPerformed(ActionEvent e) {
dialog.setVisible(false);
}
});
timer.setRepeats(false);
timer.start();
dialog.setVisible(true);
//routine to do after the dialog disappears
for better help sooner post an SSCCE, there no code or descriptions about MultiThreading
don't create final JDialog dialog = pane.createDialog(frame, title); on runtime, create this JDialog one time and re_use that for another action, and / or by removing all childs from ContentPane
override proper event from WindowListener, there you can invoke your custom code before dipose(), setVisible() e.i.
(to point 2nd.) simply to override JDialog#setDefaultCloseOperation to HIDE_ON_CLOSE
all code that invoking a new Top-Level Container on runtime must be wrapped into invokeLater(), especially setVisible(true)
use Application Inactivity by #camickr
In this example, a modeless JDialog containing a direct JOptionPane counts down to zero before closing. A nearby JFrame containing a label remains responsive.
Addendum: As #mKorbel helpfully comments, your class can use a PropertyChangeListener to learn when the dialog's option pane closes. This is a convenient feature of JOptionPane, but you can add your own support, as shown here.

Can I add a WindowListener to a MenuItem?

I have a program written in AWT, so I am using Frame (Not JFrame/Swing).
I am using MenuItem objects to do some operations through ActionListeners.
However, on my last MenuItem, I want to use a WindowListener to close the frame (intending to close the frame without terminating the program altogether).
I am aware that the MenuItem documentation doesn't have a addWindowListener() method. But is there a way around that?
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
f.dispose();
}});
This is pretty much what I'm trying to do, but from a MenuItem.
The window listener is not about making the window close - it's a set of callbacks that happen when a window does particular things. From the Javadoc:
When the window's status changes by virtue of being opened, closed, activated or deactivated, iconified or deiconified, the relevant method in the listener object is invoked, and the WindowEvent is passed to it.
windowClosing has the following Javadoc:
void windowClosing(WindowEvent e)
Invoked when the user attempts to close the window from the window's system menu.
If you want to programatically close the window when someone clicks the menu item, then simply add an action listener with the following:
f.setVisible(false);
f.dispose();

Programmatic close of JFrame

What's the programmatic equivalent of clicking the close (x) button in the upper right corner of a JFrame?
There's the dispose() method but that's not the same thing, since a JFrame can be set to do several different things upon closing (not to mention if there's a WindowListener involved)
You tell the component to dispatch an event. In this case, you want it do dispatch a Window Closing event.
private void exit() {
this.dispatchEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSING));
}
When you hit the x on a JFrame, the system can be set to do various things. The default is that the window is simply hidden with setVisible(false) I believe.
You can set a frame to do different things on close--you can have it dispose, hide or call code based on setDefaultCloseOperation. Here are the options:
DO_NOTHING_ON_CLOSE: Don't do anything; require the program to handle the operation in the windowClosing method of a registered WindowListener object.
HIDE_ON_CLOSE: Automatically hide the frame after invoking any registered WindowListener objects.
DISPOSE_ON_CLOSE: Automatically hide and dispose the frame after invoking any registered WindowListener objects.
EXIT_ON_CLOSE: Exit the application using the System exit method. Use this only in applications.
But I think what you are after is setVisible(false).
You have to insert the call into the AWT message queue so all the timing happens correctly, otherwise it will not dispatch the correct event sequence, especially in a multi-threaded program.
public void closeWindow()
{
if(awtWindow_ != null) {
EventQueue.invokeLater(new Runnable() {
public void run() {
awtWindow_.dispatchEvent(new WindowEvent(awtWindow_, WindowEvent.WINDOW_CLOSING));
}
});
}
}

Categories

Resources