Java paint()方法不会在JPanel上绘制
我尝试了一些用java绘制的源代码,它们工作得很好,但是当我尝试制作自己的源代码时,我无法使用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
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
的组件
出于这个原因,通常应该创建一个extndsJPanel
或其他组件的类,然后将该类的当前对象作为组件添加到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
方法,以扩展默认功能。