首页 文章

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

提问于
浏览
6

我的 Java 代码中的 repaint() 方法有问题 . 我想在另一个 class 中调用它,但我可以't, something doesn' t工作 . 我在论坛上搜索过,但没有任何东西可以帮助我 .

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

并且 Key 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

}
}

但是这段代码有问题: super 方法不适用于 Key class . Ball class 中的所有内容都运行良好 . 问题出在哪儿?

1 回答

  • 6

    超级工作正常,但你对它的作用的解释是错误的 . 你的问题是你通过继承解决了问题 . 你需要在实际可视化和使用的Ball实例上调用 repaint() ,而不是在一个完全不同的类Key的实例上调用,它不适当地从Ball扩展 . 首先,使Key not 延伸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));
            }
        }
    
    }
    

相关问题