Reputation: 1359
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:
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
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
Reputation: 109815
Get size of jpanel before setVisible() called
JComponent
returns its Size
in two cases
is already visible on the screen
JFrame.pack()
is called, notifier for LayoutManager
, pack()
could be called before setVisible()
(if Insets
are used for coordinates) then is possible from NullLaoyut
Upvotes: 2
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