8

I've been validating a swing application that runs on an applet for mac osx.

During this validation I found the following issues with the modal dialogs:

  1. When a dialog is open and is setModal(true) it blocks the content of the root window, but if you click somewhere on the root window, the dialog goes under it, but it should remain on the top of the root window.
  2. If the dialog has a JTextInputField it does not receive focus even when you click on it.

So I created a small program to show the problem. Can you please help me to understand what is wrong here?

package com.macosx.tests;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class DialogExample extends JApplet{

    private static final long serialVersionUID = 1L;
    private JPanel panel;
    private JButton openDialogBtn;

    private void doStart() {
        panel = new JPanel();
        panel.setPreferredSize(new Dimension(500,500));

        openDialogBtn = new JButton("open dialog");
        openDialogBtn.addActionListener(new ActionListener(){

            @Override
            public void actionPerformed(ActionEvent arg0) {
                ModalDialog dialog = new ModalDialog(panel, true);
                dialog.setVisible(true);
            }

        });
        panel.add(openDialogBtn);
        setContentPane(panel);
    }


    class ModalDialog extends JDialog {
        private static final long serialVersionUID = 1L;

        public ModalDialog(Component parent, boolean modal) {
            Dimension dimensionParentFrame = parent.getSize();
            setSize(new Dimension((parent == null) ? 300 : dimensionParentFrame.width / 2, 75));

            setModal(modal);
            setModalityType(ModalityType.APPLICATION_MODAL);

            JTextField txtField = new JTextField();
            add(txtField, BorderLayout.CENTER);
        }
    }


    @Override
    public void start() {
        try {
            SwingUtilities.invokeAndWait(new Runnable() {
                public void run() {
                    doStart();
                }
            });
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}

Use the above to create a .jar file (test.jar). Once that is done, create a html file with the following content:

<html>
<head>
<title>Dialog test Applet</title>
</head>
<body>
<applet id="DialogTestApplet" height="800" width="600"
  code="com.macosx.tests.DialogExample"
  archive="test.jar">
</applet>
</div>
</body>
</html>

When this is done, run the html file. You'll see an applet with a gray background and with a button. Then try to:

  1. click on the button to open the dialog. After that, click somewhere on the gray area: the dialog goes under the browser window but it should remain on the top, right?
  2. click on the button to open the dialog. After that click on the textfield of the dialog and try to write something: the textdialog does not receive focus.

So, what am I doing wrong here? Can someone with a mac computer test this please?

Thanks

Specs:

java.vendor    Oracle Corporation
java.version   1.7.0_07
os.name        Mac OS X
os.version     10.7.4

browser        firefox 15

NOTE: please note that this is only happening when the applet runs on the browser and only on mac osx.

Luis Gonçalves
  • 249
  • 2
  • 10
  • Unable to reproduce on 10.5/1.6. – trashgod Sep 05 '12 at 11:23
  • For me, using 10.7/1.6.0_33 I still see the modal problem(1) but not the focus problem(2). – Luis Gonçalves Sep 05 '12 at 11:31
  • Similar problem but on ubuntu [stackoverflow](http://stackoverflow.com/questions/12373140/java-applet-jtextfield-inaccesible-after-jdialog-on-ubuntu). – user1307657 Sep 12 '12 at 08:42
  • I reported this bug last weeks, but I only mention mac osx. Check it here: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7196264. Maybe you should vote / comment to see if they do something about it. The priority is low because they changed it... – Luis Gonçalves Sep 13 '12 at 11:02
  • Good News!. I just entered the link of the bug in oracle. They related to other open issue they have [8001161](http://bugs.sun.com/view_bug.do?bug_id=8001161) This issue is solved and will be available at 7u14 which is coming soon. – Amos N. Feb 13 '13 at 13:55
  • all these bugs only seem to relate to the focus problem, but for me the most important problem is that the dialog opens behind the browser (the JFileChooser). is that the same bug? – Nicolas Mommaerts Apr 05 '13 at 18:35

9 Answers9

6

I found another workaround. When the window is opened, show an optionpane for a few milliseconds and close it. It give the focus to the optionpane and then back to the dialog, allowing to ignore the bug.

Add this snipet of code to your dialog constructor and it should work:

addWindowListener(new WindowAdapter(){
public void windowOpened(WindowEvent e){
    JOptionPane pane = new JOptionPane();
    final JDialog dialog = pane.createDialog("Please Wait");
    Timer timer = new Timer(50, new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            dialog.dispose();
        }
    });
timer.setRepeats(false);
timer.start();
dialog.setVisible(true);
}
user1306322
  • 8,561
  • 18
  • 61
  • 122
  • 2
    You may try invisible dialog: `final JDialog dialog = new JDialog(); dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); dialog.setUndecorated(true); dialog.setModal(true);` – xmedeko Mar 11 '14 at 12:24
1

You should put an "owner" window on your ModalDialog. To do that, you must call super(owner) in your ModalDialog constructor and you can retrieve the parent window of your component parent with SwingUtilities.getWindowAncestor(parent).

Guillaume Polet
  • 47,259
  • 4
  • 83
  • 117
  • Thanks for your suggestion. I just tried what you mentioned but the result was the same... – Luis Gonçalves Sep 05 '12 at 10:14
  • @LuisGonçalves try to post an [SSCCE](http://sscce.org) without having to use an applet. – Guillaume Polet Sep 05 '12 at 10:36
  • why dont you just copy that code to Eclipse, for example, and select Run As -> Java Applet. That will run the applet and you will see it running. But as I mentioned in the note: this problem only happens when we run the applet on the browser which is exactly how I'm interested in make it work. – Luis Gonçalves Sep 05 '12 at 11:02
1
  • not Mac/OSX user but this is common issue about Focus and JDialog,

  • there are another issues in the case that JDialog is created on Runtime,

  • Focus is asynchronous based on properties came from Native OS

  • create this JDialog only once time and re_use this container for another action

  • JDialog#setVisible should be wrapped into invokeLater() too

  • is possible to force the Focus by JTextField#setText(JTextField#getText()) wrapped into invokeLater()

  • there is Dialog Focus, one of great workaround by @camickr

mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • I'm gonna do some code changes to include dos suggestions to see if any of them solve the problems. Just to mention that if you run the same code on windows, none of the problems occur. – Luis Gonçalves Sep 05 '12 at 11:39
  • @Luis Gonçalves this common issue is presented in most complex GUI on Win, **nix and OSX platforms too, only hacks can help you – mKorbel Sep 05 '12 at 11:41
  • Did you actually run that on Windows?! Cause, I see none of the problems if I run it on my windows machine... – Luis Gonçalves Sep 05 '12 at 11:54
  • partially agree with only one `JComponents` in the container, but I'm talking about most complex GUI (please read carefully description in linked code by `camickr`), GUI that contains bunch of `JComponents` and you needed to `setFocus` to some of `JTextField` or `JButton`, by default 1st. JComponent is fosusable, important clue is if `JTextField#setText(JTextField#getText())` or `AncesorListener` works, because this issue came from `Java5` – mKorbel Sep 05 '12 at 12:02
  • If that is for complex GUI, why is not working for this small example? To be honest I think this is a bug in the JRE7 for mac os x. For example, I tried the example Camickr gives with the JOptionPane. He says: 'In this case, if you run the above code you will notice that focus is on the “Yes” button'. This is true ONLY if you run the applet OUT of the browser. When you run the applet on the browser, none of the components of the created dialog as focus. – Luis Gonçalves Sep 05 '12 at 12:28
  • 1) have look to Sun BugParade, in the case that none of above suggestions doeasn't works, 2) and there are another issue, most of lacks are about used Look and Feel, 3) are you tried to change quaua to systemLookAndFeel or MetalLookAndFeel, sure those lacks are Bugs related too :-) – mKorbel Sep 05 '12 at 12:38
1

I confirm, I have the same bug with an old applet running in JDK7 on OS X. As the poster mentioned, the bug is seen only with the applet running in the browser (ff) and not with the appletviewer.

Michaël
  • 3,679
  • 7
  • 39
  • 64
Yves G.
  • 11
  • 1
  • Thanks for report that. By the way, can you have a look in http://stackoverflow.com/questions/12180557/swing-menus-java-7-mac-osx. I also created that one which seems a bug. Do you confirm that? – Luis Gonçalves Sep 25 '12 at 13:26
1

I can verify that this is a problem for Java 1.7 Update 7+ on the Safari 6 and Firefox running on Mountain Lion. Curiously it is not a problem on earlier versions of Safari that run on Lion but it is a problem in Firefox on the older OS. I am pretty desperate to find a fix for this as a number of my applet users are on Macs. One workaround that I have found (that is not sufficient by any means) is to minify the window and then reopen it. The textfields/textareas then become editable. Hopefully, we can find a better solution that gets around this annoying requirement.

1

I experienced the same problem on Mac with Java 7 update 9 with Safari and Firefox. When I opened a JDialog which contained a JTextField the JTextField was inaccessible.

I did find a solution. I inserted a delay from when the user pressed the “show dialog button” to executing the code that shows the button.

For example:

ActionListener al = new ActionListener(){
    public void actionPerformed(ActionEvent ae){
        TitleDialog dialog = new TitleDialog(main.findParentFrame()); // My JDialog which contains a JTextField.
        dialog.setVisible(true);
    }
};
javax.swing.Timer timer = new javax.swing.Timer(1000, al);
timer.setRepeats(false);
timer.start(); 

I experienced that if the delay was to short the solution would not work.

If one uses SwingUtilities.invokeLater instead of javax.swing.Timer it will not work. Maybe the delay of SwingUtilities.invokeLater is too short.

Alexis Pigeon
  • 7,423
  • 11
  • 39
  • 44
NINI
  • 11
  • 1
0

I found one more workaround. When JDialog is invoked from JavaScript it has a focus.

  1. Create an applet's method which will show a dialog
  2. Call this method from JavaScript.

Hope, it helps. By the way, web start samples from Java tutorial have the same issue http://docs.oracle.com/javase/tutorial/uiswing/components/textfield.html

Tanya Vybornova
  • 551
  • 1
  • 6
  • 15
0

I want to use the workaround above (to open dialog from the dialog), but without showing any dialog. Here is a code for not visible dialog.

final JDialog dialog = new JDialog();
dialog.setUndecorated(true);
dialog.setSize(0, 0);
dialog.setModal(true);
dialog.pack();
Amos N.
  • 627
  • 10
  • 16
0

I have found a solution.

GetDirectory varGetDirectory = new GetDirectory(new JFrame(),true);
varGetDirectory.setVisible(true);       

GetDirectory is JDialog containing a JFileChooser.

The weird thing is that all JDialog object should be called using new JFrame() as parent, otherwise clicking from one parent window, will bring the top modal JDialog backwards in the zOrder and somehow it cannot be set on top anymore.

My problem was the same as above. When I have created the JDialog from another JDialog, the new dialog appeared behind the other.

To bring it to top I have set the parent of all JDialogs as described above and it worked according to what expected.

Endre Olah
  • 875
  • 2
  • 9
  • 25