【问题标题】:Get size of jpanel before setVisible() called在调用 setVisible() 之前获取 jpanel 的大小
【发布时间】:2013-11-21 02:15:38
【问题描述】:

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

编辑:

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

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

编辑 2:

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

【问题讨论】:

  • 您得到的答案有多不准确?如果在调用 setVisible() 之后尝试获取它,会得到相同的结果吗?
  • 我的回答可能具有误导性,但正如另一个问题所解释的,默认情况下组件的大小为 0x0。布局管理器获取组件的最小/最大/首选尺寸,并为其提供计算尺寸。从组件本身来看,直到布局管理器显示它之后,您才能知道它的真实大小。您只能获取其最小/最大/首选尺寸。
  • 如果您认为需要在组件可见之前知道它的大小,那么您就有了设计问题。没有理由知道这些信息。如果您告诉我们您要解决的实际问题,那么我们可能会提出更好的方法。

标签: java swing layout size


【解决方案1】:

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

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

    1. 已经在屏幕上可见

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

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

【讨论】:

    【解决方案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 添加到您感兴趣的组件并监控它们的大小变化......但这会引发“为什么?”的问题

    【讨论】:

    • 解释一下?你有你测试/尝试做的示例代码吗?
    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 2011-12-04
      • 1970-01-01
      • 2012-06-19
      • 2016-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多