打开对话框时,Java Swing主窗口会自动显示在最前面

问题描述

我试图创建一个Java Swing应用程序,该应用程序在单击菜单栏中的JMenu时会打开JDialog,但是由于某种原因,一旦JDialog打开,主JFrame就会自动出现在最前面。

我只是在JMenu的MenuListener中打开对话框。

@Override
public void menuSelected(MenuEvent e) {
    Dialog dialog = new Dialog();
    dialog.setVisible(true);    
}

主JFrame从此处启动:

public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
            
        @Override
        public void run() {
            Fenster hauptFenster = new Fenster();
            hauptFenster.setVisible(true);
        }
    });
}

我已经尝试在创建时在JDialog上调用toFront(),但这无济于事。

这里是出现问题的最小重现示例:

import java.awt.EventQueue;

import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.event.MenuEvent;
import javax.swing.event.MenuListener;

public class Test extends JFrame {
    
    JFrame thisFrame;
    
    public Test() {
        //GUI
        setTitle("Behaviour Test");
        setSize(350,200);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setResizable(false);
        thisFrame = this;
        
        
        //Menübar
        JMenuBar menu = new JMenuBar();
        JMenu widerstand = new JMenu("Start Dialog");
        widerstand.addMenuListener(new MenuListener() {

            @Override
            public void menuSelected(MenuEvent e) {
                TestDialog dialog = new TestDialog(thisFrame);
                dialog.setVisible(true);    
            }
            @Override
            public void menuDeselected(MenuEvent e) {
            }
            @Override
            public void menuCanceled(MenuEvent e) {
            }
            
        });

        menu.add(widerstand);
        setJMenuBar(menu);
    }
    
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            
            @Override
            public void run() {
                Test testFrame = new Test();
                testFrame.setVisible(true);
            }
        });
    }
}

class TestDialog extends JDialog {

    public TestDialog(JFrame parent) {
        setTitle("Test Dialog");
        setSize(450,300);
        super.setLocationRelativeTo(parent);
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        setResizable(false);
    }
}


解决方法

最简单的解决方案是按照我最初在注释中建议的方式设置对话框的父级(因为这是保持框架/对话框之间父级/子级关系的正常方法)。

但是,即使您没有设置父母,我也没有看到这种行为。也许是因为我一直在ActionListener中显示一个子对话框。

因此,有趣的是,如果您未设置父级,则MenuListenerActionListener的行为是不同的。

使用MenuListener时,您需要将代码包装在invokeLater()中:

import java.awt.*;
import java.awt.EventQueue;

import javax.swing.*;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.event.MenuEvent;
import javax.swing.event.MenuListener;

public class Test extends JFrame {

    JFrame thisFrame;

    public Test() {
        //GUI
        setTitle("Behaviour Test");
        setSize(350,200);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setResizable(false);
        thisFrame = this;


        JMenuBar menu = new JMenuBar();
        JMenu widerstand = new JMenu("Start Dialog");
        widerstand.addMenuListener(new MenuListener() {

            @Override
            public void menuSelected(MenuEvent e) {

                SwingUtilities.invokeLater(new Runnable()
                {
                    public void run()
                    {
                        TestDialog dialog2 = new TestDialog(thisFrame);
                        dialog2.setVisible(true);
                    }
                });
            }
            @Override
            public void menuDeselected(MenuEvent e) {
            }
            @Override
            public void menuCanceled(MenuEvent e) {
            }

        });

        menu.add(widerstand);
        setJMenuBar(menu);

        JButton button = new JButton("Display Dialog");
        add(button);
        button.addActionListener((e) ->
        {
            TestDialog dialog2 = new TestDialog(thisFrame);
            dialog2.setVisible(true);
        });
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                Test testFrame = new Test();
                testFrame.setVisible(true);
            }
        });
    }
}

class TestDialog extends JDialog {

    public TestDialog(JFrame parent) {
        setTitle("Test Dialog");
        setSize(450,300);
        setLocationRelativeTo(parent);
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        setResizable(false);
    }
}

使用ActionListener可以正常工作。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...