2016-03-12 20 views
6

Ho un problema con il metodo repaint() nel mio codice Java. Voglio chiamarlo in un altro class ma non posso, qualcosa non funziona affatto. Ho cercato nei forum, ma nulla è stato in grado di aiutarmi.Metodo Repaint() che chiama in un'altra classe

mio principaleclass:

public class Main { 

public static Main main; 
public static JFrame f; 
public Main(){ 

} 

public static void main(String[] args) { 
    main = new Main(); 

    f = new JFrame(); 
    Ball b = new Ball(); 

    f.getContentPane().setBackground(Color.GRAY); 

    f.add(b); 
    f.setSize(500, 500); 
    f.setLocationRelativeTo(null); 
    f.setTitle("Test"); 
    f.setVisible(true); 
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    f.addMouseMotionListener(b); 
    f.addKeyListener(new Key()); 


} 
} 

sferaclass dove ho creato 2DGraphics per forme in movimento:

public class Ball extends JLabel implements MouseMotionListener{ 

public Ball(){ 

} 

public static double x = 10; 
public static double y = 10; 
public static double width = 40; 
public static double height = 40; 

String nick; 
boolean isEllipse = true; 

public void paintComponent(Graphics g){ 
    super.paintComponent(g); 

    Graphics2D g2d = (Graphics2D) g; 
    if(isEllipse){ 
     Ellipse2D e2d = new Ellipse2D.Double(x, y, width, height); 
     g2d.setColor(Color.RED); 
     g2d.fill(e2d); 
    } 
    else{ 
     Rectangle2D r2d = new Rectangle2D.Double(x, y, width, height); 
     g2d.setColor(Color.GREEN); 
     g2d.fill(r2d); 
    } 

} 

@Override 
public void mouseDragged(MouseEvent e) { 
    isEllipse = false; 
    x = e.getX() - 30; 
    y = e.getY() - 40; 
    this.repaint(); 
} 

@Override 
public void mouseMoved(MouseEvent e) { 
    x = e.getX() - 30; 
    y = e.getY() - 40; 
    isEllipse = true; 
    this.repaint(); 
} 
} 

E chiaveclass dove ho messo KeyListener per spostare le forme da pressione del tasto:

public class Key extends Ball implements KeyListener { 

public Key() { 
} 

@SuppressWarnings("static-access") 
@Override 
public void keyPressed(KeyEvent e) { 

    if(e.getKeyCode() == KeyEvent.VK_W){ 
     super.x += 10; 
     super.repaint(); 
     System.out.println("x: " + super.x); 
    } 
} 

@Override 
public void keyReleased(KeyEvent e) { 
    // TODO Auto-generated method stub 

} 

@Override 
public void keyTyped(KeyEvent e) { 
    // TODO Auto-generated method stub 

} 
} 

Ma c'è qualcosa di sbagliato con questo codice: eccellente metodo non funziona per chiaveclass. Tutto in Ballclass funziona bene. Dov'è il problema?

risposta

6

Super funziona bene, ma la tua interpretazione di ciò che fa è sbagliata. Il tuo problema è che stai cercando di usare l'ereditarietà per risolvere un problema che non è risolto con l'ereditarietà. Devi chiamare repaint() sull'istanza Ball effettivamente visualizzata e utilizzata, non su un'istanza di una classe completamente diversa, Key, che si estende in modo inappropriato da Ball. Prima di tutto, rendi la chiave non estendi la palla, passa in una vera palla di riferimento in Chiave e la soluzione cadrà da quella.

forse fare qualcosa di simile:

f.addKeyListener(new Key(b)); 

e

public class Key implements KeyListener { 
    private Ball ball; 

    public Key(Ball ball) { 
     this.ball = ball; 
    } 

    public void keyPressed(KeyEvent e) { 

     if(e.getKeyCode() == KeyEvent.VK_W){ 
      b.incrX(10); // give Ball a public method for this 
      b.repaint(); 
      // System.out.println("x: " + super.x); 
     } 
    } 

    // .... etc... 

nota, me stesso, mi piacerebbe usare il tasto binding per questo, non un KeyListener, da allora non avrebbe dovuto futz con il focus della tastiera.

Ad esempio:

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Point; 
import java.awt.RenderingHints; 
import java.awt.event.*; 

import javax.swing.AbstractAction; 
import javax.swing.ActionMap; 
import javax.swing.InputMap; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.KeyStroke; 
import javax.swing.SwingUtilities; 

public class MoveBall { 
    private static final int PREF_W = 500; 
    private static final int PREF_H = PREF_W; 

    private static void createAndShowGui() { 
     BallPanel ballPanel = new BallPanel(PREF_W, PREF_H); 
     MyMouse myMouse = new MyMouse(ballPanel); 
     ballPanel.addMouseListener(myMouse); 
     ballPanel.addMouseMotionListener(myMouse); 
     new CreateKeyBindings(ballPanel); 


     JFrame frame = new JFrame("MoveBall"); 
     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
     frame.getContentPane().add(ballPanel); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(() -> { 
      createAndShowGui(); 
     }); 
    } 
} 

@SuppressWarnings("serial") 
class BallPanel extends JPanel { 

    private static final Color ELLIPSE_COLOR = Color.RED; 
    private static final Color SQUARE_COLOR = Color.GREEN; 
    private static final int BALL_WIDTH = 40; 
    private int prefW; 
    private int prefH; 
    private boolean isEllipse = true; 
    private int ballX; 
    private int ballY; 

    public BallPanel(int prefW, int prefH) { 
     this.prefW = prefW; 
     this.prefH = prefH; 
    } 

    public boolean isEllipse() { 
     return isEllipse; 
    } 

    public void setEllipse(boolean isEllipse) { 
     this.isEllipse = isEllipse; 
    } 

    public int getBallX() { 
     return ballX; 
    } 

    public void setBallX(int ballX) { 
     this.ballX = ballX; 
    } 

    public void setXY(int x, int y) { 
     ballX = x; 
     ballY = y; 
     repaint(); 
    } 

    public void setXYCenter(int x, int y) { 
     ballX = x - BALL_WIDTH/2; 
     ballY = y - BALL_WIDTH/2; 
     repaint(); 
    } 

    public void setXYCenter(Point p) { 
     setXYCenter(p.x, p.y); 
    } 

    public int getBallY() { 
     return ballY; 
    } 

    public void setBallY(int ballY) { 
     this.ballY = ballY; 
    } 

    public void incrementBallX(int x) { 
     ballX += x; 
     repaint(); 
    } 

    public void incrementBallY(int y) { 
     ballY += y; 
     repaint(); 
    } 



    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     Graphics2D g2 = (Graphics2D) g; 
     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
     if (isEllipse) { 
      g2.setColor(ELLIPSE_COLOR); 
      g2.fillOval(ballX, ballY, BALL_WIDTH, BALL_WIDTH); 
     } else { 
      g2.setColor(SQUARE_COLOR); 
      g2.fillOval(ballX, ballY, BALL_WIDTH, BALL_WIDTH); 
     } 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     if (isPreferredSizeSet()) { 
      return super.getPreferredSize(); 
     } 
     return new Dimension(prefW, prefH); 
    } 
} 

class MyMouse extends MouseAdapter { 

    private BallPanel ballPanel; 

    public MyMouse(BallPanel ballPanel) { 
     this.ballPanel = ballPanel; 
    } 

    @Override 
    public void mousePressed(MouseEvent e) { 
     ballPanel.setXYCenter(e.getPoint()); 
    } 

    @Override 
    public void mouseDragged(MouseEvent e) { 
     ballPanel.setXYCenter(e.getPoint()); 
    } 

    @Override 
    public void mouseReleased(MouseEvent e) { 
     ballPanel.setXYCenter(e.getPoint()); 
    } 

} 

enum Direction { 
    UP(KeyEvent.VK_UP), DOWN(KeyEvent.VK_DOWN), LEFT(KeyEvent.VK_LEFT), RIGHT(KeyEvent.VK_RIGHT); 

    private int key; 

    private Direction(int key) { 
     this.key = key; 
    } 

    public int getKey() { 
     return key; 
    } 
} 

// Actions for the key binding 
@SuppressWarnings("serial") 
class MyKeyAction extends AbstractAction { 
    private static final int STEP_DISTANCE = 5; 
    private BallPanel ballPanel; 
    private Direction direction; 

    public MyKeyAction(BallPanel ballPanel, Direction direction) { 
     this.ballPanel = ballPanel; 
     this.direction = direction; 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     switch (direction) { 
     case UP: 
      ballPanel.incrementBallY(-STEP_DISTANCE); 
      break; 
     case DOWN: 
      ballPanel.incrementBallY(STEP_DISTANCE); 
      break; 
     case LEFT: 
      ballPanel.incrementBallX(-STEP_DISTANCE); 
      break; 
     case RIGHT: 
      ballPanel.incrementBallX(STEP_DISTANCE); 
      break; 

     default: 
      break; 
     } 
    } 
} 

class CreateKeyBindings { 

    private BallPanel ballPanel; 

    public CreateKeyBindings(BallPanel ballPanel) { 
     this.ballPanel = ballPanel; 
     int condition = JComponent.WHEN_IN_FOCUSED_WINDOW; 
     InputMap inputMap = ballPanel.getInputMap(condition); 
     ActionMap actionMap = ballPanel.getActionMap(); 

     for (Direction direction : Direction.values()) { 
      KeyStroke keyStroke = KeyStroke.getKeyStroke(direction.getKey(), 0); 
      String keyString = keyStroke.toString(); 
      inputMap.put(keyStroke, keyString); 
      actionMap.put(keyString, new MyKeyAction(ballPanel, direction)); 
     } 
    } 

} 
+0

Oh, grazie, ora sta funzionando. :) Sto usando KeyListener perché non ho intenzione di fare qualcosa di grande, infatti non ho usato Java "chiaro" (senza librerie estese per i plugin dei giochi) dal 2014 e ora devo ricordarlo dall'inizio . : D – McDaniel

Problemi correlati