开发者

Unwanted border around JPanel

I'm creating a form with a JPanel inside it for some graphics and some buttons for controlling the thing. For some reason I have to specify the JPanel to be 10 px less wide and 30 px less high than the actual graphics I want to put inside it. What causes this problem?

This is the code:

public class Window {
 public Sheepness sheepness;

 public ButtonPanel buttonPanel;
 public PaintPanel paintPanel;
 public JFrame frame;

 public Window(Sheepness sheepness) {
  this.sheepness = sheepness;

  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));

  buttonPanel = new ButtonPanel(this);
  background.add(BorderLayout.SOUTH, buttonPanel.buttonBox);

  paintPanel = new PaintPanel(this);
  paintPanel.setP开发者_StackOverflowreferredSize(new Dimension(320, 240));
  background.add(BorderLayout.CENTER, paintPanel);

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

public class PaintPanel extends JPanel {
 public Window window;

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

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

Screenshot with a preferredSize of 320 x 240:

Can't find source image http://www.cmbi.ru.nl/~estens/Sheepness/Sheepness_simulation_border.png.

You can see the 320 x 240 fillRect doesn't fill the JPanel entirely, a border of 10 px width and 30 px height remains.

Screenshot with a preferredSize of 310 x 210:

Can't find source image http://www.cmbi.ru.nl/~estens/Sheepness/Sheepness_simulation_noBorder.png.

Now it fits the 320 x 240 fillRect exactly!

Any ideas?


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.


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());
}

[]]


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜