tags:

views:

1077

answers:

1

Because Canvas3D doesn't have the ability to resize dynamically with the parent frame, I would like to be able to track when a user resizes a window and then resize it manually myself. (If this ends up crashing Canvas3D, as some docs suggest, I will simply destroy and recreate it when the user resizes their window). Part of this procedure involves being able to accurately tell how big the container panel is to begin with.

The two methods I've tried:

panel.getHeight();
panel.getPreferredSize().height;

Don't seem to accurately report things: getHeight() is invariably zero, and getPreferredSize() returns numbers that don't actually have anything to do with the actual size of the panel.

Any ideas?

Edit: So, I took a debugger to the panel object and manually inspected the non-object properties and I didn't see anything that resembled width/height. Granted, there are sub-objects that I didn't look at. Also, maybe the window has to be visible (it isn't, at the point I'm interfacing the object) when I query for height/object?

Edit 2: So, Swing classes are subclasses of AWT classes, so I imagine if you're able to find the height/width of those, the approach would generalize. I've amended the title accordingly.

+3  A: 

To determine the size of a component you have to either:

  • have set it manually at some point
  • run the layout manager responsible for layouting the component

Generally, you get the exact size of a component via the getSize() method, which returns a Dimension object containing width and height, but getWidth/Height() should work too. But this can only work, if one of the two preconditions are met. If a window has never been made visible, has no layout manager or the component (you want to know the size of) has been added after the window/container has been made visible, the size usually is zero.

So to get the correct size, you have to make the container/frame visible (after you have added the component) or call validate() or doLayout() on the container to recalculate the layout, if you added the component after the last layout was done. Another thing to keep in mind is setting and probably configuring a layout manager on the container. If no layout manager ist set (null), even making a container visible oder calling validate() does not set a size on its children.

The minimumSize/preferredSize/maximumSize properties are hints to the layout manager, how the component should be sized, but it does not have to obey them (most layout managers don't).

Edit 2: After I read your other question about the same subject, I think you should read Using Layout Managers from The Java Tutorials

Edit: I don't know if you already figured that out, but to react to the resizing of the window, you can do something like this:

public class WindowResizeTest extends JFrame {

    public static void main(String[] args) {
     new WindowResizeTest();
    }

    public WindowResizeTest() {
     this.setSize(640, 480);

     JPanel panel = new JPanel();
     panel.setBackground(Color.RED);
     this.add(panel);

     this.addComponentListener(new ComponentListener() {

      public void componentResized(ComponentEvent e) {
       System.out.println(e.getComponent().getSize());
      }

      public void componentHidden(ComponentEvent e) {}

      public void componentMoved(ComponentEvent e) {}

      public void componentShown(ComponentEvent e) {}
     });

     this.setVisible(true);
    }

}
Simon Lehmann
Thank you so much for the well thought out answer. I will try it out promptly!
Edward Z. Yang