2016-03-12 12 views
6

У меня проблема с repaint() методом в моем Java. Я хочу назвать это еще в class, но я не могу, что-то не работает вообще. Я искал на форумах, но ничто не могло мне помочь.Метод перерисовки() в другом классе

Мои Главнаяclass:

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()); 


} 
} 

Балclass где я создал 2DGraphics для подвижных форм:

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(); 
} 
} 

И Ключевыеclass где я положил KeyListener для перемещения формы по нажатие клавиши:

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 

} 
} 

Но что-то не так с этим кодом: супер метод не работает для Keyclass. Все в Ballclass работает хорошо. В чем проблема?

ответ

6

Супер работает отлично, но ваша интерпретация того, что он делает, неверна. Ваша проблема заключается в том, что вы пытаетесь использовать наследование для решения проблемы, которая не решена с наследованием. Вам нужно позвонить repaint() на фактический визуализированный и использованный экземпляр Ball, а не на экземпляр некоторого совершенно другого класса, Key, который неадекватно распространяется от Ball. Прежде всего, сделайте Ключ не протяните мяч, перейдите в истинную ссылку на шары в Ключ, и решение упадет с этого.

Может быть сделать что-то вроде этого:

f.addKeyListener(new Key(b)); 

и

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... 

Обратите внимание, я, я хотел бы использовать привязок ключей для этого, а не KeyListener, с тех пор я не должен был бы futz с фокусом клавиатуры.

Например:

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

О, спасибо, теперь он работает. :) Я использую KeyListener, потому что я не собираюсь делать что-то большое, на самом деле я не использовал «ясную» Java (без расширенных библиотек для игровых плагинов) с 2014 года, и теперь я должен напомнить это с самого начала , : D – McDaniel