Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Swing getSize() returns inaccurate value?

To put this most simply, I am trying to use the width of a component to set the size of its parent container. However the width being returned for the component is off by about 4 pixels.

More details: I have a dialog that has sub-panels spreading horizontally across the middle of it. The dialog should always be as wide as this list of sub panels, and use a scroll bar once the list gets too long. I tried it just using 1 sub-panel though to start. No matter what I do, the size of the sub-panel being returned is always wrong by about 4 pixels. I can see just a very annoying 4-pixel gap to the right of my sub-panel making my dialog look ghastly. The effect obviously compounds as more sub-panels are added.

What I have tried using to get the width:

sup-panel.getSize().width;
sub-panel.getBounds().width;
sub-panel.getWidth();
sub-panel.getPreferredSize().width;

All return the same wrong value.

Other things I have tried calling to make it behave:

parent.validate();
parent.repaint();
parent.doLayout();

Any help would be appreciated. Is it intentional? Am I missing some concept behind sizes? It seems consistent, but it would be nice if I could read somewhere that this is documented.

FYI: I am using java 1.3 (supporting a legacy app)

NOTE: This is not an issue getting the window to resize, that part is happening just fine. And the size of the sub-panels appears to be properly set as changes to it's size are reflected in the values returned for my code. The values are just always off slightly.

NOTE2: calling pack() on the parent container makes the window look like I want it to, but it will not work for all scenarios for me because eventually after enough sub-panels are present a scroll bar will need to be present. pack() will simply make my dialog super wide in this case and make the scroll bar useless.

EDIT: I have solved my problem. Rather embarrassingly all of my sub-panels were not of a uniform width as they should have been. There are 2 solutions that work. Force them all to be uniform, which can be tricky depending how good you are with layouts. The other is to sum up the individual widths of the first n panels I want to be visible. Note that to make this solution work, I have to add an extra +1 to the width for each sub component. Not sure why, but I have tested it with various borders and layouts and it is extremely consistent; I imagine there is perhaps a pixel of extra space somewhere I am not thinking hard enough about. But the important thing is it works perfectly now. Here is a sample of the math (sorry about the old school untyped collection requiring a cast, Java 1.3):

int width = 0;
for(int i = 0; i < MAX_VISIBLE_PANELS; i++)
{
    width += ((SubPanel)panelList.get(i)).getWidth();
    width ++;//extra pixel per panel
}
like image 353
gnomed Avatar asked Jun 03 '11 19:06

gnomed


1 Answers

Two things come to mind:

  1. You may be able to use validate() prior to pack() in order to establish a sub-panel's geometry for later reference, as shown in this example.

  2. You may need to account for the default gaps specified by FlowLayout, which is the default layout for JPanel.

like image 127
trashgod Avatar answered Oct 05 '22 11:10

trashgod