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.
Related
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
I need to take a screenshot of an area of my screen, to make that i use "Robot" in Java. But if the user place the windows in the area, the windows will be on the screenshot instead of the background.
I tried to solve my problem by placing a :
myframe.setVisible(false);
But when i look the screenshot the windows appear on it. I thought it was because the windows didn't have enough time to disappear or because the render of the screen wasn't updated yet, so i tried different things like using:
repaint();
Or by placing a
try{}finally{}
block to be sure that the actions in the try block have been finished.
But no one of these solution works. These is other ways in my mind but they looks globally bad because they use functions to wait.
So is there a good solution to my problem?
You could use window listener to fire the screen shot when window is closing:
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class MainFrame extends JFrame implements WindowListener {
public MainFrame() {
super("Test Frame");
JLabel displayMsg = new JLabel(" Close window");
getContentPane().add(displayMsg);
addWindowListener(this);
setSize(400, 300);
setVisible(true);
}
#Override
public void windowClosing(WindowEvent e) {
System.out.println("WindowListener method called: windowClosing.");
//add you screen capture code here
}
//--Not used
#Override
public void windowClosed(WindowEvent e) {
//do nothing
}
#Override
public void windowOpened(WindowEvent e) {
//do nothing
}
#Override
public void windowIconified(WindowEvent e) {
//do nothing
}
#Override
public void windowDeiconified(WindowEvent e) {
//do nothing
}
#Override
public void windowActivated(WindowEvent e) {
//do nothing
}
#Override
public void windowDeactivated(WindowEvent e) {
//do nothing
}
public void windowGainedFocus(WindowEvent e) {
//do nothing
}
public void windowLostFocus(WindowEvent e) {
//do nothing
}
public static void main(String[] args) {
new MainFrame();
}
}
Use SwingUtilities.invokeLater() to take the actual screenshot. Not 100% sure, but I think that myframe.setVisible(false); doesn't become effective till the program flow goes back to the event dispatching loop.
EDIT:
instead of
useRobotToMakeScreenshot();
write
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
useRobotToMakeScreenshot();
}
}
(of course, you have to replace useRobotToMakeScreenshot() with the actual call to the method that does the screenshooting thing)
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");
}
I want it to stay open and wait for the event to happen but as soon as it opens it closes how do i fix this?
static void hi()
{
System.out.println("g");
}
public static void main(String[] args)
{
}
#Override
public void KeyPressed(KeyEvent e) {
hi();
}
#Override
public void KeyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void KeyTyped(KeyEvent e) {
// TODO Auto-generated method stub
} <code>
Edit: wait even when i do have a frame when i press a key it dos not run hi()
You do not create any window to get an event. Your main function is empty, so your program does nothing: its process closes after it starts.
Look at Creating a GUI with Swing tutorial. You'll find the simplest Hello World GUI application in Compiling and Running Swing Programs section, see HelloWorldSwing.java.
It's not enough to create a frame: you have to register KeyListener on frame or another component. Here's the complete example:
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class PressKey implements KeyListener, Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new PressKey());
}
#Override
public void run() {
JFrame frame = new JFrame("Press a key");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.addKeyListener(this);
frame.setSize(300, 150);
frame.setVisible(true);
}
#Override
public void keyPressed(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
}
#Override
public void keyTyped(KeyEvent e) {
System.out.println("Key pressed: " + e.getKeyChar());
}
}
How does it work? The function main creates an instance of PressKey class and passes it to SwingUtilities.invokeLater utility method. This is required because Swing is not thread-safe and all modifications to GUI components must be performed on the Event Dispatch Thread (EDT). So invokeLater schedules a job onto EDT; as the result PressKey.run() will be run on EDT: it's where we create the frame and register KeyListener attached to the frame, then we show the frame. When the frame is shown on the screen, press any key: you will see the corresponding character printed in the console. If you press a functional key, or another key that does not generate an input character, you won't see anything printed because in this case KeyEvent.KEY_TYPED is not generated.
For more info, see How to Write a Key Listener.
I am assuming you have copied this code out of a tutorial? There are a couple of things missing. As Alexey mentioned, the 'main' method is the entry point for your program, and if you have no code in your main method then your program does nothing. You should be doing something like creating a new thread, frame, window, etc whatever it is that you are wanting your key listeners to attach to.
In the broader context of creating a thread that runs forever, you could do something like
while(true) {
Thread.sleep(100);
}
although you would probably want to change 'true' to 'myflag' which can be set from elsewhere in your code to terminate the thread.
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.