2016-03-06 5 views
0

Я пробовал несколько исходных кодов рисования в java, и они работали нормально, но когда я попытался сделать один из своих, я не смог получить метод paint(Grahpics g)! Я снова посмотрел на коды, которые у меня есть, и проверил некоторые из руководств на страницах Oracle, но, похоже, я не знаю, почему это не сработает. Может кто-то, пожалуйста, проверьте его и скажите мне, что здесь не так?метод paint() не нарисовал на JPanel

Основной метод: общественный класс главный

{ 
    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, также KeyListener работает, но изображения не рисовали! метод paint(Graphics g) просто не хочет срабатывать! В Google это не помогло .. Я думал, что это будет распространенная проблема, но у меня нет проблем, все решения не помогли мне. помогите пожалуйста? Если кто-то может объяснить, это было бы очень признательно!

ответ

0

Ваш класс Board не распространяется на класс JPanel. Поэтому метод paint() никогда не вызывается Swing. Кроме того, в заявлении gamePanel.repaint() будет выполняться только метод JPanelpaint()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, вы также можете переопределить метод 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(); 
    } 
}; 

Однако я бы рекомендовал первое решение, а не этим с anonymous classes.

+0

но я сделал 'gamePanel.repaint()', не должен ли это запускать его? не могу я вызвать его на текущий JPanel? – bakz

+0

Нет, 'gamePanel' - это экземпляр' JPanel', вызывающий 'gamePanel.repaint()' только инициирует исходный метод 'JPanel'' paint() '. Тем не менее, вы хотите вызвать ** ваш метод ** paint, который имеет реализацию рисования автомобиля. Я обновил свой ответ. – vsimkus

+0

Можно ли установить текущий метод рисования для нового экземпляра JPanel в текущем коде? или мне нужно создать новый объект? – bakz

0

Когда вы вызываете repaint на какой-либо контейнер, тогда происходит то, что Swing смотрит на все компоненты этого контейнера и вызывает их метод paint.

Однако, ваш класс board (кстати, вы должны называть его Board. Имена классов всегда должны начинаться с капитала) не является компонентом вашего JFrame. Когда вы вызываете repaint, Swing попытается вызвать метод краски JPanel, который является компонентом этого JFrame. Но вы не переопределили этот метод. Вы только что добавили метод paint к вашему board, а board не является компонентом JFrame.

По этой причине обычно вы должны создать класс, который extnds JPanel или какой-либо другой компонент, а затем добавить текущий объект этого класса в качестве компонента в JFrame. Таким образом, ваш метод paint будет вызываться при перекраске JFrame.

0

Ваш «основной» класс (board) должен расширить JPanel для работы, как ожидалось. С вашего пути, paint никогда не будет называться. он действует как любая нормальная самозаписываемая функция.

Если вы хотите, чтобы держать вещи, как они есть, вы можете сделать что-то, что IKE:

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

Пожалуйста, имейте в виду, что Class имя должно начинаться с заглавной буквы. Он не будет делать никаких ошибок, но это соглашение об именах, как вы можете видеть здесь: http://www.oracle.com/technetwork/java/codeconventions-135099.html

+0

Нет проблем. что-то новое каждый день :) – Amirag

Смежные вопросы