Java 在调用setVisible()之前获取jpanel的大小

Java 在调用setVisible()之前获取jpanel的大小,java,swing,layout,size,Java,Swing,Layout,Size,我的问题与此相同: 但是贴在那里的答案对我不起作用。Im使用BorderLayout和PreferedSize管理5个面板。我的目标,看标题。revalidate()validate()pack()对我不起作用。 其他想法 编辑: 我想做的是一个小的绘画程序。它以简单的边框布局构建: 中间的窗格是用来绘制的。但是我想用getgraphics在图片上画画,然后在paintComponent中画这个图片。 因此,我必须将图像的大小设置为面板的大小。我想准备所有这些东西,在调用setVisible之

我的问题与此相同: 但是贴在那里的答案对我不起作用。Im使用BorderLayout和PreferedSize管理5个面板。我的目标,看标题。revalidate()validate()pack()对我不起作用。 其他想法

编辑:

我想做的是一个小的绘画程序。它以简单的边框布局构建:

中间的窗格是用来绘制的。但是我想用getgraphics在图片上画画,然后在paintComponent中画这个图片。 因此,我必须将图像的大小设置为面板的大小。我想准备所有这些东西,在调用setVisible之后,我想让面板准备好开始绘图

编辑2:

好吧,我的问题解决了一半。我想,我可以在setVisible之后设置图像的大小,但我必须等待几秒钟(通常为2秒钟)才能确定大小。(我不知道为什么)。现在它可以与SwingUtilities.invokeLater一起使用,但也可以在setVisible()之后使用。
有没有办法做到这一点?

某些组件“A”(java.awt.Component,一个抽象类,有许多swing元素exends,JPanel就是一个例子)的默认大小在组件“B”中没有设置为其维度的值,在B显示之后,在内部设置。因此,您无法预测组件B显示之前的大小,因为此时“A”的宽度和高度的值属性尚未设置


您可以在显示组件“A”之前手动获取其高度和宽度,并在B组件中进行设置。或者,您可以使用属性文件来存储所需的大小,并编写一个Util类来访问它。

某些组件“a”(java.awt.Component,一个抽象类,有许多swing元素exends,JPanel就是一个例子)的默认大小在组件“B”中没有设置为其维度的值,在内部显示B之后设置。因此,您无法预测组件B显示之前的大小,因为此时“A”的宽度和高度的值属性尚未设置

您可以在显示组件“A”之前手动获取其高度和宽度,并在B组件中进行设置。或者,您可以使用属性文件来存储所需的大小,并编写一个Util类来访问它

在调用setVisible()之前获取jpanel的大小

  • JComponent
    在两种情况下返回其
    Size

  • 已在屏幕上显示

  • 调用
    JFrame.pack()
    ,可以在
    setVisible()之前调用
    LayoutManager的通知程序

  • (如果
    Insets
    用于坐标),则可以从
    NullLaoyut

在调用setVisible()之前获取jpanel的大小

  • JComponent
    在两种情况下返回其
    Size

  • 已在屏幕上显示

  • 调用
    JFrame.pack()
    ,可以在
    setVisible()之前调用
    LayoutManager的通知程序

  • (如果
    Insets
    用于坐标),则可以从
    NullLaoyut


如果您可以直接访问主框架,您可以调用
JFrame#pack
,这将验证容器层次结构和所有子组件的布局,例如

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;

public class BeforeVisible {

    public static void main(String[] args) {
        new BeforeVisible();
    }

    public BeforeVisible() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                TestPane center = new TestPane(100, 100);
                frame.add(center);
                frame.add(new TestPane(100, 50), BorderLayout.NORTH);
                frame.add(new TestPane(100, 50), BorderLayout.SOUTH);
                frame.add(new TestPane(50, 100), BorderLayout.EAST);
                frame.add(new TestPane(50, 100), BorderLayout.WEST);

                System.out.println("Size beofre pack = " + frame.getSize() + "; " + center.getSize());

                frame.pack();

                System.out.println("Size after pack = " + frame.getSize() + "; " + center.getSize());

                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private int pWidth, pHeight;

        public TestPane(int width, int height) {
            pWidth = width;
            pHeight = height;
            setBorder(new LineBorder(Color.RED));
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(pWidth, pHeight);
        }

    }

}
哪个输出

Size beofre pack = java.awt.Dimension[width=0,height=0]; java.awt.Dimension[width=0,height=0]
Size after pack = java.awt.Dimension[width=200,height=222]; java.awt.Dimension[width=100,height=100]
现在,如果您不能直接访问主窗口,那么您所做的一切都将是纯粹的猜测工作


您还可以向感兴趣的组件添加一个或多个组件,并监视它们的大小变化……但这会引发一个问题“为什么?”

如果您可以直接访问主框架,您可以调用
JFrame#pack
,它将验证容器层次结构并布局所有子组件,例如

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;

public class BeforeVisible {

    public static void main(String[] args) {
        new BeforeVisible();
    }

    public BeforeVisible() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                TestPane center = new TestPane(100, 100);
                frame.add(center);
                frame.add(new TestPane(100, 50), BorderLayout.NORTH);
                frame.add(new TestPane(100, 50), BorderLayout.SOUTH);
                frame.add(new TestPane(50, 100), BorderLayout.EAST);
                frame.add(new TestPane(50, 100), BorderLayout.WEST);

                System.out.println("Size beofre pack = " + frame.getSize() + "; " + center.getSize());

                frame.pack();

                System.out.println("Size after pack = " + frame.getSize() + "; " + center.getSize());

                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private int pWidth, pHeight;

        public TestPane(int width, int height) {
            pWidth = width;
            pHeight = height;
            setBorder(new LineBorder(Color.RED));
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(pWidth, pHeight);
        }

    }

}
哪个输出

Size beofre pack = java.awt.Dimension[width=0,height=0]; java.awt.Dimension[width=0,height=0]
Size after pack = java.awt.Dimension[width=200,height=222]; java.awt.Dimension[width=100,height=100]
现在,如果您不能直接访问主窗口,那么您所做的一切都将是纯粹的猜测工作


您也可以在感兴趣的组件中添加一个或多个,并监控其大小变化……但这会引发一个问题:“为什么?”

您得到的答案有多不准确?如果在调用setVisible()后尝试获取它,会得到相同的结果吗?我的回答可能有误导性,但正如另一个问题所解释的,默认情况下组件的大小为0x0。布局管理器将获取零部件的最小/最大/首选尺寸,并为其提供计算尺寸。只有在布局管理器显示构件后,才能从构件本身判断其真实尺寸。您只能获取组件的最小/最大/首选大小。如果您认为在组件可见之前需要知道其大小,则存在设计问题。没有理由知道这些信息。如果你告诉我们你试图解决的实际问题,那么我们可能会建议一个更好的方法。你得到的答案有多不准确?如果在调用setVisible()后尝试获取它,会得到相同的结果吗?我的回答可能有误导性,但正如另一个问题所解释的,默认情况下组件的大小为0x0。布局管理器将获取零部件的最小/最大/首选尺寸,并为其提供计算尺寸。只有在布局管理器显示构件后,才能从构件本身判断其真实尺寸。您只能获取组件的最小/最大/首选大小。如果您认为在组件可见之前需要知道其大小,则存在设计问题。没有理由知道这些信息。如果您告诉我们您试图解决的实际问题,那么我们可能会建议更好的方法。请解释?您是否有测试/尝试执行的示例代码?解释?您是否有测试/尝试执行的示例代码?