【问题标题】:paintComponent is not drawing in the entire JPanelpaintComponent 没有在整个 JPanel 中绘制
【发布时间】:2018-02-15 20:23:52
【问题描述】:

我正在尝试制作蛇形游戏,但遇到了问题。我有一个名为 Segment 的类,它用于创建包含 x 和 y 位置以及蛇的方向的对象。该类扩展了 JPanel 并覆盖了方法 paintComponent()。然后,我将 Segment 类型的对象添加到不同类中的 JFrame。我用于移动/改变蛇方向的方法(目前实际上只是一个正方形)效果很好,但我的问题是:

当正方形达到框架宽度的一半或框架高度的一半时,它会停止绘制。我已将 JPanel 的背景设为浅灰色,因此我知道正方形在停止时尚未到达 JPanel 的末端。下面是我的简单 paintComponent() 方法和扩展 JFrame 的类中我添加对象的部分。

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    this.setBackground(Color.LIGHT_GRAY);
    g.setColor(Color.black);
    g.fillRect(xpos, ypos, width, height);
}

public Snake() {
        setLayout(new BorderLayout());
        addKeyListener(l);
        segment = new Segment(100, 100, Segment.Dir.RIGHT);
        segment.setPreferredSize(new Dimension(500,500));
        add(segment, BorderLayout.CENTER);
        timer.start();
        setVisible(true);
        pack();
        setTitle("Snake");
        setResizable(false);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }

我也知道对象位置不会停止更新,因此问题只是在整个面板/框架中绘制正方形。感谢任何帮助!

这是一个 MCVE:

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

public class Segment extends JPanel {

private int width = 10;
private int height = 10;
private int xpos, ypos;
private Dir dir;

public enum Dir {
    LEFT, RIGHT, UP, DOWN;
}

public Segment() {
    xpos = 0;
    ypos = 0;
    dir = Dir.RIGHT;
}

public Segment(int x, int y, Dir d) {
    xpos = x;
    ypos = y;
    dir = d;
}

public Dir getDir() {
    return dir;
}
public void setDir(Dir d) {
    dir = d;
}
public void setX(int x) {
    xpos = x;
    repaint();
}
public void setY(int y) {
    ypos = y;
    repaint();
}
public int getX() {
    return xpos;
}
public int getY() {
    return ypos;
}

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    this.setBackground(Color.LIGHT_GRAY);
    g.setColor(Color.black);
    g.fillRect(xpos, ypos, width, height);
}
}

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

public class Snake extends JFrame implements ActionListener {

Segment segment;
Timer timer = new Timer(50, this);

public Snake() {
    setLayout(new BorderLayout());
    setSize(500,500);
    segment = new Segment(100, 100, Segment.Dir.RIGHT);
    segment.setPreferredSize(new Dimension(getWidth(),getHeight()));
    add(segment, BorderLayout.CENTER);
    timer.start();
    setVisible(true);
    setTitle("Snake");
    setResizable(false);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setLocationRelativeTo(null);
}

    public void actionPerformed(ActionEvent e) {
    if (e.getSource() == timer) {
            segment.setX((segment.getX() + 4 + getWidth())%getWidth());
    }
}

public static void main(String[] arg) {
    new Snake();
}

}

【问题讨论】:

  • 尝试使用paint代替paint组件并使用getWidth()和getHeight()
  • 你能发一个MCVE吗?
  • @Locke Overriding paintComponent 应该在这里工作,特别是如果它适用于正在绘制的其他尺寸
  • @phflack 我在问题末尾添加了一个 MCVE。

标签: java swing jframe jpanel paintcomponent


【解决方案1】:

不要覆盖 Segment 类的 getX() 和 getY()。

这些是所有 Swing 组件的方法。它们获取组件在父容器中的当前位置。

使用不同的方法名称来控制蛇的绘制位置。由于您的变量名称是 xPos 和 yPos 可能使用 getXPos() 和 getYPos()。

所以发生的情况是,蛇在相对于 Segment 面板的 xPos/yPos 处绘制,而 Segment 面板也在相对于其父容器的 xPos/yPos 处绘制。

【讨论】:

    猜你喜欢
    • 2021-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-10
    相关资源
    最近更新 更多