[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 931
  • Last Modified:

How do I get my modal JDialogs to always stay on top?

My application has a JFrame which contains internalframes. Each InternalFrame is the parent of a modal JDialog.  These modal dialogs work fine (ie. remain on top, can't click on anything else in that application until the modal dialog is closed) until I click on another window(s) on the taskbar and then go back to my application by clicking the icon on the taskbar.  The dialog isn't on top anymore, and is hidden behind the other window(s) that I have to minimize in order to get to the dialog.  How do I make this dialog always remain on the front of my application, even if I switch to other applications?  The code I used to display the dialog from the InternalFrame is:

MyDialog dialog = new MyDialog(this);
dialog.setVisible(true);

I set setModal(true) in the constructor of MyDialog.

Could this be a bug in the Java VM?
0
JavaTheHut
Asked:
JavaTheHut
  • 7
  • 5
  • 2
  • +1
1 Solution
 
Jim CakalicSenior Developer/ArchitectCommented:
JInternalFrame extends neither Dialog nor Frame so it cannot serve as the owner of a JDialog. I think you will get the behavior you desire if you use the application JFrame as the owner argument to the JDialog constructor. However, I don't know (off the top of my head) what this will do for each JInternalFrame having an associated modal JDialog.

Jim Cakalic
0
 
Sasha_MapaCommented:
Jim, are you sure that is possible? i.e. opening a Dialog that would be modal for all the applications, and block input from them? I think the reason that a Dialog needs a Frame (or another Dialog whose parent, or some grand-parent is eventually a Frame) as its parent is because it can only be modal to a certain Frame, not all Frames.
0
 
Jim CakalicSenior Developer/ArchitectCommented:
Sasha, I wasn't sure to begin with exactly what behavior the poster meant when s/he said, "Each InternalFrame is the parent of a modal JDialog." Is it possible for 6 JInternalFrames in the same JDesktopPane to all be displaying a modal JDialog at the same time? I'm guessing no.

What you are describing is what we would typically call a "System-modal" dialog. AFAIK, the Java platform does not support this. And I wasn't suggesting that this would or could occur.

The intent of my post was to point out, however poorly, that if the 'this' argument to the constructor of MyDialog refers to a JInternalFrame object as I think it does, then that could be part of the problem. A JInternalFrame cannot be the owner of a JDialog. Having no sample code to test my assumption, I thought I toss forward the idea and let the poster determine whether it was of value.

Best regards,
Jim
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
MoRsCommented:
JavaTheHut, if you want your dialog to be internal you should extend JInternalFrame, and then add this frame to MODAL_LAYER of JDesktopPane. But if you want these dialogs to be modal for all your application, you should extend JDialog and use JFrame as a parent. Hope this will help
0
 
Jim CakalicSenior Developer/ArchitectCommented:
My testing indicates similar behavior on jdk1.2.2 and jdk1.3rc3 (NT4/SP5). When the dialog is unowned, clicking on the application button in the Windows taskbar brings the parent window to the front but leaves the unowned dialog behind. Once in this state, the dialog will reappear if another window occludes the application and is then minimized. In this case, the application seems to know that the dialog needs to come forward. These symptoms disappear when the JDialog is owned by the JFrame.

Jim
0
 
JavaTheHutAuthor Commented:
Using the main JFrame as the parent to my dialogs (as opposed to an InternalFrame) was unsuccessful - same thing happens.  Any other suggestions?
0
 
Jim CakalicSenior Developer/ArchitectCommented:
I have the following code which works correctly on jdk1.2 and jdk1.3rc3 running on NT4. It creates a JDesktop with a JInternalFrame showing a single JButton which will construct and show a JDialog. The dialog will be owned/unowned depending on the value of the first command line argument being true (owned) or false (unowned). No command line argument defaults to false. When the JDialog is owned and the application is obscured by another window, using the taskbar button to bring the window to the front will bring the dialog along to the top. When the dialog is unowned, it stays behind.

---------- InternalFrameDemo.java ----------
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;

public class InternalFrameDemo extends JFrame {
    static final int xOffset = 30, yOffset = 30;
    static int openFrameCount = 0;
    JFrame owner;
    JDesktopPane desktop;
    boolean owned;

    public InternalFrameDemo(boolean ownedDialogs) {
        super("InternalFrameDemo");

        int inset = 50;
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        setBounds(inset, inset,
        screenSize.width - inset*2,
        screenSize.height-inset*2);

        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });

        desktop = new JDesktopPane();
        setContentPane(desktop);
        setJMenuBar(createMenuBar());
        createFrame();
        owned = ownedDialogs;
        owner = this;
    }

    protected JMenuBar createMenuBar() {
        JMenuBar menuBar = new JMenuBar();

        JMenu menu = new JMenu("Document");
        JMenuItem item1 = new JMenuItem("New");
        item1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                createFrame();
            }
        });
        menu.add(item1);
        menuBar.add(menu);
        return menuBar;
    }

    protected void createFrame() {
        JInternalFrame frame = new JInternalFrame("Document #" + (++openFrameCount),
            true, //resizable
            true, //closable
            true, //maximizable
            true);//iconifiable

        frame.getContentPane().setLayout(new GridBagLayout());
        frame.setSize(320,240);
        frame.setLocation(xOffset*openFrameCount, yOffset*openFrameCount);
        JButton button = new JButton("Show Dialog");
        final Frame owner = this;
        button.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    JDialog dialog;
                    if (owned) {
                        dialog = new JDialog(owner);
                    } else {
                        dialog = new JDialog();
                    }
                    dialog.setModal(true);
                    dialog.setSize(200, 200);
                    dialog.show();
                }
            });
        frame.getContentPane().add(button);
        frame.setVisible(true);

        desktop.add(frame);
        try {
            frame.setSelected(true);
        } catch (java.beans.PropertyVetoException e2) {
        }
    }

    private static void main(String[] args) {
        boolean owned = (args.length > 0 ? args[0].equals("true") : false);
        InternalFrameDemo frame = new InternalFrameDemo(owned);
        frame.show();
    }
}
---------- end ----------

Please try this. What version of Windows are you running, what version of the jdk?

Jim Cakalic
0
 
JavaTheHutAuthor Commented:
That sample code does the same thing my application does.  It DOESN'T work if I click on another application, then click on my application on the TASKBAR.  Can anyone get it working doing that?
0
 
Jim CakalicSenior Developer/ArchitectCommented:
You did try running it with an argument of "true" right? What version of Windows are you running? What version of the jdk?
0
 
JavaTheHutAuthor Commented:
- Yep
- NT4 (Service Pack 4)
- 1.2.2

Btw, I don't even have to switch to another application to create this error.  All I need to do is click on the application on the taskbar (while it's already selected).
0
 
Jim CakalicSenior Developer/ArchitectCommented:
Hmm. Very strange as I have a system running NT4/SP5 jdk1.2.2 and the demo works as I anticipated. If I run it as

        java InternalFrameDemo false
    or  java InternalFrameDemo

the problem is as you describe. Even clicking on the taskbar button when the window is at the top of the stacking order pushes the dialog behind. When it is run as

       java InternalFrameDemo true

the symptoms do not occur.
0
 
MoRsCommented:
It looks like the problem is in NT, cause my system is as Jim's ( NT4 SP5 + jdk 1.2.2) and the demo woks as expected - try to install new SP, maybe it will help - at least it will be do no harm :)
0
 
JavaTheHutAuthor Commented:
I mostly got the solution from another source, but I appreciate the help, as u answered often and fairly quickly.  Enjoy your points.
0
 
Jim CakalicSenior Developer/ArchitectCommented:
Are you able to share the solution? I'm still curious why the behavior on your system was so different than what I was experiencing.
0
 
JavaTheHutAuthor Commented:
No problem, the solution is very simple (and rather stupid on my part).  My modal JDialog took a JFrame as an arguement parameter, and I set modal(true) in the constructor, but I never called the superclass' constructor (d'oh) - super(parent, true).  Thus, the constructor was automatically calling super(), and not setting a parent to the JDialog.
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

  • 7
  • 5
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now