Below is 2 simple java ui application, I found if the current IME is google pinyin When I click the right-upper close button of this Frame in Windows 7 and Windows XP OS, the frame can be closed but the EDT thread doesn't terminate.
the google pinyin IME download address is http://dl.google.com/pinyin/v2/GooglePinyinInstaller.exe.
And recently I found this situation also occurs when using Baidu Pinyin IME(another chinese input method). Diffrently, it occurs only when using swing, randomly(the EDT thread can't terminate for a period of time, and become normal later).
I've read a article blaming the same problem similar to me long ago, and the author didn't come out with a solution too. I thought this is a bug in Google IME.
I know most people view this question may not be Chinese and may be unable to install these 2 IME and try my samples, but it's just too ridiculous for me, how can these two things have relations??? do anybody have some idea to explain it based on your knowledge? I'll appreciate very much!
// AWT
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
final Frame frame = new Frame("test");
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
frame.dispose();
}
});
frame.setSize(400, 400);
frame.setVisible(true);
}
});
Below is Swing
// Swing
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame("swing");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setSize(400, 400);
frame.setVisible(true);
}
});
As #MadProgrammer mentioned. I changed my code, using System.exit(0) in AWT and frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) in swing, the result is I can't close the frame, when I click the close button, nothing happens.
You should try using an exit listener, for example:
this.addWindowListener(new MyExitListener());
And the exit listener class:
public class MyExitListener extends WindowAdapter {
#Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
This is what I usually do, and it always works.
Related
I have a JFrame which needs to be always on top of the other application. For this I am using setAlwaysOnTop() method of Window class.
Here is my code :
class Test1 extends JFrame {
public Test1() {
initComponents();
setTitle("Top Window");
setAlwaysOnTop(true);
}
private void initComponents() {
jLabel1 = new JLabel();
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
jLabel1.setHorizontalAlignment(SwingConstants.CENTER);
jLabel1.setText("I am a top most window");
getContentPane().add(jLabel1, BorderLayout.CENTER);
pack();
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new Test1().setVisible(true);
}
});
}
private javax.swing.JLabel jLabel1;
}
This works fine with some of the other application such as notepad, explorer etc, i.e. when my application is above notepad everything works fine.
But when my java application goes above any application that is already on top such as task manager. Then the method setAlwaysOnTop() doesn't works.
What I need is any way through which I can make my application always on top.
I have also searched many other related posts on stackoverflow but none seems to answer my question. I have also tried other ways such as overriding the windowDeactivated(WindowEvent e) method
addWindowListener(new WindowAdapter(){
#Override
public void windowDeactivated(WindowEvent e) {
toFront();
//requestFocus();
//requestFocusInWindow();
}
});
but this also doesn't worked.
Is there any other way through which I can may my JFrame always on top of every other application except in case of full screen applications.
It depends on the operating system. In general, you can't guarantee that your window will always be on top when it comes to native windows, nor should you. The task manager is always-on-top for good reasons.
I remember that some versions of Vista and older Windows systems allowed that and the native and Java windows ended up fighting for focus.
I need to perform an action after the JFrame is closed and I have this part of code for it, but this doesn't work.
Could anyone please advise what should be change here?
private void changeDefaults(){
Thread changeDefaultsThread = new Thread(new Runnable(){
public void run(){
Change ch = new Change();
ch.setVisible(true);
ch.setListeners();
ch.defaultInput();
while(ch.isActive()){
System.out.println("active");
}
updateDefaults();
}
});
changeDefaultsThread.start();
}
Change is the JFrame I am opening for another action.
You can add listener to your JFrame
frame.addWindowListener (new java.awt.event.WindowAdapter)
and override the windowClosing
#Override
public void windowClosing
frame.addWindowListener(new java.awt.event.WindowAdapter() {
#Override
public void windowClosing(java.awt.event.WindowEvent windowEvent) {
//do something
}
});
I'm surprised no one has mentioned the simplest solution: don't use a JFrame. The best tool for this behavior -- displaying a child window and doing something immediately after it has closed -- is to use a modal dialog window such as a JDialog or JOptionPane. The JDialog set up code is very similar to that of the JFrame, with an exception being that it uses different constructors, and should have the parent window passed into it, and it uses a subset of the default close operations.
If you use a modal dialog, then program flow is halted in the calling code immediately after the dialog has been displayed (think of how a JOptionPane operates), and then immediately resumes from the spot after calling setVisible(true) on the dialog once the dialog has been closed.
The only bugaboo is that if you don't want modal behavior -- if you don't want the parent/calling window to be disabled while the child window is displayed -- then you'll have to use a non-modal JDialog window with a WindowListener.
If you want to perform an action when closing a JFrame, you just need to attach a WindowListener (extending WindowAdapter so that you do not need to implement all WindowListener methods):
import javax.swing.*;
public class AfterJFrameClose {
public static void main(String[] args) {
JFrame frame = new JFrame("My frame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setAlwaysOnTop(true);
frame.addWindowListener(new java.awt.event.WindowAdapter() {
#Override
public void windowClosing(java.awt.event.WindowEvent windowEvent) {
System.out.println("Frame closing");
}
});
}
}
Instead of the System.out.println, just write the code you want to have executed.
Update: If you want to access another frame, you either should pass it as a parameter as suggested above or you can also iterate through active frames using something like this:
Frame[] frames = Frame.getFrames();
for (Frame frame: frames) {
System.out.println(frame.getTitle());
}
I am seeing the following code in a Swing demo application:
WindowListener wndCloser = new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
};
addWindowListener(wndCloser);
Why would you use this code to close the application? What would happen without it, and/or are there other (shorter) options to do this?
Why would you use this code to close the application?
As TimH said, you can log information, write out properties, or do any other clean up you want to do before exiting your Swing application.
Here's how the window closing code is normally used.
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
WindowListener wndCloser = new WindowAdapter() {
public void windowClosing(WindowEvent e) {
exitProcedure();
}
};
frame.addWindowListener(wndCloser);
public void exitProcedure() {
frame.dispose();
System.exit(0);
}
Because exitProcedure is a separate method, you can execute it from a JMenuItem action listener, like "Exit".
What would happen without it, and/or are there other (shorter) options to do this?
A shorter option is
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
If you don't specify any default close operation, your Swing application continues to run after you close the JFrame. You wind up with dozens of running applications, doing nothing.
You can use it to log some infos like this:
frame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
log.info("Programm exit.");
System.exit(0);
super.windowClosed(e);
}
});
A shorter version would be:
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
I don't get how can I employ this code:
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
to close the program with the x button.
You need the line
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
Because the default behaviour for the JFrame when you press the X button is the equivalent to
frame.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
So almost all the times you'll need to add that line manually when creating your JFrame
I am currently referring to constants in WindowConstants like WindowConstants.EXIT_ON_CLOSE instead of the same constants declared directly in JFrame as the prior reflect better the intent.
If you don't have it, the JFrame will just be disposed. The frame will close, but the app will continue to run.
Calling setDefaultCloseOperation(EXIT_ON_CLOSE) does exactly this. It causes the application to exit when the application receives a close window event from the operating system. Pressing the close (X) button on your window causes the operating system to generate a close window event and send it to your Java application. The close window event is processed by the AWT event loop in your Java application which will exit the application in response to the event.
If you do not call this method the AWT event loop may not exit the application in response to the close window event but leave it running in the background.
I spent quite a bit of time spelunking through the internet for an elegant solution to this. As is usually the case, I found a lot of conflicting information.
I finally ended with:
Do not use EXIT_ON_CLOSE as this can leave resources behind;
Do use something like the following in the JFrame initialization:
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
The real discovery was how to actually dispatch a window message to the JFrame. As an example, as part of your JMenuItem for exiting the application, use the following, where the function getFrame() returns a reference to the JFrame:
public class AppMenuFileExit extends JMenuItem implements ActionListener
{
// do your normal menu item code here
#Override
public void actionPerformed(ActionEvent e)
{
WindowEvent we;
we = new WindowEvent((Window) App.getFrame(), WindowEvent.WINDOW_CLOSING);
App.getFrame().dispatchEvent(we);
}
}
JFrame is a subclass of Window so may be cast to Window for this purpose.
And, have the following in your JFrame class to handle Window messages:
public class AppFrame extends JFrame implements WindowListener
{
// Do all the things you need to for the class
#Override
public void windowOpened(WindowEvent e)
{}
#Override
public void windowClosing(WindowEvent e)
{/* can do cleanup here if necessary */}
#Override
public void windowClosed(WindowEvent e)
{
dispose();
System.exit(0);
}
#Override
public void windowActivated(WindowEvent e)
{}
#Override
public void windowDeactivated(WindowEvent e)
{}
#Override
public void windowDeiconified(WindowEvent e)
{}
#Override
public void windowIconified(WindowEvent e)
{}
}
If you're using a Frame (Class Extends Frame) you'll not get the
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE)
If you don't extend JFrame and use JFrame itself in variable, you can use:
frame.dispose();
System.exit(0);
The following code works for me:
System.exit(home.EXIT_ON_CLOSE);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
this worked for me in case of Class Extends Frame
What code is called when a JFrame is minimized? Is it hooked up to a listener? I just want to know what happens internally when the frame is minimized.
EDIT:
Im actually looking for the code that is called when the frame is minimized. For example, the code for the actual windowListener. Ive been searching through JFrame, Frame, and Window searching for windowIconified but have been unable to find the actual code.
Reason being, when my program runs, it has a small defect with one of the Panels, but when I minimize and maximize the JFrame, the problem goes away. I wanted to see what was going on so that I can apply whatever is going on to my Panel so it paints right.
you can listening by using WindowListener
for example
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import javax.swing.JFrame;
public class WinStateListener implements WindowListener {
static JFrame window = new JFrame("Window State Listener");
public WinStateListener() {
window.setBounds(30, 30, 300, 300);
window.addWindowListener(this);
window.setVisible(true);
}
public static void main(String[] args) {
WinStateListener winStateListener = new WinStateListener();
}
public void windowClosing(WindowEvent e) {
System.out.println("Closing");
window.dispose();
System.exit(0);
}
public void windowOpened(WindowEvent e) {
System.out.println("Opened");
}
public void windowClosed(WindowEvent e) {
System.out.println("Closed");
}
public void windowIconified(WindowEvent e) {
System.out.println("Iconified");
}
public void windowDeiconified(WindowEvent e) {
System.out.println("Deiconified");
}
public void windowActivated(WindowEvent e) {
System.out.println("Activated");
}
public void windowDeactivated(WindowEvent e) {
System.out.println("Deactivated");
}
}
You want to read about WindowListeners and WindowEvents. The event you are talking about is called Iconifying the window. Read more here:
http://download.oracle.com/javase/tutorial/uiswing/events/windowlistener.html
EDIT:
Use revalidate() then repaint() on the JPanel that is acting up.
When minimizing the JFrame application a window event windowIconified is called. If you want to process such window events by your own then either implement WindowListener interface or use WindowAdapter abstract class.
What code is called when a JFrame is minimized?
As noted in How to Make Frames: Specifying Window Decorations, "window decorations are supplied by the native window system." The article goes on to describe some changes you can make to the host platform's default.
Addendum: Reading your update, note that restoring an iconified window repaints it. As #Andrew Thompson points out, you may need to verify that you're building on the event dispatch thread. You may also need to schedule a repaint(). An sscce might clarify things.