jDialog not showing - java

I have tried to add my jPanel to a jDialog and when I trigger the button nothing happens. Why? I have the code below:
public class fontFormat{
public void fontPanel(){
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout());
panel.getPreferredSize();
Dimension size = new Dimension();
size.width = 400;
size.height = 600;
panel.setPreferredSize(size);
panel.add(new JLabel("label"));
panel.add(new JButton("button"));
JDialog fontDialog = new JDialog();
fontDialog.add(fontDialog);
}
}

Here:
JDialog fontDialog = new JDialog();
fontDialog.add(fontDialog);
You appear to be trying to add your JDialog to itself, which should cause your code to not function. While this code may compile, running this method should cause the JVM to throw an IllegalArgumentException on the fontDialog.add(fontDialog); line.
Please note that you show a JDialog similar to how you show a JFrame:
When you call your JDialog constructor, you will want to pass in the parent window into it, especially if your desire is to display a modal dialog.
You will also want to pass into the constructor the correct ModalityType enum.
You give your JDialog content, often a JPanel with your components on it.
You pack it
then you call setVisible(true) on it, and it should display
For example,
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class DialogEg {
private static void createAndShowGUI() {
MainPanelGen mainPanelGen = new MainPanelGen();
JFrame frame = new JFrame("DialogEg");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanelGen.getMainPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
class MainPanelGen {
private JPanel mainPanel = new JPanel();
private JTextField field = new JTextField(10);
private JButton btn = new JButton(new BtnActn());
private JDialog dialog;
private DialogPanel dialogPanel = new DialogPanel();
public MainPanelGen() {
mainPanel.add(field);
mainPanel.add(btn);
field.setEditable(false);
field.setFocusable(false);
}
public JPanel getMainPanel() {
return mainPanel;
}
private class BtnActn extends AbstractAction {
BtnActn() {
super("Button");
}
#Override
public void actionPerformed(ActionEvent arg0) {
if (dialog == null) {
Window win = SwingUtilities.getWindowAncestor(mainPanel);
if (win != null) {
dialog = new JDialog(win, "My Dialog",
Dialog.ModalityType.APPLICATION_MODAL);
dialog.getContentPane().add(dialogPanel);
dialog.pack();
dialog.setLocationRelativeTo(null);
}
}
dialog.setVisible(true); // here the modal dialog takes over
System.out.println (dialogPanel.getFieldText());
field.setText(dialogPanel.getFieldText());
}
}
}
class DialogPanel extends JPanel {
private JTextField field = new JTextField(10);
private JButton exitBtn = new JButton(new ExitBtnAxn("Exit"));
public DialogPanel() {
add(field);
add(exitBtn);
}
public String getFieldText() {
return field.getText();
}
private class ExitBtnAxn extends AbstractAction {
public ExitBtnAxn(String name) {
super(name);
}
#Override
public void actionPerformed(ActionEvent arg0) {
Window win = SwingUtilities.getWindowAncestor(DialogPanel.this);
if (win != null) {
win.dispose();
}
}
}
}

Related

Java Modal Dialog Won't Block Code Execution

Basically.. I made a JDialog using swing. And now I want it to return a value to the JFrame that called it. Problem is, whenever I call the constructor for the JDialog, it won't block the thread even though I've set setModal(true). Am I missing something obvious here?
private final JPanel contentPanel = new JPanel();
private File chosenFile = null;
private JList list;
private File[] files;
public File getInformation()
{
return chosenFile;
}
/**
* Create the dialog.
*/
public PatientPicker(JFrame parent)
{
super(parent);
setModal(true);
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
setLocationRelativeTo(parent);
setBounds(100, 100, 450, 396);
getContentPane().setLayout(new BorderLayout());
contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
getContentPane().add(contentPanel, BorderLayout.CENTER);
files = new File(ClientInfo.GetAppData() + "/patients").listFiles(new TextFileFilter());
{
JPanel buttonPane = new JPanel();
buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
getContentPane().add(buttonPane, BorderLayout.SOUTH);
{
JButton okButton = new JButton("OK");
okButton.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent arg0) {
if(files.length != 0)
chosenFile = files[list.getSelectedIndex()];
dispose();
}
});
okButton.setActionCommand("OK");
buttonPane.add(okButton);
getRootPane().setDefaultButton(okButton);
}
{
JButton cancelButton = new JButton("Cancel");
cancelButton.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent arg0) {
dispose();
}
});
cancelButton.setActionCommand("Cancel");
buttonPane.add(cancelButton);
}
}
}
And then here is how I create it:
PatientPicker patientPicker = new PatientPicker(frmReportGenerator);
File dataFile = patientPicker.getInformation();
You state:
Problem is, whenever I call the constructor for the JDialog, it won't block the thread even though I've set setModal(true). Am I missing something obvious here?
The constructor will never block the event thread. Modality means that the event thread is blocked only when you call setVisible (true) on your modal dialog (as per the api).
Unrelated problem: you should not use MouseListeners on JButtons but rather ActionListeners. Otherwise you will run into major problems now, such as when you press the file via the space bar, and while it does depress, nothing happens, and in later code, such as say when you make the button disabled, and yet it is still functioning, even though it looks disabled.
Now if you are still having problems, then you may wish to post more code, a minimal code example program which would allow us to understand and experience your problem.
Edit
You state:
Yes. The user chooses a file in the JDialog and I want it to return to the JFrame that called it.
Why not just use a JFileChooser modal dialog?
Edit 2
An example using a JOptionPane:
import java.awt.event.*;
import javax.swing.*;
#SuppressWarnings("serial")
public class SwingFoo extends JPanel {
private JTextField fileField = new JTextField(20);
private JButton showDialog = new JButton(new ShowDialogAction("Show Dialog",
KeyEvent.VK_D, this));
public SwingFoo() {
fileField.setEditable(false);
fileField.setFocusable(false);
add(new JLabel("File Selected:"));
add(fileField);
add(showDialog);
}
public void setFileFieldText(String text) {
fileField.setText(text);
}
private static void createAndShowGui() {
SwingFoo mainPanel = new SwingFoo();
JFrame frame = new JFrame("SwingFoo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
#SuppressWarnings("serial")
class ShowDialogAction extends AbstractAction {
private SwingFoo swingFoo;
public ShowDialogAction(String name, int mnemonic, SwingFoo swingFoo) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
this.swingFoo = swingFoo;
}
#Override
public void actionPerformed(ActionEvent e) {
PatientPicker patientPicker = new PatientPicker();
int result = JOptionPane.showConfirmDialog(swingFoo, patientPicker,
"Select Something", JOptionPane.OK_CANCEL_OPTION);
if (result == JOptionPane.OK_OPTION) {
swingFoo.setFileFieldText(patientPicker.getSelectedItem());
}
patientPicker.setVisible(true);
}
}
#SuppressWarnings("serial")
class PatientPicker extends JPanel {
private static final String[] ITEMS = {"Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Sunday", "Fubar", "Snafu", "DILLIGAF", "BOHICA"};
private JList<String> selectionList = new JList<>(ITEMS);
public PatientPicker() {
add(new JScrollPane(selectionList));
selectionList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
}
public String getSelectedItem() {
return selectionList.getSelectedValue();
}
}
What you need to do is have a way to send a notification to your main window once the user has completed interacting with the dialog assuming they clicked the ok button.
You can do this by creating an anonymous class and passing that along in the constructor of your Dialog.
let's assume that you open the dialog with a button called openDialogBtn from the main window:
openDialogBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
new PatientPicker(this, new FileSelectionNotifier() {
public void okButtonPressed(File chosenFile) {
// do whatever you need to do with the file (assign to a member variable
// or call another thread to do some kind of processing
}
});
In your dialog window you would need to have something like this:
okButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dispose();
// notify that the ok button was pressed
fileSelectionNotifier.okButtonPressed(chosenFile);
}
}

Static Input Dialog with JDialog

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.

How to start 2nd Jframe by click menu item in 1st java windows application (Jframe)

I am using eclipse 4.2 with Java.
I have 2 java program : AppWin.java Form1.java
AppWin.java is gui windows application with menu/menu item1.
Form1.java is a Gui Jframe
I like to call Form1.java from AppWin.java by click the menu/menu item1.
When close Form1.java, it is back to AppWin.java.
This is something like MDIFORM. I really cannot find answer.
Please help , if you know eclipse menu.
Thanks
package top;
import java.awt.EventQueue;
public class AppWin {
private JFrame frame;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
AppWin window = new AppWin();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
...
With your help, I made a big step.
Thanks to all of you!
Next is my final demo, in windows 7, eclipse 4.2, java Gui
Hope it is helpful to others.
There are 3 parts : AppWin, Form1, Form2. AppWin is top main which call Form1 and Form2 with menu/item.
//1
package top;
import java.awt.EventQueue;
public class AppWin {
private JFrame frame;
private Form1 form1;
private Form2 form2;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
AppWin window = new AppWin();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public AppWin() {
initialize();
form1 = new Form1();
form2 = new Form2();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JMenuBar menuBar = new JMenuBar();
frame.setJMenuBar(menuBar);
JMenu mnNewMenu = new JMenu("Menu1");
menuBar.add(mnNewMenu);
JMenuItem mntmNewMenuItem = new JMenuItem("menu item1");
mntmNewMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
form1.setVisible(true);
}
});
mnNewMenu.add(mntmNewMenuItem);
JMenuItem mntmNewMenuItem_1 = new JMenuItem("menu item2");
mntmNewMenuItem_1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
form2.setVisible(true);
}
});
mnNewMenu.add(mntmNewMenuItem_1);
JMenu mnNewMenu_1 = new JMenu("Menu2");
menuBar.add(mnNewMenu_1);
JMenuItem mntmMenuItem = new JMenuItem("Menu item3");
mnNewMenu_1.add(mntmMenuItem);
}
}
//2
package top;
import java.awt.BorderLayout;
public class Form1 extends JFrame {
private JPanel contentPane;
private JTextField textField;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Form1 frame = new Form1();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public Form1() {
// setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);
JLabel lblNewLabel = new JLabel("this Form1");
contentPane.add(lblNewLabel, BorderLayout.WEST);
textField = new JTextField();
contentPane.add(textField, BorderLayout.CENTER);
textField.setColumns(10);
JButton btnNewButton = new JButton("New button");
contentPane.add(btnNewButton, BorderLayout.EAST);
}
}
//3
package top;
import java.awt.BorderLayout;
public class Form2 extends JDialog {
private final JPanel contentPanel = new JPanel();
/**
* Launch the application.
*/
public static void main(String[] args) {
try {
Form2 dialog = new Form2();
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Create the dialog.
*/
public Form2() {
setBounds(100, 100, 450, 300);
getContentPane().setLayout(new BorderLayout());
contentPanel.setLayout(new FlowLayout());
contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
getContentPane().add(contentPanel, BorderLayout.CENTER);
{
JLabel lblThisForm = new JLabel("This Form2");
contentPanel.add(lblThisForm);
}
{
JPanel buttonPane = new JPanel();
buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
getContentPane().add(buttonPane, BorderLayout.SOUTH);
{
JButton okButton = new JButton("OK");
okButton.setActionCommand("OK");
buttonPane.add(okButton);
getRootPane().setDefaultButton(okButton);
}
{
JButton cancelButton = new JButton("Cancel");
cancelButton.setActionCommand("Cancel");
buttonPane.add(cancelButton);
}
}
}
}
Thanks again
You better use JDesktopPane + JInternalFrame for that purpose instead. Here's a quick sample.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
public class JInternalFrameSample {
private JPanel pnlMain;
private JDesktopPane desk;
public JInternalFrameSample(){
pnlMain = new JPanel(new BorderLayout()){
#Override public Dimension getPreferredSize(){
return new Dimension(600,600);
}
};
desk = new JDesktopPane();
JMenuBar bar = new JMenuBar();
JMenu menu = new JMenu("Internal Frame");
JMenuItem item = new JMenuItem();
item.setAction(new AbstractAction("Create New") {
#Override
public void actionPerformed(ActionEvent arg0) {
JInternalFrame iFrame = new JInternalFrame("Created from Menu");
iFrame.setResizable(true);
iFrame.setClosable(true);
iFrame.setIconifiable(true);
iFrame.setSize(new Dimension(300, 300));
iFrame.setLocation(0, 0);
//iFrame.getContentPane().setLayout(new BorderLayout());
//iFrame.getContentPane().add( new YourCustomUI().getUI() );
iFrame.setVisible(true);
desk.add(iFrame);
}
});
menu.add(item);
bar.add(menu);
pnlMain.add(bar, BorderLayout.PAGE_START);
pnlMain.add(desk, BorderLayout.CENTER);
}
private JPanel getUI(){
return pnlMain;
}
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame("Demo");
frame.getContentPane().setLayout(new BorderLayout());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new JInternalFrameSample().getUI());
frame.pack();
frame.setVisible(true);
}
});
}
}
See also : How to Use Internal Frames
If you do not like the JDesktopPane and JInternalFrame solution, just use your AppWin JFrame as is, and open modal JDialogs for the rest of the forms, instead of JFrames. Modal dialogs can float around the desktop and do not allow you to click your AppWin, until they are closed.
It is usually better to use just one main JFrame for an application, unless you have some wizard application that moves progressively from one JFrame to the other and back. Even with a wizard app, you can stick with one JFrame and update progressively just the ContentPane with JPanels.
Here is the AppWin JFrame:
public class AppWin extends javax.swing.JFrame {
private Form1 form1;
private Form1 form2;
...
private FormN formN;
public AppWin() {
initComponents();
form1 = new Form1(this, true);
form2 = new Form2(this, true);
...
formN = new FormN(this, true);
}
...
private void jMenuItem1ActionPerformed(java.awt.event.ActionEvent evt) {
form1.setVisible(true);
}
And here is your Form1 JDialog:
public class Form1 extends javax.swing.JDialog {
public Form1(java.awt.Frame parent, boolean modal) {
super(parent, modal);
initComponents();
}
...
private void closeButtonActionPerformed(java.awt.event.ActionEvent evt) {
setVisible(false);
}
I only use NetBeans for GUI building because that's more convenient. In the following I can tell you how to achieve what you want to do but I can't tell you how to layout all the components because NetBeans do that for me.
So basically you want to 1. show secondFrame by clicking a menuitem and then close mainFrame, 2. show mainFrame after closing secondFrame, yes? Then, the key is to pass the reference of mainFrame to secondFrame, and write your own method of formClosing event of secondFrame. Something like this:
In the menuItem method in your mainframe:
private void menuItemActionPerformed(java.awt.event.ActionEvent evt) {
//pass 'this' frame's (mainFrame) reference to the secondFrame
SecondFrame newFrame = new SecondFrame(this);
newFrame.setVisible(true); //show the secondFrame
this.setVisible(false); //hide this frame (mainFrame)
}
In your secondFrame:
public class SecondFrame extends javax.swing.JFrame {
private MainFrame mainFrame;
//define your own constructor that can use mainFrame's reference
public SecondFrame(MainFrame mainFrame) {
initComponents();
this.mainFrame = mainFrame;
}
private void initComponents(){
//bind your own event for closing second frame
setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent evt) {
formWindowClosing(evt);
}
});
/***********your stuff***************/
}
//show mainFrame when closing this frame and then dispose this frame
private void formWindowClosing(java.awt.event.WindowEvent evt) {
mainFrame.setVisible(true);
this.dispose();
}
}
The codes above is for disposing the secondFrame when closing it. If you just want to hide the secondFrame when closing for future use, then the codes will be slightly different. Let me know what you up to.
private void jMenuItem1ActionPerformed(java.awt.event.ActionEvent evt) {
form1.setVisible(true);
dispose();
}

How to override windowsClosing event in JFrame

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

GUI multiple frames switch

I am writing a program for a black jack game. It is an assignment we are not to use gui's but I am doing it for extra credit I have created two frames ant they are working. On the second frame I want to be able to switch back to the first when a button is pressed. How do I do this?
first window.............
import javax.swing.* ;
import java.awt.event.* ;
import java.awt.* ;
import java.util.* ;
public class BlackJackWindow1 extends JFrame implements ActionListener
{
private JButton play = new JButton("Play");
private JButton exit = new JButton("Exit");
private JPanel pane=new JPanel();
private JLabel lbl ;
public BlackJackWindow1()
{
super();
JPanel pane=new JPanel();
setTitle ("Black Jack!!!!!") ;
JFrame frame = new JFrame("");
setVisible(true);
setSize (380, 260) ;
setLocation (450, 200) ;
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE) ;
setLayout(new FlowLayout());
play = new JButton("Start");
exit = new JButton("exit");
lbl = new JLabel ("Welcome to Theodores Black Jack!!!!!");
add (lbl) ;
add(play, BorderLayout.CENTER);
play.addActionListener (this);
add(exit,BorderLayout.CENTER);
exit.addActionListener (this);
}
#Override
public void actionPerformed(ActionEvent event)
{
// TODO Auto-generated method stub
BlackJackWindow2 bl = new BlackJackWindow2();
if (event.getSource() == play)
{
bl.BlackJackWindow2();
}
else if(event.getSource() == exit){
System.exit(0);
}
}
second window....
import javax.swing.* ;
import java.awt.event.* ;
import java.awt.* ;
import java.util.* ;
public class BlackJackWindow2 extends JFrame implements ActionListener
{
private JButton hit ;
private JButton stay ;
private JButton back;
//private JLabel lbl;
public void BlackJackWindow2()
{
// TODO Auto-generated method stub
JPanel pane=new JPanel();
setTitle ("Black Jack!!!!!") ;
JFrame frame = new JFrame("");
setVisible(true);
setSize (380, 260) ;
setLocation (450, 200) ;
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE) ;
setLayout(new FlowLayout());
hit = new JButton("Hit");
stay = new JButton("stay");
back = new JButton("return to main menu");
// add (lbl) ;
add(hit, BorderLayout.CENTER);
hit.addActionListener (this) ;
add(stay,BorderLayout.CENTER);
stay.addActionListener (this) ;
add(back,BorderLayout.CENTER);
back.addActionListener (this) ;
}
#Override
public void actionPerformed(ActionEvent event)
{
// TODO Auto-generated method stub
BlackJackWindow1 bl = new BlackJackWindow1();
if (event.getSource() == hit)
{
//code for the game goes here i will complete later
}
else if(event.getSource() == stay){
//code for game goes here i will comeplete later.
}
else
{
//this is where i want the frame to close and go back to the original.
}
}
}
The second frame needs a reference to the first frame so that it can set the focus back to the first frame.
Also your classes extend JFrame but they are also creating other frames in their constructors.
A couple of suggestions:
You're adding components to a JPanel that uses FlowLayout but are using BorderLayout constants when doing this which you shouldn't do as it doesn't make sense:
add(play, BorderLayout.CENTER);
Rather, if using FlowLayout, just add the components without those constants.
Also, rather than swap JFrames, you might want to consider using a CardLayout and swapping veiws in a single JFrame. For instance:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class FooBarBazDriver {
private static final String INTRO = "intro";
private static final String GAME = "game";
private CardLayout cardlayout = new CardLayout();
private JPanel mainPanel = new JPanel(cardlayout);
private IntroPanel introPanel = new IntroPanel();
private GamePanel gamePanel = new GamePanel();
public FooBarBazDriver() {
mainPanel.add(introPanel.getMainComponent(), INTRO);
mainPanel.add(gamePanel.getMainComponent(), GAME);
introPanel.addBazBtnActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
cardlayout.show(mainPanel, GAME);
}
});
gamePanel.addBackBtnActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
cardlayout.show(mainPanel, INTRO);
}
});
}
private JComponent getMainComponent() {
return mainPanel;
}
private static void createAndShowUI() {
JFrame frame = new JFrame("Foo Bar Baz");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new FooBarBazDriver().getMainComponent());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
class IntroPanel {
private JPanel mainPanel = new JPanel();
private JButton baz = new JButton("Baz");
private JButton exit = new JButton("Exit");
public IntroPanel() {
mainPanel.setLayout(new FlowLayout());
baz = new JButton("Start");
exit = new JButton("exit");
mainPanel.add(new JLabel("Hello World"));
mainPanel.add(baz);
mainPanel.add(exit);
exit.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Window win = SwingUtilities.getWindowAncestor(mainPanel);
win.dispose();
}
});
}
public void addBazBtnActionListener(ActionListener listener) {
baz.addActionListener(listener);
}
public JComponent getMainComponent() {
return mainPanel;
}
}
class GamePanel {
private static final Dimension MAIN_SIZE = new Dimension(400, 200);
private JPanel mainPanel = new JPanel();
private JButton foo;
private JButton bar;
private JButton back;
public GamePanel() {
foo = new JButton("Foo");
bar = new JButton("Bar");
back = new JButton("return to main menu");
mainPanel.add(foo);
mainPanel.add(bar);
mainPanel.add(back);
mainPanel.setPreferredSize(MAIN_SIZE);
}
public JComponent getMainComponent() {
return mainPanel;
}
public void addBackBtnActionListener(ActionListener listener) {
back.addActionListener(listener);
}
}
Since I had to test it myself if it is in fact so easy to implement, I built this simple example. It demonstrates a solution to your problem. Slightly inspired by #jzd's answer (+1 for that).
import java.awt.Color;
import java.awt.HeadlessException;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class FocusChangeTwoFrames
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
createGUI();
}
});
}
private static void createGUI() throws HeadlessException
{
final JFrame f2 = new JFrame();
f2.getContentPane().setBackground(Color.GREEN);
final JFrame f1 = new JFrame();
f1.getContentPane().setBackground(Color.RED);
f1.setSize(400, 300);
f1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f1.setVisible(true);
MouseListener ml = new MouseAdapter()
{
#Override
public void mousePressed(MouseEvent e)
{
if(f1.hasFocus())
f2.requestFocus();
else
f1.requestFocus();
}
};
f1.addMouseListener(ml);
f2.setSize(400, 300);
f2.setLocation(200, 150);
f2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f2.setVisible(true);
f2.addMouseListener(ml);
}
}
Enjoy, Boro.

Categories