T_01
T_01

Reputation: 1359

Get size of jpanel before setVisible() called

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?

Upvotes: 1

Views: 5450

Answers (3)

MadProgrammer
MadProgrammer

Reputation: 347184

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?"

Upvotes: 2

mKorbel
mKorbel

Reputation: 109815

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

Upvotes: 2

Pedro Vítor
Pedro Vítor

Reputation: 191

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.

Upvotes: 0

Related Questions