views:

650

answers:

4
A: 

I guess you got the label on the screenshots wrong.

If you specify

g.fillRect(0, 0, 310, 210);

in PaintPanel and

paintPanel.setPreferredSize(new Dimension(320, 240));

in Window. You get that what the first screenshot shows. Which makes sense as the rectangle has 10px less width, and 30px less height.

If you set the same (width/height; 310, 210) for both, the blue rectangle obviously "fills "the PaintPanel out.

jitter
No, it's backwards: it you set the fillRect to 0,0,320,240 and the preferredSize to 310,210 you get the filled screenshot, with both the same dimension you get the border, that's exactly what my problem is.
FinalArt2005
+1  A: 

Here's a self-contained test case, based on your code:

import java.awt.*;
import javax.swing.*;

public class Test {

 public PaintPanel paintPanel;
 public JFrame frame;

 public Test() {
  frame = new JFrame("Sheepness simulation");
  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  //frame.setSize(width, height);

  BorderLayout frameLayout = new BorderLayout();
  JPanel background = new JPanel(frameLayout);
  background.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

  paintPanel = new PaintPanel(this);
  paintPanel.setPreferredSize(new Dimension(320, 240));
  background.add(BorderLayout.CENTER, paintPanel);

  frame.getContentPane().add(background);
  frame.pack();
  frame.setResizable(false);
  frame.setVisible(true);
 }

  public static class PaintPanel extends JPanel {
    public Test window;

   public PaintPanel(Test window) {
    this.window = window;
   }

   @Override
   public void paintComponent(Graphics g) {
    g.setColor(Color.blue);
    g.fillRect(0, 0, 320, 240);
   }
  }

  public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        new Test();
      }
    });
  }
}

When I run it on an IcedTea JVM on Linux, I see this.

Your problem is either due to the button container forcing the window to be wider, or possibly due to a Swing bug in the version of Java you're using.

My recommendation is not to bother with the built-in layout classes and to use MigLayout instead.

uckelman
I'm using Sun Java 6. I haven't checked the button container yet but since both cases use the exact same button container it seems unlikely that that is the problem. It's not so much that I want to solve the problem (I can just decrease the preferred size so it does work), but I want to find out what causes it.
FinalArt2005
I'd like to comment on one of the comments above, but can comment there...Almost all layout managers ignore maximum and minimum size, and some don't do exactly what you'd expect with preferred size.MigLayout respects all of these. This will get you something pretty close to what you're looking for:background.setLayout(new MigLayout("ins 5"));background.add(paintPanel, "w 320!, h 240!, wrap");background.add(buttonPanel, "gapabove unrel");http://www.migcalendar.com/miglayout/
uckelman
+2  A: 

Different layout managers use different rules for computing actual managed controls sizes, i.e. you can't expect that the panel has particular size only if you call 'setPreferredSize()' on it.

Feel free to check javadoc for all target layout managers for more details about used algorithm in every particular case.

Also note that you can avoid using layout managers and define all sizes absolutely via 'setBounds()' method.

denis.zhdanov
A: 

believe it or not, but try inverting the order of pack() and setResizeable()

    ...
    frame.setResizable(false);
    frame.pack();  // should be called after any changes
    frame.setVisible(true);

EDIT: checked using this

    frame.pack();
    frame.setResizable(false);
    System.out.println(paintPanel.getSize());
    frame.setVisible(true);
    System.out.println(paintPanel.getSize());

and

    frame.setResizable(false);
    frame.pack();
    System.out.println(paintPanel.getSize());
    frame.setVisible(true);
    System.out.println(paintPanel.getSize());

but if size isn't important, you can fill the actual area with

@Override
public void paintComponent(Graphics g) {
    g.setColor(Color.blue);
    g.fillRect(0, 0, getWidth(), getHeight());
}

[]]

Carlos Heuberger
Thanks for the tip, but it doesn't get rid of the border either.
FinalArt2005
works fine here, without the ButtonPanel (no code), I just get the 5x5 border (EmptyBorder). Using Java build 1.6.0_16-b01 on Windows XP
Carlos Heuberger
I was just about to post that setResizable(false) is affecting this. I'm also seeing it work correctly if the order of setResizable(false) / pack() are reversed - JDK 1.5.0_16 on Windows Vista.
Nate
You are filling the panel with getWidth() and getHeight() in your example, this will cause the panel to fill up whatever the size of the panel. Try predefining the size of your panel and then after packing it filling it with a rectangle that same size.
FinalArt2005
@FinalArt2005: isn't that what you want to do? fill the panel! Anyway I did the tests using the predefined size, using exactly your code, only changed the position of the pack() call!
Carlos Heuberger
Very strange, cause that doesn't work for me :s. And to comment on the filling: I don't want to fill the panel, I want it to have a certain size, ok, eventually I will fill it with something, but what I meant is that if I fill it with the getWidth and getHeight methods I don't have a border, but also my filled area would be too big. I think I'll just have to accept the fact that, as Denis Zhdanov already mentioned, the preferredSize is used differently by different layout managers, and that it's no guarantee the component will actually have that size after packing.
FinalArt2005
Maybe it's a system or LookAndFeel specific problem... Im using Windows XP and the standard LookAndFeel. also strange that the size get changed in the setVisible() call...
Carlos Heuberger