Java Modal Dialog Won't Block Code Execution - java

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);
}
}

Related

jDialog not showing

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();
}
}
}
}

Call actionPerformed Method using normal method of class

I am trying to call the actionPerformed() in normal method of class. I know that it get automatically executed on whenever button get pressed. But I want to call that method when ENTER button get pressed on Specific textfield. Is it possible to call actionPerformed() in keyPressed() or in normal function/method.
The following code will give you rough idea what I want to do.
void myFunction()
{
actionPerformed(ActionEvent ae);
}
public void actionPerformed(ActionEvent ae)
{
//my code
}
Thanks in advance
If you want, some actionPerformed() method of a JButton to be executed on pressing ENTER inside a JTextField, then I guess you can use the doClick(), method from AbstractButton class to achieve this. Though this approach, might can override the original behaviour of the JTextField on press of the ENTER key :(
Please have a look at this code pasted below, to see if this is what, stands fit for your needs :-) !!!
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ButtonClickExample
{
private JTextField tfield;
private JButton button;
private JLabel label;
private ActionListener actions = new ActionListener()
{
#Override
public void actionPerformed(ActionEvent ae)
{
if (ae.getSource() == button)
{
label.setText(tfield.getText());
}
else if (ae.getSource() == tfield)
{
button.doClick();
}
}
};
private void displayGUI()
{
JFrame frame = new JFrame("Button Click Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel contentPane = new JPanel();
contentPane.setLayout(new BorderLayout(5, 5));
JPanel centerPanel = new JPanel();
tfield = new JTextField("", 10);
button = new JButton("Click Me or not, YOUR WISH");
tfield.addActionListener(actions);
button.addActionListener(actions);
centerPanel.add(tfield);
centerPanel.add(button);
contentPane.add(centerPanel, BorderLayout.CENTER);
label = new JLabel("Nothing to show yet", JLabel.CENTER);
contentPane.add(label, BorderLayout.PAGE_END);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
#Override
public void run()
{
new ButtonClickExample().displayGUI();
}
});
}
}
I know this is an old thread, but for other people seeing this my recomendation is something like this:
// This calls the method that you call in the listener method
void performActionPerformedMethod(){
actionPerformed(ActionEvent e);
}
// This is what you want the listener method to do
void actionPerformedMethod(){
// Code...
}
// This is the interface method
public void actionPerformed(ActionEvent e){
actionPerformedMethod()
}

How to make JDialog onTop only for his parent?

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();
}
}

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

show two dialogs on top of each other using java swing

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.

Categories