How can I detect the java window closing if it was forced by clicking on windows taskbar -> close window?
I've found that the window to close receives the WINDOW_CLOSING event which is possible to process by adding windowListener. But in this case window would being closed anyway. Is there any way to prevent the window closing?
You can set the default close operation to DO_NOTHING_ON_CLOSE and ask the user for a confirmation instead. It's a pretty common practice even if you want to close the frame through the X button, key combination (i.e.: ALT + F4) or any method to close a window:
JFrame frame = new JFrame("Welcome!");
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
int option = JOptionPane.showConfirmDialog(null, "Do you really want to exit?");
if (option == JOptionPane.OK_OPTION) {
e.getWindow().dispose();
}
}
});
To prevent window closing you should call
setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE)
on your JFrame instance and then implement your alternative closing procedure via windowListener.
I am trying to create a wizard in java swing programatically.
On the wizard pane I have a next button and it has to perform multiple actions according to which panel is displayed on the wizard.
Is it possible to use java command pattern? may I know how?
thanks in advance.
the code i used for the wizard is
this.mainPanel.add(fileSelectionPane,"SELECT FILE");
this.mainPanel.add(sqlConnectionPane,"SQL CONNECTION");
this.mainPanel.add(devicePane,"PARSER");
this.mainPanel.add(detailsPane,"DISPLAY");
thisLayout.show(this.mainPanel,"SELECT FILE");
this.finishButton.setEnabled(false);
this.backButton.setEnabled(false);
if(newValue==1) {
this.thisLayout.show(this.mainPanel, "SQL CONNECTION");
this.nextButton.setEnabled(true);
this.nextButton.setText("Connect..");
this.cancelButton.setEnabled(true);
this.backButton.setEnabled(true);
}
if(newValue==2) {
this.thisLayout.show(this.mainPanel, "PARSER");
this.nextButton.setEnabled(true);
this.nextButton.setText("Parse..");
this.cancelButton.setEnabled(true);
this.backButton.setEnabled(true);
}
i want the next button to perform specific actions on SELECT FILE and SQL CONNECTION.
is it possible to use command patterns?
Ok, so, You add action listeners to buttons. These action listeners do something when an event occurs.
You want to change the functionality of the button depending on which panel is being displayed? Why not set a instance variable which reflects the state of the Wizard?
For example (roughly),
int state = 0; // home panel
change panel to help page, event listener is fire, set 'state' to 1. You are now tracking which panel is being displayed.
Now, in your original problem, when the button (the one you want multiple functionality with) fires, you can choose the action it will take based on the 'state' var.
have look at CardLayout
those cards put to the JDialog (JDialog has preimplemented by default BorderLayout) to the CENTER area
create a new JPanel and place there JButtons
JPanel with JButtons put to the SOUTH area
search here, on this forum, there are a few excelent examples for wizard or image previue based on CardLayout
try the following code for button:
JButton btn1;
btn1= new javax.swing.JButton();
btn1.setToolTipText("Submit");
btn1.setContentAreaFilled(false);
btn1.setBorderPainted(false);
btn1.setMargin(new java.awt.Insets(2, 2, 2, 2));
btn1.addActionListener(this);
btn1.setIcon(this.getIcons()[21]);
add(btn1); // add to Jpanel
btn1.setBounds(250,10, 12, 12);
public void actionPerformed(java.awt.event.ActionEvent evt) {
Object obj = evt.getSource();
if (obj == btn1) {
// your function on on click of button
return;
}
What I am hoping is, when typing in editable JCombobox , the Popup Menu of the JCombobox to appear autumaticaly , i did this and it worked . But, when i changed the Icon of the Arrow Button in the JCombobox it didnt worked any more as shown in the picture
before changing Arrow Button Icon
After changing Arrow Button Icon (the Popup never appears, when one writes in the JCombobox)
this is what i did :
JTextComponent editor;
/** Creates new form combo */
public combo() {
initComponents();
editor = (JTextComponent) jComboBox1.getEditor().getEditorComponent();
jComboBox1.setEditable(true);
editor.addKeyListener(new KeyAdapter() {
#Override
public void keyReleased(KeyEvent e) {
char keyChar = e.getKeyChar();
if (jComboBox1.isDisplayable())
{
jComboBox1.setPopupVisible(true);
}
editor.setCaretPosition(editor.getText().length());
// System.out.println("wwwweeeee"+keyChar);
}
});
jComboBox1.setUI(new SynthComboBoxUI() {
protected JButton createArrowButton() {
JButton btn = new JButton();
btn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Image/error3.png")));
return btn;
}
});
}
Pleeeese help because i'm really tired from searching for a solution
The technical problem here is that the editor is created/maintained by the ui. When setting a custom ui it is replaced by a new editor, so you are listening to a component that is no longer part of the container hierarchy.
After digging a bit ... I still don't have a solution :-( On face value, you'd call setUI before installing the listener on the editor - BUT calling setUI is always wrong ... so simply don't.
Seeing that the ui is synth-based, the correct way to update its visual fore/background properties is to supply custom painters, per-application or per-instance. Nimbus specifically allows to install per-instance custom UIDefaults via the "Nimbus.Overrides" client property. For changing the icon on the arrow button, the appropriate override would be
Painter core = // a custom painter which paints the icon
comboDefaults.put("ComboBox:\"ComboBox.arrowButton\"[Enabled].foregroundPainter", core);
combo.putClientProperty("Nimbus.Overrides.InheritDefaults", false);
combo.putClientProperty("Nimbus.Overrides", comboDefaults);
All fine, except not working - looks like the overrides are not properly installed on the children.
Edit 2
... hours later ...
from all available resources, the above should work, see f.i. Jasper's initial explanation of how-to define custom properties:
ComponentA:ChildComponentB.foreground which lets you specify a ChildComponentB contained within ComponentA.
So I suspect it's really a bug. A not really satisfying hack-around is to install the override on the button itself:
JButton org = null;
for (int i = 0; i < combo.getComponentCount(); i++) {
if (combo.getComponent(i) instanceof JButton) {
org = (JButton) combo.getComponent(i);
UIDefaults buttonDefaults = new UIDefaults();
buttonDefaults.put("ComboBox:\"ComboBox.arrowButton\"[Enabled].foregroundPainter", painter);
org.putClientProperty("Nimbus.Overrides.InheritDefaults", false);
org.putClientProperty("Nimbus.Overrides", buttonDefaults);
break;
}
}
That's not satisfying at all, as the button creation is controlled by the ui delegate, so this config will not survive a switch of LAF. Or the other way round: you'll need a install a PropertyChangeListener with the UIManager and on detecting a switch to Nimbus, manually copy the overrides from the combo to its children.
Is there a way to disable all X on dialog boxes?
I can accomplish this on one by doing:
JOptionPane pane = new JOptionPane("Are you hungry?", JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_OPTION);
JDialog dialog = pane.createDialog("Title");
dialog.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent evt) {
} });
dialog.setContentPane(pane);
dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
dialog.pack();
But the problem is thst I have to apply this to other 20-40 dialog boxes which will be time consuming..
So I was wondering just how you can do one line of code to make the fonts bigger on all the Dialog boxes (shown below), is there a way to for the X disable feature.
UIManager.put("OptionPane.messageFont",
new FontUIResource(new
Font("ARIAL",Font.BOLD,30)));
JDialog method setDefaultCloseOperation works just like JFrame's:
http://download.oracle.com/javase/6/docs/api/javax/swing/JDialog.html#setDefaultCloseOperation(int)
Neither will do this for all frames, it will just do it for the instance it is set on. If you want to apply to all your dialogs you need to do one of the following:
Call this every time you construct a dialog.
Extend JDialog and have it set the default for you, then use that new class.
Create a factory method that will construct a dialog with this default set. Then call this method whenever you need a new dialog.
You need to add a windowListener but also set the default close operation for the dialog.
setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
this.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
if (someConditionIsMet) {
dispose();
}
}
});
Rather than disable a control, you should remove it. Users shouldn't see an "X" button and then have it not behave like they expect.
See:
Dialog.setUndecorated() for a single dialog
JDialog.setDefaultLookAndFeelDecorated() to provide a hint for future dialogs
Why not just create a custom class that extends the JDialog setting your desired close behavior in the constructor?
class NoCLoseDialog extends JDialog {
NoCloseDialog(){
addWindowListener(new WindowAdaptor(){
// ... Close behavior ...
});
}
}
Crtl+F Replace JDialog with NoCloseDialog ...
What's the correct way to get a JFrame to close, the same as if the user had hit the X close button, or pressed Alt+F4 (on Windows)?
I have my default close operation set the way I want, via:
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
It does exactly what I want with the aforementioned controls. This question isn't about that.
What I really want to do is cause the GUI to behave in the same way as a press of X close button would cause it to behave.
Suppose I were to extend WindowAdaptor and then add an instance of my adaptor as a listener via addWindowListener(). I would like to see the same sequence of calls through windowDeactivated(), windowClosing(), and windowClosed() as would occur with the X close button. Not so much tearing up the window as telling it to tear itself up, so to speak.
If you want the GUI to behave as if you clicked the X close button then you need to dispatch a window closing event to the Window. The ExitAction from Closing An Application allows you to add this functionality to a menu item or any component that uses Actions easily.
frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
setVisible(false); //you can't see me!
dispose(); //Destroy the JFrame object
Not too tricky.
If by Alt-F4 or X you mean "Exit the Application Immediately Without Regard for What Other Windows or Threads are Running", then System.exit(...) will do exactly what you want in a very abrupt, brute-force, and possibly problematic fashion.
If by Alt-F4 or X you mean hide the window, then frame.setVisible(false) is how you "close" the window. The window will continue to consume resources/memory but can be made visible again very quickly.
If by Alt-F4 or X you mean hide the window and dispose of any resources it is consuming, then frame.dispose() is how you "close" the window. If the frame was the last visible window and there are no other non-daemon threads running, the program will exit. If you show the window again, it will have to reinitialize all of the native resources again (graphics buffer, window handles, etc).
dispose() might be closest to the behavior that you really want. If your app has multiple windows open, do you want Alt-F4 or X to quit the app or just close the active window?
The Java Swing Tutorial on Window Listeners may help clarify things for you.
Stop the program:
System.exit(0);
Close the window:
frame.dispose();
Hide the window:
frame.setVisible(false);
If you have done this to make sure the user can't close the window:
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
Then you should change your pullThePlug() method to be
public void pullThePlug() {
// this will make sure WindowListener.windowClosing() et al. will be called.
WindowEvent wev = new WindowEvent(this, WindowEvent.WINDOW_CLOSING);
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(wev);
// this will hide and dispose the frame, so that the application quits by
// itself if there is nothing else around.
setVisible(false);
dispose();
// if you have other similar frames around, you should dispose them, too.
// finally, call this to really exit.
// i/o libraries such as WiiRemoteJ need this.
// also, this is what swing does for JFrame.EXIT_ON_CLOSE
System.exit(0);
}
I found this to be the only way that plays nice with the WindowListener and JFrame.DO_NOTHING_ON_CLOSE.
Exiting from Java running process is very easy, basically you need to do just two simple things:
Call java method System.exit(...) at at application's quit point.
For example, if your application is frame based, you can add listener WindowAdapter and and call System.exit(...) inside its method windowClosing(WindowEvent e).
Note: you must call System.exit(...) otherwise your program is error involved.
Avoiding unexpected java exceptions to make sure the exit method can be called always.
If you add System.exit(...) at right point, but It does not mean that the method can be called always, because unexpected java exceptions may prevent the method from been called.
This is strongly related to your programming skills.
** Following is a simplest sample (JFrame based) which shows you how to call exit method
import java.awt.event.*;
import javax.swing.*;
public class ExitApp extends JFrame
{
public ExitApp()
{
addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
dispose();
System.exit(0); //calling the method is a must
}
});
}
public static void main(String[] args)
{
ExitApp app=new ExitApp();
app.setBounds(133,100,532,400);
app.setVisible(true);
}
}
Not only to close the JFrame but also to trigger WindowListener events, try this:
myFrame.dispatchEvent(new WindowEvent(myFrame, WindowEvent.WINDOW_CLOSING));
Best way to close a Swing frame programmatically is to make it behave like it would when the "X" button is pressed. To do that you will need to implement WindowAdapter that suits your needs and set frame's default close operation to do nothing (DO_NOTHING_ON_CLOSE).
Initialize your frame like this:
private WindowAdapter windowAdapter = null;
private void initFrame() {
this.windowAdapter = new WindowAdapter() {
// WINDOW_CLOSING event handler
#Override
public void windowClosing(WindowEvent e) {
super.windowClosing(e);
// You can still stop closing if you want to
int res = JOptionPane.showConfirmDialog(ClosableFrame.this, "Are you sure you want to close?", "Close?", JOptionPane.YES_NO_OPTION);
if ( res == 0 ) {
// dispose method issues the WINDOW_CLOSED event
ClosableFrame.this.dispose();
}
}
// WINDOW_CLOSED event handler
#Override
public void windowClosed(WindowEvent e) {
super.windowClosed(e);
// Close application if you want to with System.exit(0)
// but don't forget to dispose of all resources
// like child frames, threads, ...
// System.exit(0);
}
};
// when you press "X" the WINDOW_CLOSING event is called but that is it
// nothing else happens
this.setDefaultCloseOperation(ClosableFrame.DO_NOTHING_ON_CLOSE);
// don't forget this
this.addWindowListener(this.windowAdapter);
}
You can close the frame programmatically by sending it the WINDOW_CLOSING event, like this:
WindowEvent closingEvent = new WindowEvent(targetFrame, WindowEvent.WINDOW_CLOSING);
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(closingEvent);
This will close the frame like the "X" button was pressed.
If you really do not want your application to terminate when a JFrame is closed then,
use : setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
instead of : setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Here's a synopsis of what the solution looks like,
myFrame.dispatchEvent(new WindowEvent(myFrame, WindowEvent.WINDOW_CLOSING));
This examples shows how to realize the confirmed window close operation.
The window has a Window adapter which switches the default close operation to EXIT_ON_CLOSEor DO_NOTHING_ON_CLOSE dependent on your answer in the OptionDialog.
The method closeWindow of the ConfirmedCloseWindow fires a close window event and can be used anywhere i.e. as an action of an menu item
public class WindowConfirmedCloseAdapter extends WindowAdapter {
public void windowClosing(WindowEvent e) {
Object options[] = {"Yes", "No"};
int close = JOptionPane.showOptionDialog(e.getComponent(),
"Really want to close this application?\n", "Attention",
JOptionPane.YES_NO_OPTION,
JOptionPane.INFORMATION_MESSAGE,
null,
options,
null);
if(close == JOptionPane.YES_OPTION) {
((JFrame)e.getSource()).setDefaultCloseOperation(
JFrame.EXIT_ON_CLOSE);
} else {
((JFrame)e.getSource()).setDefaultCloseOperation(
JFrame.DO_NOTHING_ON_CLOSE);
}
}
}
public class ConfirmedCloseWindow extends JFrame {
public ConfirmedCloseWindow() {
addWindowListener(new WindowConfirmedCloseAdapter());
}
private void closeWindow() {
processWindowEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSING));
}
}
Based on the answers already provided here, this is the way I implemented it:
JFrame frame= new JFrame()
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// frame stuffs here ...
frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
The JFrame gets the event to close and upon closing, exits.
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. When this is done you may handle the resulting event sequence exactly as you would if the user has clicked on the [x] button for an OS suppled decorated JFrame.
public void closeWindow()
{
if(awtWindow_ != null) {
EventQueue.invokeLater(new Runnable() {
public void run() {
awtWindow_.dispatchEvent(new WindowEvent(awtWindow_, WindowEvent.WINDOW_CLOSING));
}
});
}
}
I have tried this, write your own code for formWindowClosing() event.
private void formWindowClosing(java.awt.event.WindowEvent evt) {
int selectedOption = JOptionPane.showConfirmDialog(null,
"Do you want to exit?",
"FrameToClose",
JOptionPane.YES_NO_OPTION);
if (selectedOption == JOptionPane.YES_OPTION) {
setVisible(false);
dispose();
} else {
setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
}
}
This asks user whether he want to exit the Frame or Application.
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
Posting what was in the question body as CW answer.
Wanted to share the results, mainly derived from following camickr's link. Basically I need to throw a WindowEvent.WINDOW_CLOSING at the application's event queue. Here's a synopsis of what the solution looks like
// closing down the window makes sense as a method, so here are
// the salient parts of what happens with the JFrame extending class ..
public class FooWindow extends JFrame {
public FooWindow() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(5, 5, 400, 300); // yeah yeah, this is an example ;P
setVisible(true);
}
public void pullThePlug() {
WindowEvent wev = new WindowEvent(this, WindowEvent.WINDOW_CLOSING);
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(wev);
}
}
// Here's how that would be employed from elsewhere -
// someplace the window gets created ..
FooWindow fooey = new FooWindow();
...
// and someplace else, you can close it thusly
fooey.pullThePlug();
If you do not want your application to terminate when a JFrame is closed,
use:
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE)
instead of:
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
From the documentation:
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): Exit the application using the System exit method. Use this only in applications.
might still be useful:
You can use setVisible(false) on your JFrame if you want to display the same frame again.
Otherwise call dispose() to remove all of the native screen resources.
copied from Peter Lang
https://stackoverflow.com/a/1944474/3782247