当前位置: 首页 > 知识库问答 >
问题:

JDialog不当行为

梁丘琛
2023-03-14
JDialog dialog = new JDialog(parent JFrame, "blabla");
dialog.setLayout(new BorderLayout());

JLabel label = new JLabel("more blabla");

dialog.getContentPane().add(label, BorderLayout.CENTER);

dialog.setSize(new Dimension(280, 80));
dialog.setLocationRelativeTo(parent JFrame);
dialog.setVisible(true);

//part of code that takes time to execute
//actually, I'm sending an email here, but it doesn't really matter what I do,
//as you will read below        

dialog.dispose();

我有上面的代码,它的用途是在执行某些代码时向用户显示消息(代码执行大约需要5-10秒,我不想让用户认为程序冻结)。

问题是,添加到对话框中的JLabel根本没有出现。确切地说,无论我在对话框中添加什么,它都不会出现。

然而,如果我将JDialog设置为modal(将true作为最后一个参数添加到上面的构造函数中),它就会出现,但是我想要执行的代码不会运行,直到对话框关闭,违背了它的目的。

由于代码在代码中的位置,将要执行的代码并不重要,我尝试将其保留为当前在上面 - 根本没有执行代码 - 对话框将显示一瞬间,但我可以看到它是空的。

我知道我可以创建一个确认窗口并说“等待10秒,代码正在执行”,但我不想这样做。

我还尝试将JDialog替换为JFrame,文本仍然不会出现。

我错过了什么?

共有1个答案

岳炎彬
2023-03-14

如果在事件调度线程(EDT)上执行长时间运行的任务,则在任务完成之前,对话框可能没有机会绘制/重新绘制自身。有关EDT的更多详细信息,请参阅Swing中的并发教程。

下面是一个利用您的代码的示例,它演示了错误的对话框:

import java.awt.BorderLayout;
import java.awt.Dimension;
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;

public class TestDialog {

    private static void createAndShowGUI() {
        final JFrame frame = new JFrame("Demo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JButton button = new JButton("Execute");
        button.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e) {
                final JDialog dialog = new JDialog((JFrame)frame, "blabla");
                dialog.setLayout(new BorderLayout());
                JLabel label = new JLabel("more blabla");
                dialog.getContentPane().add(label, BorderLayout.CENTER);

                dialog.setSize(new Dimension(280, 80));
                dialog.setLocationRelativeTo(frame);
                dialog.setVisible(true);

                try {
                    Thread.sleep(3000);
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }

                dialog.setVisible(false);
                dialog.dispose();
            }

        });

        frame.add(button);          
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

考虑通过在工作线程上执行长时间运行的任务来重构实现。例如,您可以使用SwingWorker来实现这一点。

下面是一个演示,用一个简单的工人演示了同一个对话框:

import java.awt.BorderLayout;
import java.awt.Dimension;
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.SwingWorker;

public class TestDialogWithWorker {

    private static void createAndShowGUI() {
        final JFrame frame = new JFrame("Demo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JButton button = new JButton("Execute");
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                new Worker(frame).execute();
            }

        });

        frame.add(button);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    static class Worker extends SwingWorker<Void, Void> {
        JDialog dialog;

        public Worker(JFrame parent) {
            dialog = new JDialog((JFrame) parent, "blabla");
            dialog.setLayout(new BorderLayout());
            JLabel label = new JLabel("more blabla");
            dialog.getContentPane().add(label, BorderLayout.CENTER);

            dialog.setSize(new Dimension(280, 80));
            dialog.setLocationRelativeTo(parent);
            dialog.setVisible(true);
        }

        @Override
        protected Void doInBackground() throws Exception {
            Thread.sleep(3000);
            return null;
        }

        @Override
        protected void done() {
            dialog.setVisible(false);
            dialog.dispose();

            try {
                get();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }       
}
 类似资料:
  • 特性: 可修改CSS来统一定制UI; 通过参数设置标题,高度,宽度,窗口显示的HTML内容; 一个页面同时只能显示一个窗口; 窗口显示需要指定一个页面上的对象做为窗口显示做置定位,这样窗口会出现在哪个东西的下面,就像下拉列表一样. 不能拖动(我们不需要这样的功能); 可以点击窗口之外的任意区域来关闭窗口,或是点右上角的关闭按钮. 演示地址: http://huacnlee.github.com/jdialog/

  • 主要内容:1 Java JDialog的介绍,2 Java JDialog的声明,3 Java JDialog的构造方法,4 Java JDialog的案例1 Java JDialog的介绍 JDialog控件表示一个带有边框和标题的顶级窗口,用于从用户那里获取某种形式的输入。它继承了Dialog类。 与JFrame不同,它没有最大化和最小化按钮。 2 Java JDialog的声明 我们来看一下javax.swing.JDialog类的声明。 3 Java JDialog的构造方法 方法 描述

  • 我有两个类:类jDialog和JFrame 知道如何保持jDialog运行吗?我只使用setVisible()来隐藏它,而不使用dispose();

  • 我有一个JFrame主窗口,里面有一个Register按钮,点击Register按钮,弹出JDialog窗口。 JDialog窗口有两个按钮->Register、Cancel,这两个按钮都必须做一些事情并关闭对话框窗口。 这就是我试过的。在Reg(对话框窗口)中-->btn取消:

  • 问题内容: 当我打开自定义JDialog以及关闭对话框以再次继续时,如何使我的应用程序暂停。 问题答案: 只需使用: 我通常从的构造函数中调用它。 请参阅中的Javadocs 。 http://java.sun.com/javase/6/docs/api/java/awt/Dialog.html#setModal(boolean) 这将导致执行在当前线程上阻塞,直到对话框关闭。 或者,您可以使用:

  • 问题内容: 我在应用程序中有一个JDialog作为主窗口(最初是JFrame,但它在任务栏中显示了我不想要的)。 目前我正在做: 当我单击退出按钮时: 但是该过程似乎仍然在后台徘徊 JFrame 似乎可以满足我的要求。 如何正确关闭我的应用程序? 问题答案: 你可以加 您希望程序结束的位置,也许在dispose()行之后。