关注mac osx上java7模式对话框的问题

时间:2012-09-05 09:41:11

标签: java macos swing applet modal-dialog

我一直在验证在mac osx的applet上运行的swing应用程序。

在此验证过程中,我发现模式对话框存在以下问题:

  1. 当一个对话框打开并且是setModal(true)时,它会阻止根窗口的内容,但是如果你点击根窗口的某个地方,对话框会在它下面,但它应该保留在根窗口的顶部
  2. 如果对话框有JTextInputField,即使单击它也不会获得焦点。
  3. 所以我创建了一个小程序来显示问题。你能帮我理解这里有什么问题吗?

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

    使用以上方法创建.jar文件(test.jar)。完成后,创建一个包含以下内容的html文件:

    <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>
    

    完成后,运行html文件。你会看到一个灰色背景和一个按钮的小程序。然后尝试:

    1. 单击按钮打开对话框。之后,单击灰色区域的某个位置:对话框在浏览器窗口下方,但它应保留在顶部,对吧?
    2. 单击按钮打开对话框。之后单击对话框的文本字段并尝试编写一些内容:textdialog无法获得焦点。
    3. 那么,我在这里做错了什么?有人用Mac电脑测试一下吗?

      由于

      规格:

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

      请注意:请注意,这仅在applet在浏览器上运行且仅在mac osx上运行时才会发生。

9 个答案:

答案 0 :(得分:6)

我发现了另一种解决方法。打开窗口时,显示一个选项窗格几毫秒并关闭它。它将焦点放在选项窗格上,然后返回到对话框,允许忽略该错误。

将此snipet代码添加到对话框构造函数中,它应该可以工作:

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

答案 1 :(得分:1)

你应该把一个&#34;所有者&#34; ModalDialog上的窗口。为此,您必须在ModalDialog构造函数中调用super(owner),并且可以使用parent检索组件SwingUtilities.getWindowAncestor(parent)的父窗口。

答案 2 :(得分:1)

  • 不是Mac / OSX用户,但这是关于FocusJDialog的常见问题,

  • 在运行时创建JDialog的情况下还有其他问题,

  • Focus基于来自Native OS

  • 的属性是异步的
  • 仅创建此JDialog一次,re_usecontainer用于其他操作

  • JDialog#setVisible也应该包含在invokeLater()

  • 可以Focus强制JTextField#setText(JTextField#getText())包裹在invokeLater()

  • Dialog Focus,是@camickr的一个很好的解决方法

答案 3 :(得分:1)

我确认,我在OS X上的JDK7中运行的旧applet也有同样的错误。如上所述,只有applet在浏览器中运行(ff)而不是appletviewer。

答案 4 :(得分:1)

我可以验证这是在Mountain Lion上运行的Safari 6和Firefox上的Java 1.7 Update 7+的问题。奇怪的是,早期版本的Safari在Lion上运行并不是问题,但在旧操作系统的Firefox中存在问题。由于许多applet用户都在Mac上,我非常渴望找到解决方法。我找到的一种解决方法(通过任何方式都不够)是缩小窗口然后重新打开它。 textfields / textareas然后变得可编辑。希望我们能找到一个更好的解决方案来解决这个烦人的需求。

答案 5 :(得分:1)

我在使用Safari和Firefox的Java 7更新9的Mac上遇到了同样的问题。当我打开一个包含JTextField的JDialog时,JTextField无法访问。

我确实找到了解决方案。我插入了一个延迟,从用户按下“显示对话框按钮”到执行显示按钮的代码。

例如:

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

我经历过,如果延迟时间缩短,解决方案将无效。

如果使用SwingUtilities.invokeLater代替javax.swing.Timer,则无效。也许SwingUtilities.invokeLater的延迟太短了。

答案 6 :(得分:0)

我找到了另外一个解决方法。当从JavaScript调用JDialog时,它有一个焦点。

  1. 创建一个显示对话框的applet方法
  2. 从JavaScript调用此方法。
  3. 希望,这有帮助。顺便说一句,来自Java教程的Web start示例具有相同的问题http://docs.oracle.com/javase/tutorial/uiswing/components/textfield.html

答案 7 :(得分:0)

我想使用上面的解决方法(从对话框中打开对话框),但不显示任何对话框。 这是一个不可见对话框的代码。

final JDialog dialog = new JDialog();
dialog.setUndecorated(true);
dialog.setSize(0, 0);
dialog.setModal(true);
dialog.pack();

答案 8 :(得分:0)

我找到了解决方案。

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

GetDirectory是包含JFileChooser的JDialog。

奇怪的是,所有JDialog对象都应该使用新的JFrame()作为父级进行调用,否则从一个父窗口单击会使顶级模态JDialog在zOrder中向后移动,并且不知何故它不能再设置在顶部。< / p>

我的问题与上述相同。当我从另一个JDialog创建JDialog时,新对话框出现在另一个之后。

为了使它成为顶部我已经如上所述设置了所有JDialog的父级,并且它根据预期工作。