Java paint()方法不会在JPanel上绘制

Java paint()方法不会在JPanel上绘制,java,swing,draw,drawing2d,Java,Swing,Draw,Drawing2d,我尝试了一些用java绘制的源代码,它们工作得很好,但是当我尝试制作自己的源代码时,我无法使用paint(Grahpics g)方法!我再次查看了我的代码,并查看了Oracle页面中的一些教程,但我似乎不知道为什么它不起作用。 有人能检查一下并告诉我这里出了什么问题吗 主要方法: 公共班机 { public static void main(String[] args) { new board(); } } 董事会: import java.awt.B

我尝试了一些用java绘制的源代码,它们工作得很好,但是当我尝试制作自己的源代码时,我无法使用
paint(Grahpics g)
方法!我再次查看了我的代码,并查看了Oracle页面中的一些教程,但我似乎不知道为什么它不起作用。 有人能检查一下并告诉我这里出了什么问题吗

主要方法: 公共班机

{
    public static void main(String[] args) 
    {
        new board();
    }
}
董事会:

import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;


public class board implements ActionListener
{
    private JFrame f = new JFrame("Speedy");
    private JPanel gamePanel = new JPanel();


    private Image bg = new ImageIcon(this.getClass().getResource("road.png")).getImage();
    private Timer t;


    private car myCar = new car();


    public board()
    {
        t = new Timer(50,this);
        t.start();


        gamePanel.setSize(600,400);
        gamePanel.setDoubleBuffered(true);
        gamePanel.setFocusable(true);
        gamePanel.addKeyListener(new TAdapter());

        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(gamePanel,BorderLayout.CENTER);
        //f.addKeyListener(new TAdapter());
        f.setBounds(200,100,600,400);
        f.setVisible(true);
        f.revalidate();
        f.repaint();

    }




    public void paint(Graphics g) {
        gamePanel.paint(g);

        Graphics2D g2d = (Graphics2D)g;
        g2d.drawImage(bg,0,0,null);
        g2d.drawImage(myCar.getImg(), myCar.xPos, myCar.yPos, null);

        System.out.println("Painted");

        g.dispose();
    }



    public void actionPerformed(ActionEvent e) 
    {
        gamePanel.repaint();
        //System.out.println("Painting..");
    }





    private class TAdapter extends KeyAdapter {

        public void keyReleased(KeyEvent e) {}

        public void keyPressed(KeyEvent e)  
        {
            myCar.keyPressed(e);
            System.out.println("You pressed: "+e);
        }
    }

}
car.java:

    import java.awt.Image;
    import java.awt.event.KeyEvent;
    import java.util.ArrayList;

    import javax.swing.ImageIcon

;



public class car 
{

    private Image image;
    public int xPos,yPos;

    public car()
    {
        image = new ImageIcon(this.getClass().getResource("car.png")).getImage();
        xPos = 300;
        yPos = 200;
        System.out.println(image.getWidth(null));
    }



    public Image getImg() {return image;}


    public void move() {}


    public void keyPressed(KeyEvent e) 
    {

        int key = e.getKeyCode();

        if (key == KeyEvent.VK_LEFT) xPos -= 1;
        if (key == KeyEvent.VK_RIGHT)xPos += 1;
        if (key == KeyEvent.VK_UP)   yPos -= 1;
        if (key == KeyEvent.VK_DOWN) yPos += 1;
    }

}
没有错误,它向我显示了正确的图像宽度,计时器也触发了
ActionListener
,而且
keystener
正在工作,但图像不会绘制!
paint(Graphics g)
方法只是不想被触发! 用谷歌搜索也无济于事。。我认为这是一个常见的问题,但没有人有我的问题,所有的解决方案都失败了。 请帮忙?
如果有人能解释,我将不胜感激

您的类
不扩展
JPanel
类。因此,Swing永远不会调用
paint()
方法。 另外,语句
gamePanel.repaint()
将只执行
gamePanel
的默认
JPanel
paint()
方法。相反,您希望执行重写的
paint
方法,因此可能需要执行以下操作:

public class Board extends JPanel implements ActionListener {
   ....
    public void paint(Graphics g) {
       this.paint(g);

       Graphics2D g2d = (Graphics2D)g;
       g2d.drawImage(bg,0,0,null);
       g2d.drawImage(myCar.getImg(), myCar.xPos, myCar.yPos, null);

       System.out.println("Painted");

       g2d.dispose();
    }
    ....
}
将您的操作功能替换为以下内容:

public void actionPerformed(ActionEvent e) {
   this.repaint();
}
替代解决方案: 如果您不希望您的
Board
类扩展
JPanel
,也可以在初始化
gamePanel
时重写
paint()
方法

gamePanel = new JPanel() {
   @Override
   public void paint(Graphics g) {
       this.paint(g);

       Graphics2D g2d = (Graphics2D)g;
       g2d.drawImage(bg,0,0,null);
       g2d.drawImage(myCar.getImg(), myCar.xPos, myCar.yPos, null);

       g2d.dispose();
   }
};

但是,我建议使用第一种解决方案,而不是使用此解决方案。

当您在某个容器上调用
repaint
时,发生的情况是Swing查看该容器中的所有组件并调用它们的
paint
方法

但是,您的
board
类(顺便说一句,您应该称它为
board
。类名应始终以大写字母开头)不是JFrame的组成部分。调用
repaint
时,Swing将尝试调用
JPanel
的绘制方法,该方法是
JFrame
的一个组件。但是你没有覆盖这个方法。您刚刚将
paint
方法添加到
board
,而
board
不是
JFrame
的组件

出于这个原因,通常应该创建一个extnds
JPanel
或其他组件的类,然后将该类的当前对象作为组件添加到JFrame中。这样,当重新绘制
JFrame
时,将调用您的
paint
方法。

您的“main”类(
board
)应扩展JPanel以按预期工作。 按照您的方式,
paint
将永远不会被调用。它的行为类似于任何正常的自写函数

如果你想保持现状,你可以做一些类似的事情:

gamePanel = new JPanel() 
{
    @Override
    public void paint(Graphics g) 
    {
        //your code here
    }
};
请记住,
名称应以大写字母开头。它不会出现任何错误,但这是一种命名约定,您可以在此处看到:

但是我做了
gamePanel.repaint()
,这不应该触发它吗?我不能将它触发到当前的JPanel上吗?不,
gamePanel
JPanel
的一个实例,调用
gamePanel.repaint()
只会触发原始的
JPanel
paint()
方法。但是,您希望触发您的
paint
方法,该方法实现了绘制汽车。我已经更新了答案。是否可以在当前代码中为新的JPanel实例设置当前的绘制方法?或者我必须为它创建一个新对象吗?同样,根据您所说的
paint(Graphics g)
方法实际上是对原始
JPanel
对象的重写?是的,您可以在初始化
gamePanel
时重写
paint
方法。关于第二个问题,
paint
方法应该覆盖默认的
paint
方法,以扩展默认功能。