如何等到 JDialog 完全创建

How to wait until JDialog is fully created

我需要以某种方式计算 window 装饰。所以我覆盖了 JDialog 的构造函数。但是当我调用 get_decoration_size() 时,它有时会 returns 错误的值。我的想法是:window 创建晚于 get_decoration_size() 执行(奇怪,因为两者都在同一个线程和同一个构造函数中)。所以我决定睡一秒钟,它起作用了,现在装饰总是有效的。

我的问题是:有没有办法“加入”创建过程(等到setVisible(true)显示window)?如果是这样,那一定是用来代替 unsafe_sleep(1000).

的东西
package swing.window;

import db.db;

import javax.swing.*;
import java.awt.*;

import static swing.util.*;
import static util.util.unsafe_sleep;

public class calc_decor extends JDialog {
        {
                //some initializations
                setLayout(null);
                setResizable(false);
                JLabel label = new JLabel("Loading...");
                add(label);
                setxy(label, 3, 3);
                fit(label);
                setsize(this, label.getWidth() + 100, label.getHeight() + 100);
                window_to_center(this);

                setVisible(true);//trying to draw

                unsafe_sleep(1000);//without that it looks like get_decoratoin_size()
                                   //is called before setVisible(true)

                db.sysdecor = get_decoration_size();//trying to get decorations
                dispose();
        }

        private Dimension get_decoration_size() {
                Rectangle window = getBounds();
                Rectangle content = getContentPane().getBounds();
                int width = window.width - content.width;
                int height = window.height - content.height;
                return new Dimension(width, height);
        }
}

我不得不假设很多来创建一个可运行的示例。

这是您的 getDecorationSize 方法的结果。直到我关闭 JDialog 才打印出该行。

java.awt.Dimension[width=16,height=39]

这是我使用的代码。

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
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 JDialogTest implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new JDialogTest());
    }

    private JFrame frame;

    @Override
    public void run() {
        frame = new JFrame("JDialog Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.add(createMainPanel());

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

    private JPanel createMainPanel() {
        JPanel panel = new JPanel(new BorderLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(
                150, 100, 150, 100));
        panel.setPreferredSize(new Dimension(400, 400));

        JButton button = new JButton("Open JDialog");
        button.addActionListener(new ButtonListener());
        panel.add(button);

        return panel;
    }

    public class ButtonListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            new CalculateDecor(frame, "Spash Screen");
        }

    }

    public class CalculateDecor extends JDialog {

        private static final long serialVersionUID = 1L;

        public CalculateDecor(JFrame frame, String title) {
            super(frame, true);
            setDefaultCloseOperation(DISPOSE_ON_CLOSE);
            setTitle(title);

            JPanel panel = new JPanel(new BorderLayout());
            panel.setPreferredSize(new Dimension(200, 200));

            JLabel label = new JLabel("Loading...");
            label.setHorizontalAlignment(JLabel.CENTER);
            panel.add(label);

            add(panel);
            pack();
            setLocationRelativeTo(frame);
            setVisible(true);

            System.out.println(getDecorationSize());
        }

        private Dimension getDecorationSize() {
            Rectangle window = getBounds();
            Rectangle content = getContentPane().getBounds();
            int width = window.width - content.width;
            int height = window.height - content.height;
            return new Dimension(width, height);
        }

    }

}