6

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
}
gnomed
  • 5,483
  • 2
  • 26
  • 28
  • 1
    to get a good answer you will most likely need to provide some sample code and/or a screenshot. – Sean Jun 03 '11 at 20:01
  • @mKorbel rofl. @Sean - I will work on that, unfortunately the code is proprietary which is why I didnt bother, but I will see if I can make a quick unrelated sample... – gnomed Jun 03 '11 at 20:27
  • that's against all todays rulles for Swing, but all code cames from this edge were harcoded with setSize + setBounds, and if there was any resizable then by using resize() and resharpe(), anyway I never tried that ..., I jump to the Java in version 1.6.010 – mKorbel Jun 03 '11 at 21:46

2 Answers2

3

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.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • I am using GridBagLayout and specified no insets for the layout in the constraints. and I need a solution without pack() because of my scrollbar (see NOTE2) – gnomed Jun 03 '11 at 20:25
  • 1
    You'll want to verify any `GridBagConstraints` [`insets`](http://download.oracle.com/javase/6/docs/api/java/awt/GridBagConstraints.html#insets) or `Container` [`insets`](http://download.oracle.com/javase/6/docs/api/java/awt/Container.html#getInsets%28%29), too. A solution that can't survive `pack()` may be fragile. – trashgod Jun 03 '11 at 21:03
  • yes, i actually ran the debugger and checked the values on the insets object for the container and its parent. all insets `left` and `right` values appear to be 0. Thanks for the input though. – gnomed Jun 03 '11 at 21:13
  • 1
    @trashgod for some reasons is better call revalidate() then repaint(), but that is valid for todays Java5/6, after all important fixies for Swing, – mKorbel Jun 03 '11 at 21:47
  • FYI, ive just had to use some rather nasty hard coded integers for now. but ill select this one as at least an attempt to solve my issue and offer insight into what could be causing it. – gnomed Jun 04 '11 at 20:13
  • I _hate_ [magic numbers](http://en.wikipedia.org/wiki/Magic_number_%28programming%29),but sometimes you have to leave a TODO for later. – trashgod Jun 04 '11 at 20:39
  • I hate them too. Having encountered them already in this legacy application I am supporting, I can really appreciate their disadvantages. At least these will have some sort of comments with them. – gnomed Jun 06 '11 at 17:41
  • 1
    just another FYI, i have found the embarrassing cause of my problems. see my edit in the original post. On the plus side, while this was a silly mistake, at least there are no more magic numbers XD. – gnomed Jun 07 '11 at 20:07
  • Hard fought is well won! Good followup. – trashgod Jun 07 '11 at 20:17
2

Instead, could you pack() the window and then constrain the window size to the available screen dimensions?

Lawrence Dol
  • 63,018
  • 25
  • 139
  • 189
  • not sure what you mean by this. my issue is not with available screen dimensions, but rather determining the dimensions to be used based on the sub-panel. sure I could try constraining the size after a call to `pack()` but what do I constrain it to? I still don't know with width of my sub-panel – gnomed Jun 03 '11 at 20:30
  • @gnomed: "*calling pack() on the parent container makes the window look like I want it to, but ... after enough sub-panels ... a scroll bar will need[ed]*" - At what point do you cease to make a window larger and present scrollbars instead? I would contend that it's when the window no longer fits within the user's display space. – Lawrence Dol Jun 03 '11 at 20:35
  • @Software Monkey good point, whats probably not clear from the post is that this will be a very short dialog, and I think it just looks silly when a window is more than 2 times wider than its height... But that is entirely an aesthetic opinion I admit. – gnomed Jun 03 '11 at 20:41
  • @gnomed: But then just use `min(astheticallyPleasingWidth,DisplayWidth)`. But, for heavens sake, make the window sizable so the user can disagree with what you think is "right". And don't forget to account for things like the task bar, which may be top, bottom, left or right - use `Toolkit.getScreenInsets`. – Lawrence Dol Jun 03 '11 at 20:54
  • Also, FWIW and IMHO, better a window with "silly" dimensions than a window with "silly" unnecessary scrollbars. – Lawrence Dol Jun 03 '11 at 20:58
  • So.... the "astheticallyPleasingWidth" is EXACTLY what I am trying to determine programmatically based on the sub-panel width. And dont worry, it is not resizable by the user and I have already accounted for the height of the toolbar and other components of the window. And also, the window will never have "silly unnecessary scrollbars" because I only ever use the scrollbar "as needed" – gnomed Jun 03 '11 at 21:11
  • 1
    @gnomed: "it is not resizeable"?? Huh?! Never inflict non-resizeable windows on your users. Also, any window which has a scrollbar, cannot be resized and which fails to take up my whole screen in the dimension of said scrollbar has an *unnecessary* scrollbar. – Lawrence Dol Jun 03 '11 at 23:38
  • youre still not answering my question at all. cant you just accept that I have my reasons for the styling (which I cant be bothered to type out) and actually try to answer my question? If you have no solution then why are you commenting? I have taken your point into consideration already and it is not an acceptable solution. – gnomed Jun 04 '11 at 20:10
  • @Gnomed: Apologies - I was becoming convinced you are working hard to solve a problem which could simply be altogether avoided... sorry my ideas were of no assistance - good luck. – Lawrence Dol Jun 06 '11 at 18:46