繁体   English   中英

Paint() 方法不会在 JPanel 上绘制

[英]paint() method would not draw on JPanel

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

主要方法:公共类main

{
    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);
        }
    }

}

汽车.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;
    }

}

没有错误,它向我显示了正确的图像宽度,定时器也触发了ActionListenerKeyListener也在工作,但图像不会绘制! paint(Graphics g)方法只是不想被触发! 谷歌搜索没有帮助..我认为这将是一个常见问题,但没有人遇到我遇到的问题,所有解决方案都失败了。 请帮忙? 如果有人可以解释,将不胜感激!

您的类Board没有扩展JPanel类。 因此,Swing 永远不会调用paint()方法。 此外,声明gamePanel.repaint()将只执行默认JPanel paint()方法gamePanel 相反,您希望执行覆盖的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 ,您还可以在初始化时覆盖gamePanelpaint()方法。

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 将尝试调用作为该JFrame组件的JPanel的paint方法。 但是您没有覆盖该方法。 您刚刚向board添加了一个paint方法,并且board不是JFrame的组件。

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

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

如果您想保持原样,您可以执行以下操作:

gamePanel = new JPanel() 
{
    @Override
    public void paint(Graphics g) 
    {
        //your code here
    }
};

请记住, Class名称应以大写字母开头。 它不会出错,但它是一个命名约定,正如您在此处看到的: http : //www.oracle.com/technetwork/java/codeconventions-135099.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM