简体   繁体   English

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

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

I tried few source codes of drawing in java and they were working fine, but when i tried to make one of my own I could not get the paint(Grahpics g) method to work!我尝试了一些在 Java 中绘制的源代码,它们运行良好,但是当我尝试自己制作一个时,我无法使paint(Grahpics g)方法起作用! I looked again at the codes I have and checked some of the tutorials in Oracle's pages but i don't seem to be able to know why it would not work.我再次查看了我拥有的代码并检查了 Oracle 页面中的一些教程,但我似乎无法知道为什么它不起作用。 can someone please check it and tell me what is wrong here??有人可以检查一下并告诉我这里有什么问题吗??

main method: public class main主要方法:公共类main

{
    public static void main(String[] args) 
    {
        new board();
    }
}

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

}

There are no errors, it shows me the width of the image which is right, also the timer triggers the ActionListener , also KeyListener is working, but the images would not draw!没有错误,它向我显示了正确的图像宽度,定时器也触发了ActionListenerKeyListener也在工作,但图像不会绘制! the paint(Graphics g) method just does not want to get triggered! paint(Graphics g)方法只是不想被触发! Googling it did not help.. I thought this would be a common problem but nobody has the problem I have, all solutions failed me.谷歌搜索没有帮助..我认为这将是一个常见问题,但没有人遇到我遇到的问题,所有解决方案都失败了。 help please?请帮忙? If someone can explain it would be most appreciated!如果有人可以解释,将不胜感激!

Your class Board does not extend the JPanel class.您的类Board没有扩展JPanel类。 So the paint() method is never called by the Swing.因此,Swing 永远不会调用paint()方法。 Also, the statement gamePanel.repaint() will only execute the default JPanel paint() method of gamePanel .此外,声明gamePanel.repaint()将只执行默认JPanel paint()方法gamePanel Instead you want the overridden paint method to be executed, so might want to do this:相反,您希望执行覆盖的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();
    }
    ....
}

Replace your action functionality with this:用这个替换你的动作功能:

public void actionPerformed(ActionEvent e) {
   this.repaint();
}

Alternative solution: If you do not want your Board class to extend JPanel , you can also override the paint() method of the gamePanel as you initialize it.替代解决方案:如果您不希望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();
   }
};

However, I would recommend the first solution rather than this one with anonymous classes .但是,我会推荐第一个解决方案,而不是这个带有匿名类的解决方案。

When you call repaint on some container, then what happens is that Swing looks at all the components in that container and calls their paint method.当您在某个容器上调用repaint时,发生的事情是 Swing 查看该容器中的所有组件并调用它们的paint方法。

However, your board class (you should be calling it Board , by the way. Class names should always start with a capital) is not a component of your JFrame.但是,您的board类(顺便说一下,您应该将其称为Board 。类名应始终以大写开头)不是 JFrame 的组件。 When you call repaint , Swing will attempt to call the paint method of the JPanel that is a component of that JFrame .当您调用repaint ,Swing 将尝试调用作为该JFrame组件的JPanel的paint方法。 But you didn't override that method.但是您没有覆盖该方法。 You just added a paint method to your board , and board is not a component of the JFrame .您刚刚向board添加了一个paint方法,并且board不是JFrame的组件。

For this reason, usually you are supposed to create a class that extnds JPanel or some other component, and then add the current object of that class as a component to the JFrame.出于这个原因,通常您应该创建一个扩展JPanel或其他一些组件的类,然后将该类的当前对象作为组件添加到 JFrame。 This way, your paint method will be called when the JFrame is repainted.这样,在重新绘制JFrame时将调用您的paint方法。

Your "main" class ( board ) should extend JPanel to work as expected.您的“主”类( board )应该扩展 JPanel 以按预期工作。 With your way, paint would never be called.用你的方式, paint永远不会被调用。 it acts like any normal self-written function.它的作用类似于任何正常的自写函数。

If you want to keep things as they are, you can do something ike that:如果您想保持原样,您可以执行以下操作:

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

Please keep in mind that a Class name should start with a capital letter.请记住, Class名称应以大写字母开头。 It won't make any errors but it is a naming convention as you can see here: http://www.oracle.com/technetwork/java/codeconventions-135099.html它不会出错,但它是一个命名约定,正如您在此处看到的: http : //www.oracle.com/technetwork/java/codeconventions-135099.html

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

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