paint() method would not draw on JPanel

落花浮王杯 提交于 2019-12-04 05:49:13

问题


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! 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. can someone please check it and tell me what is wrong here??

main method: public class 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:

    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! the paint(Graphics g) method just does not want to get triggered! 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!


回答1:


Your class Board does not extend the JPanel class. So the paint() method is never called by the Swing. Also, the statement gamePanel.repaint() will only execute the default JPanel paint() method of gamePanel. Instead you want the overridden paint method to be executed, so might want to do this:

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.

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.




回答2:


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.

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. When you call repaint, Swing will attempt to call the paint method of the JPanel that is a component of that JFrame. 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.

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. This way, your paint method will be called when the JFrame is repainted.




回答3:


Your "main" class (board) should extend JPanel to work as expected. With your way, paint would never be called. 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. 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



来源:https://stackoverflow.com/questions/35827298/paint-method-would-not-draw-on-jpanel

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!