如何让JPanel填充父JFrame

时间:2015-02-17 21:28:52

标签: java swing

我想在窗口的中心画一个圆圈,我似乎无法把它弄好,应该真的很容易!我的理解是,如果将JPanel设置为JFrame的内容窗格,则默认布局为flowLayout,该绘图应从屏幕的左上角开始为0,0。为了弄清楚发生了什么,我画了一个填充JPanel的蓝色背景,但似乎有这样的边缘:

enter image description here

当窗口小于蓝色矩形时,绘图开始从对面剪切:

enter image description here

发生了什么事!这是我的代码:

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

public class Test extends JFrame {

    public static void main(String args[])
    {
        Test test = new Test();
        test.Start();
    }

    public void Start()
    {
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setSize(500, 500);
        CirclePanel circlePanel = new CirclePanel();
        this.setContentPane(circlePanel);
        this.setVisible(true);
    }

    public class CirclePanel extends JPanel
    {
        private int radius = 200;

        public void paintComponent(Graphics g) {
            g.setColor(Color.blue);
            g.fillRect(0, 0, this.getWidth(), this.getHeight());
            g.setColor(Color.red);
            int diameter = radius * 2;
            g.fillOval(getX(), getY(), diameter, diameter);
        }

        public int getX()
        {
            return (this.getWidth()/2) - radius;
        }

        public int getY()
        {
            return (this.getHeight()/2) - radius;
        }
    }
}

3 个答案:

答案 0 :(得分:5)

一个大问题是,您在不知不觉中重写了布局管理器使用的两种关键方法来定位组件,getX()getY()方法,从而您不会弄乱JPanel的位置。

首先,重命名这些方法,以免意外移动JPanel。

另外,不要忘记调用super的paintComponent方法,并避免调用setSize()。而是覆盖JPanel上的getPreferredSize,并打包您的JFrame。

如,

public int getMyX() {
   return myX;
}

public int getMyY() {
   return myY;
}

例如

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

public class Test extends JFrame {

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

   public void Start() {
      this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      // this.setSize(500, 500);
      CirclePanel circlePanel = new CirclePanel();
      setContentPane(circlePanel);
      pack();
      setVisible(true);
   }

   public class CirclePanel extends JPanel {
      private static final int PREF_W = 500;
      private static final int PREF_H = PREF_W;
      private int radius = 200;

      public void paintComponent(Graphics g) {
         super.paintComponent(g); //!!
         g.setColor(Color.blue);
         g.fillRect(0, 0, this.getWidth(), this.getHeight());
         g.setColor(Color.red);
         int diameter = radius * 2;
         g.fillOval(getMyX(), getMyY(), diameter, diameter);
      }

      //!!
      public int getMyX() {
         return (this.getWidth() / 2) - radius;
      }

      //!!
      public int getMyY() {
         return (this.getHeight() / 2) - radius;
      }

      //!!
      @Override
      public Dimension getPreferredSize() {
         if (isPreferredSizeSet()) {
            return super.getPreferredSize();
         }
         return new Dimension(PREF_W, PREF_H);
      }
   }
}

答案 1 :(得分:3)

问题是您要覆盖getX()getY()。将这些重命名为其他内容,您的代码将按预期工作。此外,最好打开编译器警告以查找缺少的@Override注释,并注意这些警告。 (那会通知方法覆盖超类方法)。

答案 2 :(得分:0)

尝试使用this.add(circlePanel)代替this.setContentPane(circlePanel)并将JPanel的大小设置为与JFrame相同的大小