英文:
How to wait until JDialog is fully created
问题
我需要计算窗口装饰的大小。所以我重写了 JDialog 的构造函数。但是当我调用 get_decoration_size() 时,有时会返回错误的值。我认为窗口创建比 get_decoration_size() 执行要晚(奇怪的是,它们都在同一线程和同一构造函数中)。所以我决定睡眠一秒钟,它起作用了,现在装饰总是有效的。
我的问题是:是否有一种方法可以“加入”到创建过程中(等待窗口通过 setVisible(true) 显示)?如果有,它必须是用来替代 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 {
        {
                //一些初始化
                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);//尝试绘制
                unsafe_sleep(1000);//如果没有这个,似乎会在setVisible(true)之前调用get_decoratoin_size()
                db.sysdecor = get_decoration_size();//尝试获取装饰
                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);
        }
}
英文:
I need to calculate window decorations somehow. So I override JDialog's constructor. But when I call get_decoration_size() it sometimes returns wrong values. And my thought was: window creates later than get_decoration_size() executes(strange, because both in same thread and in same constructor). So I decided to sleep for a second, and it worked, and now decorations always valid.
My question is: is there a way to "join" to the creating process(wait until window is shown by setVisible(true))? If so, it must be something to replace 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);
        }
}
答案1
得分: 1
以下是您要翻译的内容:
I had to assume a lot to create a runnable example.
Here's the result of your getDecorationSize method. The line didn't print until I closed the JDialog.
java.awt.Dimension[width=16,height=39]
And here's the code I used.
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, "Splash 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);
    }
}
}
英文:
I had to assume a lot to create a runnable example.
Here's the result of your getDecorationSize method. The line didn't print until I closed the JDialog.
java.awt.Dimension[width=16,height=39]
And here's the code I used.
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);
		}
	}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论