在Swing中修改模态对话框的父级

时间:2017-10-25 01:35:11

标签: java macos swing dialog modal-dialog

我遇到了一个模式对话框的错误我正在使用Java 8u151 / 8u152,这在8u112中不是问题,而且我不确定我是否在做一些固有的错误,或者这是否是一个JRE错误。这只影响Mac OS,据我所知(我正在运行OS 10.12.6),所以虽然我的问题不是特定于Mac的,如果你不是Mac,你将无法观察到这个bug用户。

我创建了一个模式对话框,主JFrame作为其父级。然后我创建一个新的模态对话框,我从对话框#1创建。将对话框#2的父级设置为主JFrame也是错误的吗?或者必须是对话#2?

问另一种方法:如果两个对话框共享同一个父对象(主JFrame),但最后创建了对话框#2,那么期望对话框#2应该位于顶部,还是未定义的行为是否合理?

使用8u112,对话框#2聚焦并位于顶部。对于8u151,对话框#2聚焦但落后。如果我点击任一对话框,对话框#2会抓住焦点并且似乎在大多数情况下表现得恰到好处。但是,有时对话框#2将保留在其他应用程序之上(我相信如果我点击主窗口,然后返回模态对话框就会发生这种情况......这部分肯定是个错误。)

注意:对于Java 8u121到(我认为)8u144,在8u152中应该修复的模态对话框存在其他问题(几个月前我记录了一个错误报告并检查了早期访问构建,事情确实如此然后修好了。

一些示例代码来说明我正在做的事情:

import javax.swing.*;
import java.awt.*;

public class Main extends JFrame {
    MyPanel panel;

    public Main() {
        setTitle("This is a frame");
        setSize(300, 200);
        panel = new MyPanel(this);
        add(panel);

        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            Main frame = new Main();
            frame.pack();
            frame.setVisible(true);
        });
    }

    private static class MyPanel extends JPanel {

        int dialogCounter = 1;
        final JFrame theParent;

        public MyPanel(JFrame parent) {
            super();
            theParent = parent;
            setPreferredSize(new Dimension(300, 200));
            JButton button = new JButton("Press the button");
            button.addActionListener(e -> showDialog(theParent));

            add(button);
        }

        private void showDialog(Frame parent) {
            JDialog dialog = new JDialog(parent, "This is dialog " + dialogCounter, true);
            setupDialog(dialog);
        }

        private void setupDialog(JDialog dialog) {
            JPanel dialogPanel = new JPanel();
            dialogPanel.setPreferredSize(new Dimension(300, 200));
            dialogPanel.add(new JLabel("Current dialog count: " + dialogCounter++));
            JButton button = new JButton("Open a new modal dialog");
            button.addActionListener(e -> showDialog(theParent));
            dialogPanel.add(button);
            dialog.add(dialogPanel);
            dialog.pack();
            dialog.setVisible(true);
        }
    }
}

1 个答案:

答案 0 :(得分:1)

这是8u151中引入的错误。它已经修复,应该向后移植到下一个OpenJDK 8更新版本。 以下是您可以使用的解决方法:

    dialog.addWindowListener(new WindowAdapter() {
        @Override
        public void windowOpened(WindowEvent e) {
            dialog.removeWindowListener(this);
            dialog.toFront();
        }
    });