【问题标题】:How to change the modality of a dialog while it is visible如何在对话框可见时更改其模式
【发布时间】:2016-02-25 08:42:20
【问题描述】:

我有一个JDialog,我将其模态设置为少模型。但是,现在我需要在它可见时修改它的模态。但我知道 Swing 不允许在可见时更改对话框的模态。那么,有没有其他技巧或代码可以做到这一点?

【问题讨论】:

  • 除了按照 JavaDoc 所说的去做之外,可能没有这样的技巧,即再次隐藏和显示对话框。主要问题是:你为什么要这样做?在显示对话框之前您不知道模态吗?当对话框突然变成模态时,用户应该如何处理被某个窗口(可能也是模态)隐藏的对话框?
  • @Thomas,实际上我遇到了一种情况,其中有一个包含一个文本字段的对话框。我为此文本字段设置了默认焦点。但是,当我的对话框是模态的时,它工作正常。但是,当我的对话框是无模型的时,焦点不会在打开对话框后自动到达文本字段
  • 所以问题是对话框没有获得或失去焦点?然后我会努力解决这个问题,而不是让对话框成为模态。
  • @Thomas,对话框没有获得焦点
  • 好的,然后正如我所说,尝试解决这个问题,而不是努力解决问题(顺便说一句,您确定对话框没有获得焦点并由于其他一些组件的请求而立即失去焦点吗? )。

标签: java swing jdialog modality


【解决方案1】:

按照Javadoc 所说的做...隐藏并显示对话框。

注意:更改可见对话框的模式可能无效,直到它被隐藏然后再次显示。

所以这是一个工作示例:

public class ModalDialogTest {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame ();
                final JDialog dialog = new JDialog(frame);
                dialog.setModal(true);

                Runnable modalSwitcher = new Runnable() {
                    @Override
                    public void run() {
                        try {
                            System.out.println("Worker thread: sleeping for 5 seconds");
                            Thread.sleep(5000);
                            System.out.println("Worker thread: sleeping finished!");
                        } catch (InterruptedException ex) {
                            // this thread is not interrupted
                        }
                        SwingUtilities.invokeLater(new Runnable() {
                            @Override
                            public void run() {
                                System.out.println("ENTERING MODALSWITCHER!");

                                dialog.setModalityType(ModalityType.MODELESS);
                                dialog.setVisible(false);
                                dialog.setVisible(true);

                                System.out.println("NO LONGER MODAL!");
                            }
                        });
                    }
                };
                new Thread(modalSwitcher).start();

                System.out.println("DIALOG WILL NOW SHOW UP:");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setVisible(true);
                dialog.setVisible(true);
                System.out.println("BYE!");
            }
        });
    }
}

5 秒后,您将能够点击父 JFrame。

这是程序打印的内容:

DIALOG WILL NOW SHOW UP:
Worker thread: sleeping for 5 seconds
Worker thread: sleeping finished!
ENTERING MODALSWITCHER!
NO LONGER MODAL!
BYE!

你是否真的想在显示对话框的同时继续切换模式的做法取决于你,但从用户体验的角度来看,我不建议这样做——感觉很奇怪。

【讨论】:

    【解决方案2】:

    更新对话框并调用repaint()。如果您更改了层次结构(添加/删除了组件),请不要忘记revalidate()

    【讨论】:

    • repaint() 是否评估 Dialog.modalityType
    • 我不明白为什么这个答案被如此赞成。 repaint() 没有重新评估对话模式的效果。
    • 你甚至不能在 JDialog 上调用 revalidate()。人们是盲目地投票还是什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多