how to call a method before exit in jframe with java - java

i tried like they answered in this question
How can save some Objects, directly after the User has closed the Applications JFrame, but before the Program exits?
but the frame won't close
i wrote the following but it's the same thing, the frame wont close .
#Override
public void windowClosed(WindowEvent e) {
dispose();
setVisible(false);
System.exit(0);
}
#Override
public void windowClosing(WindowEvent e) {
dispose();
setVisible(false);
System.exit(0);
}

you can add shutdown hook in general to do work just before the jvm exits, no need for these listeners.
Shutdown Hook
If you want to do it by listener, use the windowClosedEvent:
#Override
public void windowClosed(WindowEvent e) {
save();
}
By default the last frame exits the application, unless you did not set the default close operation to anything other than DISPOSE_ON_CLOSE.

Related

Java - How to "unhide" a JFrame

I am quite new to Java, but familiar with native Android dev so bear with me xD. I created an application that creates a JFrame. Then I set the closeOperation to: setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);.
It performs as expected, the frame is hidden and this is what I want (when I close). I need the application to keep on running (only once instance), because I am running a thread in the background that is performing an operation.
My actionListener on my button in my JFrame currently does this: setVisible(false);
My question is this, how can I maximize the JFrame again after it has been hidden? Would it be possible to display the frame when the user clicks on the minimized application in the task bar? Is there some type of listener that I need to implement?
Thanks in advance, any advice will be appreciated
UPDATE
For this solution to work correctly you need to do the following. Also have a look at XtremeBaumer's answer for this to make sense.
On JFrame creation setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);.
When you want to minimize the app (on click possibly) frame.setState(Frame.ICONIFIED);.
When you want to maximize the app again frame.setState(Frame.NORMAL); in windowDeiconified event.
One last thing, if you want to also minimize your app when the user clicks on the exit button (red x) add this to the windowClosing event frame.setState(Frame.ICONIFIED);.
this.addWindowListener(new WindowListener(){
#Override
public void windowActivated(WindowEvent e) {
}
#Override
public void windowClosed(WindowEvent e) {
}
#Override
public void windowClosing(WindowEvent e) {
setState(Frame.ICONIFIED)
}
#Override
public void windowDeactivated(WindowEvent e) {
}
#Override
public void windowDeiconified(WindowEvent e) {
this.setVisible(true);
//this should be what you want
}
#Override
public void windowIconified(WindowEvent e) {
}
#Override
public void windowOpened(WindowEvent e) {
}
});
i hope this solves your question. add it to your JFrame

How to stop executing code after setVisible of JWindow until it is closed?

For example, I have code like:
public static void main(String[] args) {
JWindow w = new JWindow();
w.setSize(100, 100);
w.setVisible(true);
// some code need to be executed after window is closed, Eg.
System.out.println("some code need to be executed after window is closed");
}
I want code to stop at w.setVisible(true); until the window is closed/setVisible(false), then execute System.out.println("window closed");, how to achieve this?
you could refer to this link
you can override the windowClosing() method
public void windowClosing(WindowEvent e) {
System.out.println("window closed");
}
or windowClosed()
public void windowClosed(WindowEvent e) {
System.out.println("window closed");
}
based on what you are doing, right after the setVisible(true) start the screen capture in your constructor for example, and then the screen capture should tell you that the process is done so you can proceed to your other code execution. there is no need to pause the code execution.
You can use window closing event or window closed event
public void windowClosing(WindowEvent e)
{
System.out.println("window closed");
}
OR
public void windowClosed(WindowEvent e)
{
System.out.println("window closed");
}

JFrame.HIDE_ON_CLOSE onHide event?

I have a WorldEditor JFrame that launches a Game JFrame. However, when the Game closes, I don't want it to end the entire program, so I set the default close operation to HIDE_ON_CLOSE. But, to save resources, I pause the WorldEditor while the Game is running.
How can I detect when the Game window is hidden so I can resume WorldEditor?
Why don't you hide the frame yourself instead of using a default HIDE_ON_CLOSE?
// inside WindowListener class
public windowClosing(WindowEvent e) {
yourFrame.setVisible( false );
// your code here...
}
Edit made: from docs:
The default close operation is executed after any window listeners
handle the window-closing event. So, for example, assume that you
specify that the default close operation is to dispose of a frame. You
also implement a window listener that tests whether the frame is the
last one visible and, if so, saves some data and exits the
application. Under these conditions, when the user closes a frame, the
window listener will be called first. If it does not exit the
application, then the default close operation — disposing of the frame
— will then be performed.
New edit with a working example:
import java.awt.event.*;
import javax.swing.JFrame;
public class ListenerTest extends JFrame implements WindowListener {
public static void main(String[] args) {
ListenerTest frame = new ListenerTest();
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.setVisible( true );
}
public ListenerTest() {
this.addWindowListener( this );
}
public void windowActivated(WindowEvent e) {
System.out.println(" activated ");
}
public void windowClosed(WindowEvent e){
System.out.println(" closed ");
}
public void windowClosing(WindowEvent e){
System.out.println(" closing ");
}
public void windowDeactivated(WindowEvent e){
System.out.println(" deactivated ");
}
public void windowDeiconified(WindowEvent e){
System.out.println(" deiconified ");
}
public void windowIconified(WindowEvent e){
System.out.println(" iconified ");
}
public void windowOpened(WindowEvent e){
System.out.println(" opened ");
}
}
Test this out in order to catch what which events are firing.

Recursion causes exit to exit all JFrames (terminates app)

I have made an application that gives the user the option to open up a new spawn of the application entirely. When the user does so and closes the application the entire application terminates; not just the window.
How should I go about recursively spawning an application and then when the user exits the JFrame spawn; killing just that JFrame and not the entire instance?
Here is the relevant code:
[...]
JMenuItem newMenuItem = new JMenuItem ("New");
newMenuItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
new MainWindow();
}
});
fileMenu.add(newMenuItem);
[....]
JMenuItem exit = new JMenuItem("Exit");
exit.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
});
fileMenu.add(exit);
[...]
First you should try JFrame.DISPOSE_ON_CLOSE instead of JFrame.EXIT_ON_CLOSE because EXIT_ON_CLOSE shuts down the application no matter if there are active threads running or not.
If you still have issues you should consider to introduce an instance counter. To react smarter
See also this discussion
I completely removed the frame.setDefaultCloserOperation(JFrame.EXIT_ON_CLOSE); code.
I changed it to DISPOSE_ON_CLOSE and still the problem was still happening. I ended up creating a windowEvent and adding: frame.dispose(); and the behavior is what I wanted.
Here is the code:
frame.addWindowListener(new WindowListener() {
public void windowClosing(WindowEvent e) {
//Allows for multiple instances and properly closing
//only one of the Frames instead of all of them
frame.dispose();
}
public void windowOpened(WindowEvent e) {}
public void windowClosed(WindowEvent e) {}
public void windowIconified(WindowEvent e) {}
public void windowDeiconified(WindowEvent e) {}
public void windowActivated(WindowEvent e) {}
public void windowDeactivated(WindowEvent e) {}
});

How to close a Java Swing application from the code

What is the proper way to terminate a Swing application from the code, and what are the pitfalls?
I'd tried to close my application automatically after a timer fires. But just calling dispose() on the JFrame didn't do the trick - the window vanished but the application did not terminate. However when closing the window with the close button, the application does terminate. What should I do?
Your JFrame default close action can be set to "DISPOSE_ON_CLOSE" instead of EXIT_ON_CLOSE (why people keep using EXIT_ON_CLOSE is beyond me).
If you have any undisposed windows or non-daemon threads, your application will not terminate. This should be considered a error (and solving it with System.exit is a very bad idea).
The most common culprits are java.util.Timer and a custom Thread you've created. Both should be set to daemon or must be explicitly killed.
If you want to check for all active frames, you can use Frame.getFrames(). If all Windows/Frames are disposed of, then use a debugger to check for any non-daemon threads that are still running.
I guess a EXIT_ON_CLOSE
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
before System.exit(0) is better since you can write a Window Listener to make some cleaning operations before actually leaving the app.
That window listener allows you to defined:
public void windowClosing(WindowEvent e) {
displayMessage("WindowListener method called: windowClosing.");
//A pause so user can see the message before
//the window actually closes.
ActionListener task = new ActionListener() {
boolean alreadyDisposed = false;
public void actionPerformed(ActionEvent e) {
if (frame.isDisplayable()) {
alreadyDisposed = true;
frame.dispose();
}
}
};
Timer timer = new Timer(500, task); //fire every half second
timer.setInitialDelay(2000); //first delay 2 seconds
timer.setRepeats(false);
timer.start();
}
public void windowClosed(WindowEvent e) {
//This will only be seen on standard output.
displayMessage("WindowListener method called: windowClosed.");
}
Try:
System.exit(0);
Crude, but effective.
May be the safe way is something like:
private JButton btnExit;
...
btnExit = new JButton("Quit");
btnExit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e){
Container frame = btnExit.getParent();
do
frame = frame.getParent();
while (!(frame instanceof JFrame));
((JFrame) frame).dispose();
}
});
The following program includes code that will terminate a program lacking extraneous threads without explicitly calling System.exit(). In order to apply this example to applications using threads/listeners/timers/etc, one need only insert cleanup code requesting (and, if applicable, awaiting) their termination before the WindowEvent is manually initiated within actionPerformed().
For those who wish to copy/paste code capable of running exactly as shown, a slightly-ugly but otherwise irrelevant main method is included at the end.
public class CloseExample extends JFrame implements ActionListener {
private JButton turnOffButton;
private void addStuff() {
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
turnOffButton = new JButton("Exit");
turnOffButton.addActionListener(this);
this.add(turnOffButton);
}
public void actionPerformed(ActionEvent quitEvent) {
/* Iterate through and close all timers, threads, etc here */
this.processWindowEvent(
new WindowEvent(
this, WindowEvent.WINDOW_CLOSING));
}
public CloseExample() {
super("Close Me!");
addStuff();
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
CloseExample cTW = new CloseExample();
cTW.setSize(200, 100);
cTW.setLocation(300,300);
cTW.setVisible(true);
}
});
}
}
If I understand you correctly you want to close the application even if the user did not click on the close button. You will need to register WindowEvents maybe with addWindowListener() or enableEvents() whichever suits your needs better.
You can then invoke the event with a call to processWindowEvent(). Here is a sample code that will create a JFrame, wait 5 seconds and close the JFrame without user interaction.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class ClosingFrame extends JFrame implements WindowListener{
public ClosingFrame(){
super("A Frame");
setSize(400, 400);
//in case the user closes the window
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
//enables Window Events on this Component
this.addWindowListener(this);
//start a timer
Thread t = new Timer();
t.start();
}
public void windowOpened(WindowEvent e){}
public void windowClosing(WindowEvent e){}
//the event that we are interested in
public void windowClosed(WindowEvent e){
System.exit(0);
}
public void windowIconified(WindowEvent e){}
public void windowDeiconified(WindowEvent e){}
public void windowActivated(WindowEvent e){}
public void windowDeactivated(WindowEvent e){}
//a simple timer
class Timer extends Thread{
int time = 10;
public void run(){
while(time-- > 0){
System.out.println("Still Waiting:" + time);
try{
sleep(500);
}catch(InterruptedException e){}
}
System.out.println("About to close");
//close the frame
ClosingFrame.this.processWindowEvent(
new WindowEvent(
ClosingFrame.this, WindowEvent.WINDOW_CLOSED));
}
}
//instantiate the Frame
public static void main(String args[]){
new ClosingFrame();
}
}
As you can see, the processWindowEvent() method causes the WindowClosed event to be fired where you have an oportunity to do some clean up code if you require before closing the application.
Take a look at the Oracle Documentation.
Starting from JDK 1.4 an Application terminates if:
There are no displayable AWT or Swing components.
There are no native events in the native event queue.
There are no AWT events in java EventQueues.
Cornercases:
The document states that some packages create displayable components without releasing them.A program which calls Toolkit.getDefaultToolkit() won't terminate. is among others given as an example.
Also other Processes can keep AWT alive when they, for what ever reason, are sending events into the native event queue.
Also I noticed that on some Systems it takes a coupple of seconds before the Application actually terminates.
I think, the idea is here the WindowListener - you can add any code there that you'd like to run before the thing shuts down
In response to other comments, DISPOSE_ON_CLOSE does not seem to properly exit the application - it only destroys the window, but the application will continue running. If you want to terminate the application use EXIT_ON_CLOSE.

Categories