如何等待直到JDialog完全创建

huangapple go评论82阅读模式
英文:

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);
		}

	}

}

huangapple
  • 本文由 发表于 2020年8月4日 23:17:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/63249967.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定