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

时间:2013-11-08 22:35:00

标签: java swing layout size

我的问题与此相同: How to get the size of JPanel which is not visible yet 但那里发布的答案对我来说不起作用。我使用BorderLayout和Prefferedsize来管理5个面板。我的目标,看标题。 revalidate()validate()pack()对我没用。 其他想法?

编辑:

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

paint structure

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

编辑2:

好的,我的问题已经解决了一半。我想,我可以在setVisible之后设置图像的大小,但是我必须在大小合适之前等待几秒钟(通常是2秒)。 (我不知道为什么)。现在它适用于SwingUtilities.invokeLater,但也适用于setVisible()。 没有办法达到这个目标吗?

3 个答案:

答案 0 :(得分:2)

如果您可以直接访问主框架,则可以调用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]

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

您还可以向感兴趣的组件添加ComponentListener并监控其大小的变化......但这会引发“为什么?”的问题。

答案 1 :(得分:1)

  

在setVisible()调用

之前获取jpanel的大小
  • JComponent在两种情况下返回Size

    1. 已在屏幕上显示

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

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

答案 2 :(得分:0)

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

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