1

My Question is the same as this: How to get the size of JPanel which is not visible yet But the answered posted there doesnt work for me. Im using the BorderLayout and Prefferedsize to manage 5 panels. My aim, see the title. revalidate() validate() pack() didnt work for me. Other ideas?

Edit:

What im trying to do is a small paint program. Its build up in a simple border layout:

paint structure

and the center pane is that to draw on. But i want to draw on a picutre, with getgraphics, and then draw this picure in the paintComponent. so i have to set the size of the image to the size from the panel. And i want to prepare all this stuff, and after i call setVisible i want the panel to be ready to start drawing.

Edit 2:

Okay, my problem is half solved. I can set the size of the image after setVisible, i thought, but i had to wait a few seconds (usually 2) before the size was right. (i dont know why). Now it works with SwingUtilities.invokeLater, but also AFTER setVisible(). Isnt there any way to reach this?

Community
  • 1
  • 1
T_01
  • 1,256
  • 3
  • 16
  • 35
  • How inaccurate was the answer you got? What if you try to get it after setVisible() is called, do you get the same result? – Robin Green Nov 08 '13 at 22:41
  • My answer may have been misleading, but as explained by the other question, components have a size of 0x0 by default. The layout manager takes the min/max/pref sizes of a component and gives it a computed size. From the component itself, you cannot tell its true size until after it is displayed by the layout manager. You can only get its min/max/pref sizes. – hotforfeature Nov 08 '13 at 22:49
  • If you think you need to know the size of a component before it is visible then you have a design problem. There is no reason to know this information. If you tell us the actual problem you are trying to solve, then we can probably suggest a better approach. – camickr Nov 09 '13 at 02:15

3 Answers3

2

Get size of jpanel before setVisible() called

  • JComponent returns its Size in two cases

    1. is already visible on the screen

    2. JFrame.pack() is called, notifier for LayoutManager, pack() could be called before setVisible()

    3. (if Insets are used for coordinates) then is possible from NullLaoyut

mKorbel
  • 109,525
  • 20
  • 134
  • 319
2

If you have direct access to the main frame, you can call JFrame#pack which will validate the container hierarchy and layout all the child components, for example...

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);
        }

    }

}

Which outputs....

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]

Now, if you don't have direct access to the main window, anything you do will be purely guess work.

You could also add a ComponentListener to the component(s) you are interested and monitor their changes in size...but this then raises the question of "why?"

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
0

The default size of some Component "A" (java.awt.Component, a abstract class who many swing elements exends, JPanel is a example) that not has value setted to its dimensions inside component "B" is setted after B shows, internally. So, you can not predict how is the size before component B shows because at this time the value properties of width and height of "A" is not setted yet.

You can manually get the height and width of component "A" before show it and set in B component. Or you can use a property file to store the sizes that you need and code a Util class to access it.

Pedro Vítor
  • 191
  • 1
  • 6