11

我有一个模式设置对话框,它是一个 JDialog。在这个设置窗口中,我放置了一些组件,包括一个指向另一个模态设置对话框的按钮,该对话框也是一个 JDialog。我将它们制作为 JDialogs,因为这是我所知道的制作模态对话框的唯一方法。

问题是这样的:当我创建主设置对话框时,我必须在没有父框架或父框架的情况下构建 JDialog。由于我的主窗口是一个 JFrame,我可以将它传递给主设置对话框构造函数。但是当我想创建第二个模式设置对话框时,它应该将主设置对话框作为父级,我找不到获取 JDialog 的 (J)Frame 的方法。我确实想将该主设置对话框作为父级传递,以便第二个设置对话框在显示时以它为中心。假设第二个设置对话框没有用于传递位置的构造函数,只有 JDialog 的构造函数。

有没有办法获得 JDialog 的 (J)Frame?我的设置中是否存在设计缺陷,我是否应该为这些设置对话框使用其他东西?(如果是这样,我应该如何使这些替代设置对话框成为模态?)

谢谢你的帮助,埃里克

更新:谢谢大家的回答。他们让我明白,显然拥有一个 JDialog 的所有者并不是绝对必要的。我认为对话框需要这样做才能禁用所有者,直到对话框关闭,但显然该模式独立于所有者。我还注意到,即使有所有者,对话框仍然不会以所有者为中心,所以现在我的代码如下:

public class CustomDialog extends JDialog {
    public CustomDialog(String title) {
        setModal(true);
        setResizable(false);
        setTitle(title);

        buildGUI();
    }

    public Result showDialog(Window parent) {
        setLocationRelativeTo(parent);
        setVisible(true);
        return getResult();
    }
}

这也允许模态对话框中的模态对话框。

感谢你的帮助!

4

3 回答 3

14

不确定您到底有什么问题,但这里有一个关于如何拥有多个模式对话框的示例:

import java.awt.BorderLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class TestDialog {

    protected static void initUI() {
        JPanel pane = newPane("Label in frame");
        JFrame frame = new JFrame("Title");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(pane);
        frame.pack();
        frame.setVisible(true);

    }

    public static JPanel newPane(String labelText) {
        JPanel pane = new JPanel(new BorderLayout());
        pane.add(newLabel(labelText));
        pane.add(newButton("Open dialog"), BorderLayout.SOUTH);
        return pane;
    }

    private static JButton newButton(String label) {
        final JButton button = new JButton(label);
        button.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                Window parentWindow = SwingUtilities.windowForComponent(button);
                JDialog dialog = new JDialog(parentWindow);
                dialog.setLocationRelativeTo(button);
                dialog.setModal(true);
                dialog.add(newPane("Label in dialog"));
                dialog.pack();
                dialog.setVisible(true);
            }
        });
        return button;
    }

    private static JLabel newLabel(String label) {
        JLabel l = new JLabel(label);
        l.setFont(l.getFont().deriveFont(24.0f));
        return l;
    }

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

            @Override
            public void run() {
                initUI();
            }
        });
    }
}
于 2012-06-25T14:14:02.890 回答
5

1.请阅读Java SE 6 中的新模式 API

2.有没有办法获取JDialog的(J)Frame?

Window ancestor = SwingUtilities.getWindowAncestor(this);

或者

Window ancestor = (Window) this.getTopLevelAncestor();
于 2012-06-25T14:03:33.613 回答
1

现在是 2021 年,距离问题发布大约 8.5 年,但早在 2012 年,到目前为止,最简单的解决方案是简单地JDialogDialog所有者身份创建。Java 提供了5 个带有 Dialog 所有者的构造函数,旁边有 5 个具有所有者的类似构造函数和 5 个Frame具有所有者的构造函数Window

OP 可能面临的问题是JDialogNetbeans 或其他 IDE 中的默认模板。Netbeans (12.2) 将此作为新JDialog 表单的模板...

public class NewJDialog extends javax.swing.JDialog {

    /**
     * Creates new form NewJDialog
     */
    public NewJDialog(java.awt.Frame parent, boolean modal) {
        super(parent, modal);
        initComponents();
    }

您可以简单地更改构造函数的签名以使用 aDialog作为所有者而不是 a 的默认选项Frame

public class NewJDialog extends javax.swing.JDialog {

    /**
     * Creates new form NewJDialog
     */
    public NewJDialog(java.awt.Dialog parent, boolean modal) {
        super(parent, modal);
        initComponents();
    }

你走了。

于 2021-01-18T04:57:12.067 回答