Вызов метода Repaint () в другом классе


У меня есть проблема с методом 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

}
}

, но что-то не так с этим код: супер метод не работает для ключа class. Все в шаре class работает хорошо. В чем же проблема?

1 6

1 ответ:

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

Возможно сделайте что-нибудь вроде этого:

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

Обратите внимание, что я бы использовал для этого привязки клавиш, а не Кейлистер, так как тогда мне не пришлось бы работать с клавиатурой.

Например:

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

}