问题
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