如何让JPanel填充父JFrame

mbd*_*vis 2 java swing

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

在此输入图像描述

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

在此输入图像描述

这是怎么回事!这是我的代码:

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Hov*_*els 5

一个很大的问题,你在不知不觉中覆盖由布局管理器来定位组件,这两个关键的方法getX()getY()方法,从而你与JPanel的布局搞乱.

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

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

例如,

public int getMyX() {
   return myX;
}

public int getMyY() {
   return myY;
}
Run Code Online (Sandbox Code Playgroud)

例如

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);
      }
   }
}
Run Code Online (Sandbox Code Playgroud)