Closing a dialog created by JOptionPane.showOptionDialog() - java

I am creating an options dialog using JOptionPane.showOptionDialog(...);
For the options parameter I am passing an array of JButtons each with its own ActionListener.
One of these buttons is responsible for closing the dialog. My question is: what code do I place in the close button's event handler to close the option dialog?
A point that may make a difference: the class responsible for showing this dialog is a singleton and, as such, the method responsible for displaying the dialog is static. Therefore, calling javax.swing.JInternalFrame.doDefaultCloseAction(); does not work "from a static context".
Thanks

final JButton btn = new JButton("Close");
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
Window w = SwingUtilities.getWindowAncestor(btn);
if (w != null) {
w.setVisible(false);
}
}
});

Try
JOptionPane.getRootFrame().dispose();

JOptionPane is closed by calling its setValue method
(Speaking of dirty side effects)

Related

addActionListener argument is incorrect

In the program I want to use actionListener to monitor a TextFrame. I created a class called monitor and there is a constructor which invoke the whole TextFieldFrame, TFFrame.
class Monitor implements ActionListener{
TFFrame tf = null;
public void Monitor(TFFrame tf){
this.tf = tf;
}
In the TFFrame class, I add a actionListener which invoke itself.
class TFFrame extends Frame{
TextField num1, num2, num3;
public void launchFrame(){
num1 = new TextField(10);
num2 = new TextField(10);
num3 = new TextField(20);
Label plus = new Label("+");
Button equal = new Button("=");
equal.addActionListener(new Monitor(this));
However the compiler fails with an error and the error is that the argument in the Monitor is incorrect. What is the problem?
ActionListener is an interface and has only one required method:
actionPerformed(ActionEvent e)
You don't appear to have actually implemented that method here. Normally it's called under the hood when an appropriate event occurs.
I think you may not be using events and listeners correctly. Logically speaking, given what I understand from your example code, you'd have something like this:
TFFrame tf = new TFFrame();
tf.addActionListener( new Monitor() );
One problem is that the frame has it's own set of events and will not communicate the events from clicking buttons or focusing on textfields up through the frame to the listener. The frame's events are what will end up calling the actionPerformed method that you should have in Monitor.
You could certainly add other stuff to your custom listener, but the listener generally doesn't contain a reference to thing its listening to. Perhaps what you really wanted was just an actionlistener to check when the equals button is pressed, in which case you'd have something like this.
TFFrame tf = new TFFrame();
tf.launchFrame();
Inside of the launchFrame method you would add an action listener to the equals button with some kind of listener for buttons.
equals.addActionListener( new ButtonListener() );
Now for that to work you'd have to create a class called button listener that implements action listener, and then write the appropriate event handling code inside of it's actionPerformed method.
P.S.
To be perfectly honest, much of this inference. If I'm wrong about what you want, then I'd recommend you go and read through this: https://docs.oracle.com/javase/tutorial/uiswing/events/actionlistener.html

Resetting a JDialog after closing

I am using a JDialog to get payment info, paymentAmount and Date is submitted by a JTextfield and a datechooser.beans.DateChooserCombo.
When the user close the JDialog or clicks Cancel, JDialog closes.But when they click the Payment button and JDialog reappears, previously submitted inputs are shown.
I want JDialog to be default state whenever it appears.Is there a default way to do this, or i have to create my own reset method?
When you close a dialog it is not destroyed. It will just become invisible, but it still contains everything as it was when it was closed.
You may override the function setVisible() and reinitialize it if the dialog should be shown again.
#Override
public void setVisible(boolean bVisible)
{
if(bVisible == false)
{
super.setVisible(bVisible);
return;
}
initMyValues();
super.setVisible(bVisible);
return;
}
Alternatively you could create a WindowListener and then you get notified about various state changes of the window. Depends on what suits your needs better. The WindowListener doesn't require you to create a separate class, jsut to override the setVisible(), but you have to add some extra function required by the interface.
Another workaround would be to set a windowListener to your dialog.
myDialog.addWindowListener(new WindowListener() {
/*Implements over methods here*/
#Override
public void windowClosing(WindowEvent e) {
//set default values here
}});

Events and Listeners in Java

This should be a basic Java program for beginners to be found on
"Head First Java 2nd Edition" on the topic of ActionListener interface.
I didn't understand some of the terminologies used in this program such as
button.addActionListener(this);
when this code executes how is the method actionPerformed is triggered or run or
any terminologies you use??
//Program begins from now!!
import javax.swing.*;
import java.awt.event.*;
public class SimpleGui1B implements ActionListener {
JButton button;
public static void main(String[] args) {
SimpleGui1B gui = new SimpleGui1B();
gui.go();
}
public void go(){ //start go
JFrame frame= new JFrame();
button=new JButton("Click me");
frame.getContentPane().add(button);
button.addActionListener(this);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300,300);
frame.setVisible(true);
}//close go()
public void actionPerformed(ActionEvent event){
button.setText("I’ve been clicked!");
}
}
Let's break down this statement shall we:
button.addActionListener(this);
Okay, so you're referencing the button object. This is an object of type JButton I presume. The button object has a method called addActionListener. What this does, is add an object that implements the ActionListener interface.
The class that this occurs in is one of those objects. As you can see at the top it says:
public class SimpleGui1B implements ActionListener
So what the program is doing, is saying that the current class (this) will work as a parameter for your method. Then if you look in this class, you have a method actionPerformed.
public void actionPerformed(ActionEvent event){
button.setText("I’ve been clicked!");
}
This means that whenever the button is clicked, the code inside the actionPerformed method is called. Another alternative is to say:
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
// Add some code here.
}
This is doing the exact same thing, only it's defining the class inside the brackets.
In the JButton class, the keyboard and mouse events are handled, and once the button detects a click, it iterates to its action listeners and calls them:
ActionEvent event = new ActionEvent(...);
for (ActionListener listener : addedListeners) {
listener.actionPerformed(event);
}
Listeners are just callback objects.
Let's walk through the code:
In javax.swing.AbstractButton there is a method called addActionListener where the code is:
public void addActionListener(ActionListener l) {
listenerList.add(ActionListener.class, l);
}
listenerList is defined in javax.swing.JComponent as:
protected EventListenerList listenerList = new EventListenerList();
When an event occurs fireActionPerformed in javax.swing.AbstractButton is called. The code looks like:
protected void fireActionPerformed(ActionEvent event) {
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
ActionEvent e = null;
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners[i]==ActionListener.class) {
// Lazily create the event:
if (e == null) {
String actionCommand = event.getActionCommand();
if(actionCommand == null) {
actionCommand = getActionCommand();
}
e = new ActionEvent(AbstractButton.this,
ActionEvent.ACTION_PERFORMED,
actionCommand,
event.getWhen(),
event.getModifiers());
}
((ActionListener)listeners[i+1]).actionPerformed(e);
}
}
}
The most important part is the last line that says:
((ActionListener)listeners[i+1]).actionPerformed(e);
This is the line of code that calls your actionPerformed() method
That means that the class which is invoking this code is a listener of button changes. So that button will invoke "actionPerformed" on this particular class.
button.addActionListener(this); tells button that this wants to know whenever the button is clicked. From then on, whenever the button is clicked it will go through its list of registered ActionListeners and call the actionPerformed method on each one.
What the code
button.addActionListener(this);
does is add your class (using the keyword this) to be the action listener of the button you created.
What this means, is that the button will call your class whenever an action (such as click) happens. This is why you need the method
public void actionPerformed(ActionEvent event){
button.setText("I’ve been clicked!");
}
Because it will be called by the button
Basically you are going thru observer pattern where observers registers themselves with subject.Now whenever this is some event triggers on subject , subject notifies the different observers. Here Button is subject and SimpleGui1B(basically listener) is observer.Now lets come to your code snippet
button.addActionListener(this);
In above line , button is subject and this is listener/observer. JButton has designed in a way, whenever some event(click in this case) happens on button, observers will be notified thru the method actionPerformed

How to run a method only after a frame has been closed?

So, my code right now looks like this:
Class2 className = new Class2(param1, param2);
className = null;
if (Class2 == null) {
refreshState();
}
I want the refreshState method to run once the className object is destroyed. So basically Class2 is a class that runs another frame on top of my existing frame. I want the method to run only when the new frame has been closed. How can I do this?
So basically Class2 is a class that runs another frame on top of my existing frame. I want the method to run only when the new frame has been closed. How can I do this?
The better solution is to use modal dialogs such as a JOptionPane or a modal JDialog. This will stop the processing of the Swing code in the main window until the dialog window has been dealt with and is no longer visible. Then your refreshState can run immediately after the dialog has been closed:
Pseudocode:
main window code
show modal dialog
refresh state here. This will be called only after the dialog has returned.
I would say add a java.awt.event.WindowListener to the frame:
class2.getFrame().addWindowsListener(new WindowAdapter() {
public void windowClosed(WindowEvent we) {
// The frame is closed, let's dot something else
refreshState();
}
}

How do i find if a window is opened on swing

I have a problem with my application where the user will open more than one window at a time. And i have added dispose() method to call on closing the window. Now i should keep at-least one window open all the time so that the application does not hides without closed fully. If you don't understand read the following scenario:
I have window A and window B opened at the same time. Now i can close either window A or Window B but not both. In other words window B should be allowed to close only if window A is opened and vice versa. How do i do this in swing ??
A simple kind-of windowManger is not really tricky, all you need is
WindowListener which keeps tracks of the Windows it's listening to
a defined place to create the windows and register the the listener
make the windows do-nothing-on-close and make the listener responsible for the decision of whether to close or not (will do so for all except the last)
Some snippet:
// the listener (aka: WindowManager)
WindowListener l = new WindowAdapter() {
List<Window> windows = new ArrayList<Window>();
#Override
public void windowOpened(WindowEvent e) {
windows.add(e.getWindow());
}
#Override
public void windowClosing(WindowEvent e) {
if (windows.size() > 1) {
windows.remove(e.getWindow());
e.getWindow().dispose();
}
}
};
// create the first frame
JFrame frame = createFrame(l);
frame.setVisible(true);
// a method to create a new window, config and add the listener
int counter = 0;
private JFrame createFrame(final WindowListener l) {
Action action = new AbstractAction("open new frame: " + counter) {
#Override
public void actionPerformed(ActionEvent e) {
JFrame frame = createFrame(l);
frame.setVisible(true);
}
};
JFrame frame = new JFrame("someFrame " + counter++);
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.add(new JButton(action));
frame.addWindowListener(l);
frame.pack();
frame.setLocation(counter * 20, counter * 10);
return frame;
}
Just a possible approach...
Create a class, call it WindowManager, that manages creation and disposal of windows.
It could for example retain the count of the windows currently open, and allow a dispose operation only if there are more than one windows "alive", otherwise show a confirm message with JOptionPane telling the user "Really close? That would terminate the application." or something like that.
The "tricky" part is that you have to do this kind of window-related operations throughout the WindowManager, otherwise everything would screw up.
Dunno if Swing has something like this built-in, I've never seen such a scenario.
simply check if the other window is open before closing with window.isVisible();

Categories

Resources