首页 > 解决方案 > Java Swing 主窗口在打开对话框时自动出现在最前面

问题描述

我正在尝试制作一个 Java Swing 应用程序,其中在单击菜单栏中的 JMenu 时会打开一个 JDialog,但由于某种原因,一旦 JDialog 打开,主 JFrame 就会自动出现在前面。

我只是在 JMenu 的 MenuListener 中打开 Dialog。

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

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

这是发生问题的最小可重现示例:

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


标签: javaswingjframe

解决方案


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

但是,即使您不设置父级,我也没有看到这种行为。也许那是因为我总是在ActionListener.

因此,有趣的是,如果您不设置父级,则 theMenuListener和 an之间的行为会有所不同。ActionListener

使用时,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.


推荐阅读