Как дождаться полного создания JDialog - PullRequest
0 голосов
/ 04 августа 2020

Мне нужно как-то рассчитать оконные украшения. Поэтому я переопределяю конструктор 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 {
        {
                //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 голос
/ 04 августа 2020

Мне пришлось многое предположить, чтобы создать работоспособный пример.

Вот результат вашего метода 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);
        }

    }

}
...