在另一个类中调用Repaint()方法

时间:2016-03-12 14:44:45

标签: java swing paintcomponent repaint

我的 Java 代码中的repaint()方法存在问题。我想在另一个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());


}
}

Ball 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

}
}

但此代码有问题:超级方法不适用于 class Ball class中的所有内容都运行良好。问题在哪里?

1 个答案:

答案 0 :(得分:6)

超级工作正常,但你对其所做的解释是错误的。您的问题是您尝试使用继承来解决未通过继承解决的问题。你需要在实际可视化和使用的Ball实例上调用repaint(),而不是在一个完全不同的类Key的实例上调用,这个类不合适地从Ball扩展。首先,让Key 延伸Ball,将一个真正的Ball引用传递给Key,解决方案就会从中落下。

也许做这样的事情:

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

请注意,我自己,我使用的是Key Bindings,而不是KeyListener,因为那样我就不会有键盘焦点。

例如:

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

}