我试图在窗口的中心画一个圆圈,我似乎无法把它弄好,应该真的很容易!我的理解是,如果将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)
一个很大的问题,你在不知不觉中覆盖由布局管理器来定位组件,这两个关键的方法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)