当整个应用程序在打开之前失去焦点时,Java模态对话框会冻结整个应用程序

时间:2018-04-23 03:40:26

标签: java swing modal-dialog freeze

执行以下步骤后,整个应用程序将被冻结,并且无法关闭模态对话框。

(这与another question有关,但这次我们有一个可重复的方案)

步骤:

  • 打开下拉列表
  • 选择" Han-Ra" (下拉列表中的最后一个值)

在此之后,尝试调整大小或关闭模式对话框将不会成功。它会再现3次中的1次(如果您通过向下箭头选择进行选择可能更容易重现,但也可以选择鼠标进行选择)

这发生在jdk 1.8(尝试1.8.0_1621.8.0_144)和jdk 1010.0.1)上,而不是在使用1.7时尝试过1.7.0_80

这是我们可以找到的最明显的情况,但是大多数模态对话框都会随机(很少)发生这种情况。 其他人有这个问题,找到了解决方法?我们会向Oracle报告,但我们对解决方法更感兴趣。

import javax.swing.*;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;

public class FreezePleeze {

    public static final Object[] ALL_THE_SINGLE_LADIES = {"Rahan", "Crao", "Naouna", "Han-ra"};

    public static void main(String[] args) {
        new FreezePleeze();
    }

    public FreezePleeze() {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JButton push_me = new JButton("Push me");
                JFrame frame = new JFrame("Mmmmm");
                JPanel containerPanel = new JPanel();
                frame.add(containerPanel);
                final JComboBox<Object> comboBox = new JComboBox<>(ALL_THE_SINGLE_LADIES);
                containerPanel.add(comboBox);
                frame.setSize(300, 300);

                comboBox.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        JDialog jDialog = new JDialog((JFrame) null, true);
                        jDialog.add(push_me);
                        if (comboBox.getSelectedIndex() == ALL_THE_SINGLE_LADIES.length - 1) {
                            jDialog.setLocationRelativeTo(frame);
                            jDialog.setSize(300, 300);
                            jDialog.setVisible(true);
                        }
                    }
                });

                comboBox.addPopupMenuListener(new PopupMenuListener() {
                    @Override
                    public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
                    }

                    @Override
                    public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
                        try {
                            Robot robot = new Robot();
                            robot.keyPress(KeyEvent.VK_WINDOWS);
                            robot.keyRelease(KeyEvent.VK_WINDOWS);
                        } catch (AWTException e1) {
                            e1.printStackTrace();
                        }
                        push_me.setText("Finished counting");
                    }

                    @Override
                    public void popupMenuCanceled(PopupMenuEvent e) {
                    }
                });
                frame.setVisible(true);
            }
        });
    }
}

1 个答案:

答案 0 :(得分:1)

我可以重现你的问题。解决方案是将正确的窗口提交给对话框的构造函数:

示例:

JDialog jDialog = new JDialog(frame, true);

或者,如果在创建对话框时没有窗口实例:

JDialog jDialog = new JDialog(FocusManager.getCurrentKeyboardFocusManager().getActiveWindow(),
                            ModalityType.APPLICATION_MODAL);
相关问题