1

我的问题与此相同: 如何获得尚不可见的 JPanel 的大小 但是那里发布的答案对我不起作用。我使用 BorderLayout 和 Prefferedsize 来管理 5 个面板。我的目标,见标题。revalidate() validate() pack() 对我不起作用。其他想法?

编辑:

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

油漆结构

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

编辑2:

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

4

3 回答 3

2

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

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]

现在,如果您无法直接访问主窗口,那么您所做的任何事情都只是猜测。

您还可以将 a 添加ComponentListener到您感兴趣的组件中并监视它们的大小变化......但这会引发“为什么?”的问题。

于 2013-11-08T23:19:16.917 回答
2

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

  • JComponentSize在两种情况下 返回它

    1. 已经在屏幕上可见

    2. JFrame.pack()被调用,通知器LayoutManagerpack()可以在之前调用setVisible()

    3. (如果Insets用于坐标)则可以从NullLaoyut

于 2013-11-08T23:12:05.753 回答
0

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

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

于 2013-11-08T23:04:35.380 回答