how to allow to open new jdialogbox in jdialog box - java

i want to open new JDialog box inside JDialog box. so i have used that code to prevent to come on ancestor JFrame but i am facing the problem to open new JDialog box in previous JDialog box. please give me the solution to get rid of this problem.
Here is the code :-
TestbedWorkflow tbwf = new TestbedWorkflow();
JDialog dialog = new JDialog();
Dimension s = SOAStreamer.getSOAStreamerObj().getContentPanel().getSize();
dialog.setSize(s);
dialog.setTitle("TestBed Workflow Design");
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
tbwf.setSize(s);
dialog.add(tbwf);
tbwf.updateUI();
dialog.setVisible(true);
TestbedWorkflow is JFrame which i have added in to JDialog box.now i want to open new JDialog box.
thanks in advance

The example below opens an arbitrary number of dialogs in an APPLICATION_MODAL hierarchy; only the most recent is operable. As an alternative, consider a modeless dialog, illustrated here.
Update: The revised example below shows the hierarchy depth in the dialog title and eliminates a spurious subclass.
import java.awt.Dialog;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
/**
* #see https://stackoverflow.com/a/12301243/230513
*/
public class DialogTest {
private static int index;
static class OpenAction extends AbstractAction {
public OpenAction() {
super("Open");
}
#Override
public void actionPerformed(ActionEvent e) {
JDialog jd = new JDialog();
jd.setTitle("D" + String.valueOf(++index));
jd.setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
jd.add(new JButton(new OpenAction()));
jd.pack();
jd.setLocationRelativeTo(null);
jd.setVisible(true);
}
}
private void display() {
JFrame f = new JFrame("DialogTest");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new JButton(new OpenAction()));
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new DialogTest().display();
}
});
}
}

Related

unable to close JOptionPane properly in chain order

I am displaying a JOptionPane suppose A on a button click from JFrame, and again displaying another JOptionPane suppose B on a button click from JOptionPane A, and I have a button on JOptionPane B suppoce button1, on the click event of button1, I am using code JOptionPane.getRootFrame().dispose() for closing the JOptionPane B, but it closes both A and B, please help me how can close only B but not A.
here is my sample code
i want second JOptionPane must be open
import java.awt.Dimension;
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.JOptionPane;
import javax.swing.JPanel;
public class SampleCode extends JFrame {
public SampleCode() {
setSize(new Dimension(500, 500));
setLocation(450, 150);
but1 = new JButton("Click me");
add(but1);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
but1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
but1Function();
}
});
}
public static void main(String args[]) {
new SampleCode();
}
void but1Function() {
JPanel panel1 = new JPanel();
JButton but2 = new JButton("Open new dialog");
panel1.add(but2);
but2.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JPanel pan2 = new JPanel();
JButton but3 = new JButton("click me to close");
pan2.add(but3);
but3.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JOptionPane.getRootFrame().dispose();
}
});
JOptionPane.showMessageDialog(null, pan2);
}
});
JOptionPane jp = new JOptionPane(panel1, JOptionPane.CLOSED_OPTION,
JOptionPane.DEFAULT_OPTION, null, new Object[] {}, null);
JDialog dialog = jp.createDialog(null, "This one must be remain open");
dialog.setLocation(500, 200);
dialog.setSize(new Dimension(345, 200));
dialog.setVisible(true);
}
JButton but1;
}
You don't want to get the root frame nor dispose of it. You want to get the window that is displaying the JOptionPane, a Window that should be a modal JDialog. So instead, use SwingUtilities.getWindowAncestor(someComponentInJOptionPane), and call dispose() on that Window if you want to programmatically dispose of your JOPtionPane.
import java.awt.Component;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class OptionPaneFun {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#SuppressWarnings("serial")
public void run() {
final JPanel panel1 = new JPanel();
panel1.add(new JButton(new AbstractAction("Show new option pane") {
{
putValue(MNEMONIC_KEY, KeyEvent.VK_S);
}
#Override
public void actionPerformed(ActionEvent e1) {
final JPanel panel2= new JPanel();
panel2.add(new JButton(new AbstractAction("Dispose of this option pane") {
{
putValue(MNEMONIC_KEY, KeyEvent.VK_D);
}
#Override
public void actionPerformed(ActionEvent e2) {
Component comp = (Component) e2.getSource();
Window win = SwingUtilities.getWindowAncestor(comp);
if (win != null) {
win.dispose();
}
}
}));
JOptionPane.showMessageDialog(panel1, panel2);
}
}));
JOptionPane.showMessageDialog(null, panel1);
}
});
}
}
The static method "getRootFrame()" returns your root frame which is the only one and it's the same for both your components (A and B). What you need to do - you have to put two frames in your root frame (call them frameA and frameB) and put paneA to frameA and paneB to frameB. Instead of calling this static method just invoke frameB.dispose() on reference frameB which you already have.
Try to add
panel.validiate();
After the dispose command. I had the same problem once and it helped a lot when I used this trick.
Basically when you add this command, it is telling the frame to validate or actually do it.
Read the oracle docs for more info.

setModal issue with 2 Jdialogs within a Jframe

I am facing issues when I set my first JDialog modal and the second one non-modal.
This is the functionality I am trying to implement:
On click of "Test the dialog!" button, a JDialog with name Custom Dialog
Main will open.
If click "yes" option in Custom Dialog Main, another
JDialog named Custom Dialog Search will open.
If click "yes" option in Custom Dialog Search, then
Custom Dialog Main should come front.
And I should be able to select any JDialog. For example if I select
Custom Dialog Search, the other dialog should go
back and vice versa.
Problem I am facing is when I click "yes" in Custom Dialog Main, then Custom Dialog Search is displayed behind the main dialog.
This is happening because I am setting Custom Dialog Search non-modal.
If I this dialog modal it is displayed correctly but after I click "yes" Custom Dialog Main doesn't come front.
I even tried to set CustomDialogSearch's parent to be CustomDialog the behaviour still not correct.
Below is the example code I am testing.
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JButton;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.ActionEvent;
import java.awt.Dimension;
public class TestTheDialog implements ActionListener {
JFrame mainFrame = null;
JButton myButton = null;
public TestTheDialog() {
mainFrame = new JFrame("TestTheDialog Tester");
mainFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {System.exit(0);}
});
myButton = new JButton("Test the dialog!");
myButton.addActionListener(this);
mainFrame.setLocationRelativeTo(null);
mainFrame.getContentPane().add(myButton);
mainFrame.pack();
mainFrame.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if(myButton == e.getSource()) {
System.err.println("Opening dialog.");
CustomDialog myDialog = new CustomDialog(mainFrame, true, "Custom Dialog Main?");
System.err.println("After opening dialog.");
if(myDialog.getAnswer()) {
System.err.println("The answer stored in CustomDialog is 'true' (i.e. user clicked yes button.)");
}
else {
System.err.println("The answer stored in CustomDialog is 'false' (i.e. user clicked no button.)");
}
}
}
public static void main(String argv[]) {
TestTheDialog tester = new TestTheDialog();
}
}
import javax.swing.JDialog;
import java.awt.event.ActionListener;
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JButton;
import java.awt.event.ActionEvent;
public class CustomDialog extends JDialog implements ActionListener {
private JPanel myPanel = null;
private JButton yesButton = null;
private JButton noButton = null;
private boolean answer = false;
private JFrame parentFrame;
public boolean getAnswer() { return answer; }
public CustomDialog(JFrame frame, boolean modal, String myMessage) {
super(frame, modal);
parentFrame = frame;
myPanel = new JPanel();
getContentPane().add(myPanel);
myPanel.add(new JLabel(myMessage));
yesButton = new JButton("Yes");
yesButton.addActionListener(this);
myPanel.add(yesButton);
noButton = new JButton("No");
noButton.addActionListener(this);
myPanel.add(noButton);
pack();
setLocationRelativeTo(frame);
setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if(yesButton == e.getSource()) {
CustomDialogSearch myDialog = new CustomDialogSearch(parentFrame, false, "CustomDialog Search?");
System.err.println("User chose yes.");
answer = true;
myDialog.getAnswer();
System.out.println("myDialog.getAnswer()="+myDialog.getAnswer());
myDialog.show();
if(myDialog.getAnswer()==true)
{
System.out.println("tofront");
this.toFront();
}
//setVisible(false);
}
else if(noButton == e.getSource()) {
System.err.println("User chose no.");
answer = false;
setVisible(false);
}
}
}
import javax.swing.JDialog;
import java.awt.event.ActionListener;
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JButton;
import java.awt.event.ActionEvent;
public class CustomDialogSearch extends JDialog implements ActionListener {
private JPanel myPanel = null;
private JButton yesButton = null;
private JButton noButton = null;
private boolean answer = false;
public boolean getAnswer() { return answer; }
public CustomDialogSearch(JFrame frame, boolean modal, String myMessage) {
super(frame, modal);
myPanel = new JPanel();
getContentPane().add(myPanel);
myPanel.add(new JLabel(myMessage));
yesButton = new JButton("Yes");
yesButton.addActionListener(this);
myPanel.add(yesButton);
noButton = new JButton("No");
noButton.addActionListener(this);
myPanel.add(noButton);
pack();
setLocationRelativeTo(frame);
setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if(yesButton == e.getSource()) {
System.err.println("Search User chose yes.");
answer = true;
//setVisible(false);
}
else if(noButton == e.getSource()) {
System.err.println("Search User chose no.");
answer = false;
setVisible(false);
}
}
}
I even tried to set CustomDialogSearch's parent to be CustomDialog the
behaviour still not correct.
I think you're in the right track here but you need to play with dialogs modality type. For instance:
Set the modality type of Custom Dialog Main ("parent" dialog) as Dialog.ModalityType.APPLICATION_MODAL. By doing this when this dialog is visible it will block all windows except its children.
Set the modality type of Custom Dialog Search ("child" dialog) as Dialog.ModalityType.MODELESS. This way it won't block any other window and you can go from the child to the parent and vice versa.
For a better understanding take a look to How to Use Modality in Dialogs article.
Example
Here is a code example about using modality as I've suggested above:
import java.awt.Dialog;
import java.awt.Window;
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.SwingUtilities;
public class Demo {
private void createAndShowGUI() {
JButton button = new JButton("Create Parent modal dialog");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JButton button = (JButton)e.getSource();
JFrame owner = (JFrame)SwingUtilities.windowForComponent(button);
Demo.this.createAndShowParentDialog(owner);
}
});
JFrame frame = new JFrame("Demo");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(button);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void createAndShowParentDialog(JFrame owner) {
JButton button = new JButton("Create Child non-modal dialog");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JButton button = (JButton)e.getSource();
JDialog parent = (JDialog)SwingUtilities.windowForComponent(button);
Demo.this.createAndShowChildrenDialog(parent);
}
});
JDialog parentDialog = new JDialog(owner, "Parent dialog");
parentDialog.setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
parentDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
parentDialog.getContentPane().add(button);
parentDialog.pack();
parentDialog.setLocationRelativeTo(null);
parentDialog.setVisible(true);
}
private void createAndShowChildrenDialog(JDialog parent) {
JButton backButton = new JButton("Back to parent dialog");
backButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JButton button = (JButton)e.getSource();
Window dialog = SwingUtilities.windowForComponent(button);
dialog.getOwner().toFront();
}
});
JDialog childDialog = new JDialog(parent, "Child dialog");
childDialog.setModalityType(Dialog.ModalityType.MODELESS);
childDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
childDialog.getContentPane().add(backButton);
childDialog.pack();
childDialog.setLocationRelativeTo(null);
childDialog.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Demo().createAndShowGUI();
}
});
}
}
Edit
I can select the windows of parent and child JDialogs but when I
select the parent JDialog window, the child JDialog is still in front
of parent JDialog.
Well I have a better understanding now on what is the problem. This behaviour depends on how native windowing system handles focused and active windows. Having said this if you call for instance toFront() it will attempt to place the window at the top of the stack BUT some platforms do not allow windows which own other windows to appear on top of its childre. The same happens when you call toBack() method. See the javadocs for more details.
I've tested my code on Windows 7 (32 bits if it makes any difference) and parent dialog becomes focused but its children still showing (not focused) at the top. As mentioned above it's up to the windowing system decide how to handle this matter.

How to add ImageIcon into JDialog?

I tried to create a floating dialog box which contains a loader gif image and some text. I have got the following class:
public class InfoDialog extends JDialog {
public InfoDialog() {
setSize(200, 50);
setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
setUndecorated(true);
setLocationRelativeTo(null);
URL url = InfoDialog.class.getClassLoader().getResource("loader.gif");
ImageIcon loading = new ImageIcon(url);
getContentPane().add(new JLabel("Logging in ... ", loading, JLabel.CENTER));
}
}
However, when I call:
InfoDialog infoDialog = new InfoDialog()
infoDialog.setVisible(true);
An empty dialog is shown. The ImageIcon and the Label is not shown in the dialog box.
What did I do wrong in this code?
Many thanks.
Images are usually placed into a "resource" Source Folder,
and then accessed as a byte stream,
package com.foo;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
public class Demo
{
private static final String IMAGE_URL = "/resource/bar.png";
public static void main(String[] args)
{
createAndShowGUI();
}
private static void createAndShowGUI()
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
try
{
JDialog dialog = new JDialog();
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.setTitle("Image Loading Demo");
dialog.add(new JLabel(new ImageIcon(ImageIO.read(getClass().getResourceAsStream(IMAGE_URL)))));
dialog.pack();
dialog.setLocationByPlatform(true);
dialog.setVisible(true);
}
catch (IOException e)
{
e.printStackTrace();
}
}
});
}
}
to produce Morgan Freeman.
I would add the ImageIcon to a JLabel and then add JLabel to JDialog contentPane followed by a this.validate and this.repaint in the constructor.
To debug, sometimes you need actual code without which these are just suggestions based on assumptions

Dialog visible without app. on alt tab

I have developed Swing application in which I have used JDialog to show popup.
But the problem is when I press alt+tab it shows only the dialog not the application. I also tried the modal for dialog.
My requirement is when the dialog opened on application and I press the alt+tab key it switch to another X application and again when I press alt+tab key it display dialog opened on my application. Currently it shows dialog opened but alone not with application.
How I can meet this requirement using JDialog?
Here is sample code
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
*$Id$
*/
public class Main
{
public static void main(final String[] args)
{
final JFrame jFrame = new JFrame();
jFrame.setSize(300, 200);
final JPanel panel = new JPanel();
final JButton button = new JButton("click here to open dialog");
final ProductDialog dialog = new ProductDialog();
button.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(final ActionEvent e)
{
dialog.setVisible(true);
}
});
panel.add(button);
jFrame.add(panel);
jFrame.setVisible(true);
}
}
And The dialog is as under
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class ProductDialog extends JDialog
{
private static final long serialVersionUID = 1L;
public ProductDialog()
{
this.add(new JPanel().add(new JLabel("Test")));
this.setSize(150, 100);
this.setModal(true);
this.setLocationRelativeTo(null);
}
}
Here is an image of the visual effect of a small app. that is currently displaying a security dialog in alt+tab on Windows 7. The app. itself is already visible on-screen, though the security dialog (upper left) is all that is shown in the smaller icons.
You need to set the parent window of the dialog to the Frame of your application.
Small example:
import java.awt.Window;
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.SwingUtilities;
public class TestDialog {
protected void initUI() {
JFrame frame = new JFrame(TestDialog.class.getSimpleName());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JButton button = new JButton("Click me to open dialog");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Window parentWindow = SwingUtilities.windowForComponent(button);
JDialog dialog = new JDialog(parentWindow);
dialog.setLocationRelativeTo(button);
dialog.setModal(true);
dialog.add(new JLabel("A dialog"));
dialog.pack();
dialog.setVisible(true);
}
});
frame.add(button);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TestDialog().initUI();
}
});
}
}
I have pass the parent Frame to the Dialog as under.
final ProductDialog dialog = new ProductDialog(jFrame);
And set it as under
Call the constructor of super class with parent window as argument and set the modality type of dialog and it's work for me.
import java.awt.Dialog;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class ProductDialog extends JDialog
{
private static final long serialVersionUID = 1L;
public ProductDialog(final JFrame jFrame)
{
super(jFrame);
this.add(new JPanel().add(new JLabel("Test")));
this.setSize(150, 100);
this.setModal(true);
this.setModalityType(Dialog.ModalityType.DOCUMENT_MODAL);
}
}
This is just sample example that I have created for testing.

programmatically close a JPanel which is displayed in JDialog

I have a main application frame (MainFrame class). On actionperformed event of a JButton, a JPanel (MyJPanel class) is opened by placing it in JDialog. I am not extending JDialog to create MyJPanel class because I might need MyJPanel at other purposes too.
My Problem is I cannot programmatically close the MyJPanel which is displayed in JDialog. Is there anything that I missing? Could you please figure it out?
import java.awt.EventQueue;
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.JPanel;
import javax.swing.WindowConstants;
public class MainFrame extends JPanel {
public MainFrame() {
JButton btnOpenJdialog = new JButton("Open JDialog");
add(btnOpenJdialog);
btnOpenJdialog.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JDialog jd = new JDialog();
MyJPanel mjp = new MyJPanel(true);//showing in JDialog
jd.setTitle("JDialog");
jd.add(mjp);
jd.pack();
jd.setVisible(true);
}
});
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
JFrame frame = new JFrame("Test-JFrame");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.getContentPane().add(new MainFrame());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
MyJPanel Class :
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JPanel;
import javax.swing.JButton;
public class MyJPanel extends JPanel {
private boolean isShownInJDialog = false;
public MyJPanel() {
JButton btnCloseMe = new JButton("Finish Action");
add(btnCloseMe);
btnCloseMe.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (isShownInJDialog) {
MyJPanel.this.setVisible(false);
//how to close the JDialog too.
}
else {
//just hide the content,
MyJPanel.this.setVisible(false);
}
}
});
}
public MyJPanel(boolean isShownInJDialog) {
this();
this.isShownInJDialog = isShownInJDialog;
}
}
UPDATE
I was able to solve this using Howard's answer as :
...
if (isShownInJDialog) {
Window w = SwingUtilities.getWindowAncestor(MyJPanel.this);
w.setVisible(false);
}
...
If I understand your question correctly, you want to close the JDialog which your MyJPanel is contained in but do not have a reference to it?
You may either provide such a reference using the constructor of MyJPanel or change the code inside your ActionListener to
Window w = SwingUtilities.getWindowAncestor(MyJPanel.this);
w.setVisible(false);
which looks up the parent window of your panel without direct reference.

Categories

Resources