i have a situation where i show a dialog where user has to fill some menus and then press OK. It works fine, but now i have another button on this dialog that if user wants to add some certain value, i want another dialog to popup where user fills the additional value and while pressing ok, this dialog disappears and user comes back to the main dialog.
I have tried this, but every time i call the new dialog, the focus does not go away from the main dialog, how can i do such a task.
Is there any relevant example or what is the proper way of doing such things.
EDIT:
public static class EdgeMenu extends JPopupMenu {
// private JFrame frame;
public MyMenu(final JFrame frame) {
super("My Menu");
// this.frame = frame;
this.addSeparator();
this.add(new EdgePropItem(frame));
}
}
//this shows the first dialog, another class because i have some other
//functions to be performed here
public static class EdgePropItem extends JMenuItem{
//...
public EdgePropItem(final JFrame frame) {
super("Edit Properties");
this.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
EdgePropertyDialog dialog = new EdgePropertyDialog(frame, edge);
dialog.setVisible(true);
}
});
}
}
and now in other dialog, in the button even listener i am trying to call another dialog:
private void newDialogHandler(java.awt.event.ActionEvent evt) {
MyNewDialog rdialog = new MyNewDialog(edge);
rdialog.setVisible(true);
}
It appears fine, but the previous dialog, does not leave the focus, and it goes away only if i press finish/done on that dialog, what i want is the new dialog to come in focus, while pressing ok on here, focus should come back to the old main dialog, but it is not working?
maybe this code could be demonstate your issues,
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SuperConstructor extends JFrame {
private static final long serialVersionUID = 1L;
public SuperConstructor() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setPreferredSize(new Dimension(300, 300));
setTitle("Super constructor");
Container cp = getContentPane();
JButton b = new JButton("Show dialog");
b.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
FirstDialog firstDialog = new FirstDialog(SuperConstructor.this);
}
});
cp.add(b, BorderLayout.SOUTH);
JButton bClose = new JButton("Close");
bClose.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
System.exit(0);
}
});
add(bClose, BorderLayout.NORTH);
pack();
setVisible(true);
}
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
SuperConstructor superConstructor = new SuperConstructor();
}
});
}
private class FirstDialog extends JDialog {
private static final long serialVersionUID = 1L;
FirstDialog(final Frame parent) {
super(parent, "FirstDialog");
setPreferredSize(new Dimension(200, 200));
setLocationRelativeTo(parent);
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
setModalityType(Dialog.ModalityType.DOCUMENT_MODAL);
JButton bNext = new JButton("Show next dialog");
bNext.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
SecondDialog secondDialog = new SecondDialog(parent, false);
}
});
add(bNext, BorderLayout.NORTH);
JButton bClose = new JButton("Close");
bClose.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
setVisible(false);
}
});
add(bClose, BorderLayout.SOUTH);
pack();
setVisible(true);
}
}
private int i;
private class SecondDialog extends JDialog {
private static final long serialVersionUID = 1L;
SecondDialog(final Frame parent, boolean modal) {
//super(parent); // < --- Makes this dialog
//unfocusable as long as FirstDialog is visible
setPreferredSize(new Dimension(200, 200));
setLocation(300, 50);
setModal(modal);
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
setTitle("SecondDialog " + (i++));
JButton bClose = new JButton("Close");
bClose.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
setVisible(false);
}
});
add(bClose, BorderLayout.SOUTH);
pack();
setVisible(true);
}
}
}
You can achieve this as follows:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JOptionPane;
public class MultipleDialogs
{
public MultipleDialogs()
{
JButton btnOpen = new JButton("Open another dialog!");
btnOpen.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
JOptionPane.showMessageDialog(null, "This is the second dialog!");
}
});
Object[] options = {"OK", "Cancel", btnOpen};
int selectedOption = JOptionPane.showOptionDialog(null,
"This is the first dialog!", "The title",
JOptionPane.NO_OPTION, JOptionPane.PLAIN_MESSAGE,
null, options, options[0]);
if(selectedOption == 0) // Clicking "OK"
{
}
else if(selectedOption == 1) // Clicking "Cancel"
{
}
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
new MultipleDialogs();
});
}
}
}
You can replace "This is the first dialog!" and "This is the second dialog!" with JPanel's which can contain any swing components you want.
Create the second dialog from a constructor that takes dialog and boolean as parameters and that solves the problem.
Related
I am making a game where the user has to press keys to move around. I am using keybindings but they are not working. The keybindings are supposed to call the Wp class and print "W pressed", but nothing happens. Here's the code:
public class SO extends JFrame {
public static void main(String[] args) {
new SO();
}
C c;
public SO(){
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(500, 500);
c=new C();
c.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("W"), "wp");
c.getActionMap().put("wp", new Wp());
this.setVisible(true);
}
private class C extends JComponent {
public void paint(Graphics g){}
}
private class Wp extends AbstractAction {
#Override
public void actionPerformed(ActionEvent arg0) {
System.out.println("W pressed");
}
}
}
Use Action to call like component.getActionMap().put("doSomething", anAction);
Refer Key Binding for more information. Below is a sample code I have referred in another Stackoverflow Question reference link SO Ref link
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ButtonBinding {
private JPanel contentPane;
private JTextField tField;
private JButton button;
private KeyStroke keyStroke = KeyStroke.getKeyStroke("ENTER");
private Action action = new AbstractAction() {
#Override
public void actionPerformed(ActionEvent ae) {
System.out.println("Action Performed");
contentPane.setBackground(Color.BLUE);
}
};
private MouseAdapter mouseActions = new MouseAdapter() {
#Override
public void mouseEntered(MouseEvent me) {
System.out.println("Mouse Entered");
JButton button = (JButton) me.getSource();
button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(keyStroke, "enter");
button.getActionMap().put("enter", action);
}
#Override
public void mouseExited(MouseEvent me) {
System.out.println("Mouse Exited");
JButton button = (JButton) me.getSource();
button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(keyStroke, "none");
contentPane.setBackground(Color.RED);
}
};
private void displayGUI() {
JFrame frame = new JFrame("Button Binding Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
contentPane = new JPanel();
contentPane.setOpaque(true);
tField = new JTextField(10);
button = new JButton("Click Me");
button.addMouseListener(mouseActions);
contentPane.add(tField);
contentPane.add(button);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
Runnable runnable = new Runnable() {
#Override
public void run() {
new ButtonBinding().displayGUI();
}
};
EventQueue.invokeLater(runnable);
}
}
I made this sample:
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
public class JDialogTest extends JDialog implements ActionListener{
private boolean actionPerformed;
private JButton okButton;
private JTextField textField;
private JDialogTest(String title, JFrame frame){
super(frame, title, true);
setDefaultCloseOperation(HIDE_ON_CLOSE);
setMinimumSize(new Dimension(200, 200));
init();
}
public static String getInput(String title, JFrame frame){
JDialogTest input = new JDialogTest(title, frame);
input.setVisible(true);
while(true){
if(input.actionPerformed){
input.setVisible(false);
String text = input.textField.getText();
return text;
}
}
}
private void init(){
textField = new JTextField();
okButton = new JButton("OK");
okButton.addActionListener(this);
setLayout(new GridLayout(2, 1, 5, 5));
add(textField);
add(okButton);
pack();
}
#Override
public void actionPerformed(ActionEvent evt) {
System.out.println("click");
actionPerformed = true;
}
public static void main(String[] args) {
System.out.println(JDialogTest.getInput("Test", null));
}
}
I create new Dialog via a static method witch returns a string.
But the while-loop witch should detect if the button was pressed won't get started!
I know about JOptionPanes but I don't want to use them. I tried using a JFrame instead but it doesn't work if I try to init the Dialog inside of another JFrame/JDialog (it doesn't render).
With while(true) running in the same thread as the gui, is gonna to freeze your view, and is not the proper way you are using listeners. As your dialog is modal then the dialog has the flowcontrol.
Look at this SSCCE based in your example , with a few changes.
Example:
public class JDialogTest {
private JDialog dialog;
private JTextField textField;
private JDialogTest (String title, JFrame frame){
dialog = new JDialog(frame, title, true);
dialog.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
dialog.setMinimumSize(new Dimension(200, 200));
init();
}
public void setVisible(Boolean flag){
dialog.setVisible(flag);
}
public static String getInput(String title, JFrame frame){
JDialogTest input = new JDialogTest (title, frame);
input.setVisible(true);
String text = input.textField.getText();
return text;
}
private void init(){
textField = new JTextField();
JButton okButton = new JButton("OK");
okButton.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
dialog.dispose();
}
});
dialog.setLayout(new GridLayout(2, 1, 5, 5));
dialog.add(textField);
dialog.add(okButton);
dialog.pack();
}
public static void main(String args []){
String s = getInput("Dialog",null);
System.out.println(s);
}
}
Here is one possible solution. Take special note of the changes to the JDialogTest constructor, getInput() and actionPerformed().
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class JDialogTest extends JDialog implements ActionListener{
private JButton okButton;
private JTextField textField;
private JDialogTest(String title, JFrame frame){
super(frame, title, true);
this.setModal(true); // Set the dialog as modal
setDefaultCloseOperation(HIDE_ON_CLOSE);
setMinimumSize(new Dimension(200, 200));
init();
}
public static String getInput(String title, JFrame frame){
JDialogTest input = new JDialogTest(title, frame);
input.setVisible(true);
return input.textField.getText(); // If this is executed, the dialog box has closed
}
private void init(){
textField = new JTextField();
okButton = new JButton("OK");
okButton.addActionListener(this);
setLayout(new GridLayout(2, 1, 5, 5));
add(textField);
add(okButton);
pack();
}
#Override
public void actionPerformed(ActionEvent evt) {
System.out.println("click");
setVisible(false); // Close the modal dialog box
}
public static void main(String[] args) {
System.out.println(JDialogTest.getInput("Test", null));
}
}
Again you wan to use a a modal JDialog and then query it for the text it holds once it has been dealt with. Since the dialog is modal, your calling application will know when the button has been pressed, if you make the dialog invisible within the button's ActionListener. This will then return control to the calling program. Your calling program can then query the dialog by calling a public method that you give it (here I called it getText() then then returns the String held by the dialog's JTextField.
For example, using your code...
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class JDialogTest extends JDialog implements ActionListener {
// private boolean actionPerformed;
private JButton okButton;
private JTextField textField;
private JDialogTest(String title, JFrame frame) {
super(frame, title, true);
setDefaultCloseOperation(HIDE_ON_CLOSE);
setMinimumSize(new Dimension(200, 200));
init();
}
// public static String getInput(String title, JFrame frame) {
// JDialogTest input = new JDialogTest(title, frame);
// input.setVisible(true);
//
// while (true) {
// if (input.actionPerformed) {
// input.setVisible(false);
// String text = input.textField.getText();
// return text;
// }
// }
// }
private void init() {
textField = new JTextField();
okButton = new JButton("OK");
okButton.addActionListener(this);
// UGLY layout
setLayout(new GridLayout(2, 1, 5, 5));
add(textField);
add(okButton);
pack();
}
// I've added this method to allow outside methods to get text
public String getText() {
return textField.getText();
}
#Override
public void actionPerformed(ActionEvent evt) {
System.out.println("click");
// actionPerformed = true;
setVisible(false);
}
private static void createAndShowGui() {
final JTextField textField = new JTextField(20);
JFrame frame = new JFrame("Test JFrame");
final JDialogTest jDialogTest = new JDialogTest("Dialog", frame);
JButton button = new JButton(
new AbstractAction("Press Me to Show Dialog") {
#Override
public void actionPerformed(ActionEvent arg0) {
jDialogTest.setVisible(true); // code is frozen here
// until the dialog is no longer visible
// when code flow reaches here, we know that the dialog
// is no longer visible and
// we now can query our JDialog to get its text
textField.setText(jDialogTest.getText());
}
});
textField.setFocusable(false);
JPanel panel = new JPanel();
panel.add(button);
panel.add(textField);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(panel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Edit
If you want to display the dialog in a static way, change your getInput method to simply:
public static String getInput(String title, JFrame frame) {
JDialogTest input = new JDialogTest(title, frame);
input.setVisible(true);
return input.getText();
}
Changes to calling code:
final JTextField textField = new JTextField(20);
final JFrame frame = new JFrame("Test JFrame");
JButton button = new JButton(
new AbstractAction("Press Me to Show Dialog") {
#Override
public void actionPerformed(ActionEvent arg0) {
String result = JDialogTest.getInput("Get Input", frame);
textField.setText(result);
}
});
Edit 2
Note that JOptionPane works great:
String result = JOptionPane.showInputDialog(frame, "Please enter input:",
"Get Input", JOptionPane.PLAIN_MESSAGE);
Edit 3
You ask:
The solution in the edit seems to work but what method should I use in the action listener to close the JDialog and return the text?
The dialog button's ActionListener will make the dialog invisible by either calling setVisible(false) or dispose(). See my code above or nachokk's code for examples.
When I pressed the ENTER my JTextArea starts a new row and I only want do to the doClick() method nothing else.
How should I do that?
textarea.addKeyListener(new KeyListener(){
#Override
public void keyPressed(KeyEvent e){
if(e.getKeyCode() == KeyEvent.VK_ENTER){
button.doClick();
}
}
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
}
});
Use .consume():
Consumes this event so that it will not be processed in the default
manner by the source which originated it.
public void keyPressed(KeyEvent e){
if(e.getKeyCode() == KeyEvent.VK_ENTER){
e.consume();
button.doClick();
}
}
Documentation
You should use KeyBindings with any JTextComponent in question. KeyListeners are way too low level from Swing's perspective. You are using the concept which was related to AWT, Swing uses KeyBindings to do the same task with more efficiency and provides desired results :-)
A small program for your help :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class KeyBindingExample {
private static final String key = "ENTER";
private KeyStroke keyStroke;
private JButton button;
private JTextArea textArea;
private Action wrapper = new AbstractAction() {
#Override
public void actionPerformed(ActionEvent ae) {
button.doClick();
}
};
private void displayGUI() {
JFrame frame = new JFrame("Key Binding Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel contentPane = new JPanel(new BorderLayout(5, 5));
textArea = new JTextArea(10, 10);
keyStroke = KeyStroke.getKeyStroke(key);
Object actionKey = textArea.getInputMap(
JComponent.WHEN_FOCUSED).get(keyStroke);
textArea.getActionMap().put(actionKey, wrapper);
button = new JButton("Click Me!");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
System.out.format("Button Clicked :-)%n");
}
});
contentPane.add(textArea, BorderLayout.CENTER);
contentPane.add(button, BorderLayout.PAGE_END);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
new KeyBindingExample().displayGUI();
}
};
EventQueue.invokeLater(r);
}
}
Lets say, we have a few JFrame windows visible in same time and for each window JDialog appears. When our windows in cascading mode and for dialogs setAlwaysOnTop is true then all dialogs will be visible over last window.
I just want to associate a Dialog component with its owner, so that when you'll be switching between Frames you'll get only one dialog on top and won't lose this dialog when click on a frame.
Dialogs have constructor like this:
setAlwaysOnTop(true);
setModal(false);
Thanks in advance!
How to make JDialog onTop only for his parent?
setParent in the constructor properly
have to use setModalityType f.e. ModalityType.DOCUMENT_MODAL ModalityType.APPLICATION_MODAL instead of setModal
setModal is valid to the container which intialized / is parent for this JDialog
don't to use more than one JFrame, use JDialog instead, reuse this container for another action
for example
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SuperConstructor extends JFrame {
private static final long serialVersionUID = 1L;
public SuperConstructor() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setPreferredSize(new Dimension(300, 300));
setTitle("Super constructor");
Container cp = getContentPane();
JButton b = new JButton("Show dialog");
b.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
FirstDialog firstDialog = new FirstDialog(SuperConstructor.this);
}
});
cp.add(b, BorderLayout.SOUTH);
JButton bClose = new JButton("Close");
bClose.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
System.exit(0);
}
});
add(bClose, BorderLayout.NORTH);
pack();
setVisible(true);
}
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
SuperConstructor superConstructor = new SuperConstructor();
}
});
}
private class FirstDialog extends JDialog {
private static final long serialVersionUID = 1L;
FirstDialog(final Frame parent) {
super(parent, "FirstDialog");
setPreferredSize(new Dimension(200, 200));
setLocationRelativeTo(parent);
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
JButton bNext = new JButton("Show next dialog");
bNext.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
SecondDialog secondDialog = new SecondDialog(parent, false);
}
});
add(bNext, BorderLayout.NORTH);
JButton bClose = new JButton("Close");
bClose.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
setVisible(false);
}
});
add(bClose, BorderLayout.SOUTH);
pack();
setVisible(true);
}
}
private int i;
private class SecondDialog extends JDialog {
private static final long serialVersionUID = 1L;
SecondDialog(final Frame parent, boolean modal) {
//super(parent); // Makes this dialog unfocusable as long as FirstDialog is visible
setPreferredSize(new Dimension(200, 200));
setLocation(300, 50);
setModal(modal);
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
setTitle("SecondDialog " + (i++));
setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
JButton bClose = new JButton("Close");
bClose.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
setVisible(false);
}
});
add(bClose, BorderLayout.SOUTH);
pack();
setVisible(true);
}
}
}
In the API one of JDialog constructor is JDialog(Dialog owner, boolean modal) which means that you can create a dialog and specify the parent container as well as the modality. In the modal section, setting it to true means that this dialog will be modal and you cannot access the parent window while the dialog is in display.
But again, you can use the setModal() method to accomplish the same.
just set the Model true and Just set Relativelocation(parent); and dont use setontop(true) for the JDialog.
and then if u back open that time u will get dialog ontop every time. but that will be differ when u Drag the Parent Frame.
I managed to solve this problem building a focus listener that does this job. You can then set this listener to the window you want the dialog stays always visible until is closed. Here is what worked for me:
public class WindowFocusListenerDialogFocus implements WindowFocusListener {
private JFrame _dialogFrame;
public WindowFocusListenerDialogFocus(JFrame dialogFrame) {
_dialogFrame = dialogFrame;
}
#Override
public void windowLostFocus(WindowEvent e) {
System.out.println("Focus lost!");
}
#Override
public void windowGainedFocus(WindowEvent e) {
System.out.println("Focus gained!");
_dialogFrame.toFront();
}
}
i'm developing a JFrame which has a button to show another JFrame. On the second JFrame i want to override WindowsClosing event to hide this frame but not close all the application. So i do like this:
On second JFrame
addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent evt) {
formWindowClosing(evt);
}
});
private void formWindowClosing(java.awt.event.WindowEvent evt) {
this.dispose();
}
but application still close when i click x button on the windows. why? can you help me?
I can't use
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
because i need to show again that JFrame with some information added in it during operations from first JFrame. So i init second JFrame with attribute visible false. if i use dispose i lose the information added in a second moment by the other JFrame. so i use
private void formWindowClosing(java.awt.event.WindowEvent evt) {
this.setVisible(false);
}
but it still continue to terminate my entire app.
don't create a new JFrame, for new container use JDialog, if you want to hide the JFrame then better would be override proper e.g DefaultCloseOperations(JFrame.HIDE_ON_CLOSE), method JFrame.EXIT_ON_CLOSE teminating current JVM instance simlair as calll for System.exit(int)
EDIT
but it still continue to terminate my entire app.
1) then there must be another issue, your code maybe call another JFrame or formWindowClosing <> WindowClosing, use implemented method from API
public void windowClosing(WindowEvent e) {
2) I'b preferred DefaultCloseOperations(JFrame.HIDE_ON_CLOSE),
3) use JDialog instead of JFrame
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class ClosingFrame extends JFrame {
private JMenuBar MenuBar = new JMenuBar();
private static JFrame frame = new JFrame();
private static JFrame frame1 = new JFrame("DefaultCloseOperation(JFrame.HIDE_ON_CLOSE)");
private static final long serialVersionUID = 1L;
private JMenu File = new JMenu("File");
private JMenuItem Exit = new JMenuItem("Exit");
public ClosingFrame() {
File.add(Exit);
MenuBar.add(File);
Exit.addActionListener(new ExitListener());
WindowListener exitListener = new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
frame.setVisible(false);
/*int confirm = JOptionPane.showOptionDialog(frame,
"Are You Sure to Close this Application?",
"Exit Confirmation", JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE, null, null, null);
if (confirm == JOptionPane.YES_OPTION) {
System.exit(1);
}*/
}
};
JButton btn = new JButton("Show second JFrame");
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
frame1.setVisible(true);
}
});
frame.add(btn, BorderLayout.SOUTH);
frame.addWindowListener(exitListener);
frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
frame.setJMenuBar(MenuBar);
frame.setPreferredSize(new Dimension(400, 300));
frame.setLocation(100, 100);
frame.pack();
frame.setVisible(true);
}
private class ExitListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
int confirm = JOptionPane.showOptionDialog(frame,
"Are You Sure to Close this Application?",
"Exit Confirmation", JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE, null, null, null);
if (confirm == JOptionPane.YES_OPTION) {
System.exit(1);
}
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
ClosingFrame cf = new ClosingFrame();
JButton btn = new JButton("Show first JFrame");
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
frame.setVisible(true);
}
});
frame1.add(btn, BorderLayout.SOUTH);
frame1.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
frame1.setPreferredSize(new Dimension(400, 300));
frame1.setLocation(100, 400);
frame1.pack();
frame1.setVisible(true);
}
});
}
}
Adding a New Code with no WindowListener part as explained by #JBNizet, the very right thing. The default behaviour just hides the window, nothing is lost, you simply have to bring it back, every value inside it will remain as is, below is the sample program for further help :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TwoFrames
{
private SecondFrame secondFrame;
private int count = 0;
private void createAndDisplayGUI()
{
JFrame frame = new JFrame("JFRAME 1");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
secondFrame = new SecondFrame();
secondFrame.createAndDisplayGUI();
secondFrame.tfield.setText("I will be same everytime.");
JPanel contentPane = new JPanel();
JButton showButton = new JButton("SHOW JFRAME 2");
showButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
secondFrame.tfield.setText(secondFrame.tfield.getText() + count);
count++;
if (!(secondFrame.isShowing()))
secondFrame.setVisible(true);
}
});
frame.add(contentPane, BorderLayout.CENTER);
frame.add(showButton, BorderLayout.PAGE_END);
frame.setSize(200, 200);
frame.setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new TwoFrames().createAndDisplayGUI();
}
});
}
}
class SecondFrame extends JFrame
{
private WindowAdapter windowAdapter;
public JTextField tfield;
public void createAndDisplayGUI()
{
setLocationByPlatform(true);
JPanel contentPane = new JPanel();
tfield = new JTextField(10);
addWindowListener(windowAdapter);
contentPane.add(tfield);
getContentPane().add(contentPane);
setSize(300, 300);
}
}
Is this what you want, try this code :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TwoFrames
{
private SecondFrame secondFrame;
private void createAndDisplayGUI()
{
JFrame frame = new JFrame("JFRAME 1");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
secondFrame = new SecondFrame();
secondFrame.createAndDisplayGUI();
secondFrame.tfield.setText("I will be same everytime.");
JPanel contentPane = new JPanel();
JButton showButton = new JButton("SHOW JFRAME 2");
showButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
if (!(secondFrame.isShowing()))
secondFrame.setVisible(true);
}
});
frame.add(contentPane, BorderLayout.CENTER);
frame.add(showButton, BorderLayout.PAGE_END);
frame.setSize(200, 200);
frame.setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new TwoFrames().createAndDisplayGUI();
}
});
}
}
class SecondFrame extends JFrame
{
private WindowAdapter windowAdapter;
public JTextField tfield;
public void createAndDisplayGUI()
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationByPlatform(true);
JPanel contentPane = new JPanel();
tfield = new JTextField(10);
windowAdapter = new WindowAdapter()
{
public void windowClosing(WindowEvent we)
{
setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
}
};
addWindowListener(windowAdapter);
contentPane.add(tfield);
getContentPane().add(contentPane);
setSize(300, 300);
}
}
You could avoid the listener completely and use
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
Note that the default value is HIDE_ON_CLOSE, so the behavior you want should be the default behavior. Maybe you registered another listener that exits the application.
See http://docs.oracle.com/javase/6/docs/api/javax/swing/JFrame.html#setDefaultCloseOperation%28int%29
It's hard to pinpoint exactly why you are experiencing the behavior stated without seeing a little more of the set-up code, however it may be due to defaultCloseOperation set to EXIT_ON_CLOSE.
Here's a link to a demo displaying the properties you are looking for although the structure is a bit different. Have a look: http://docs.oracle.com/javase/tutorial/uiswing/examples/components/FrameworkProject/src/components/Framework.java