【问题标题】:Repaint() method calling in another class在另一个类中调用 Repaint() 方法
【发布时间】:2016-06-27 19:26:23
【问题描述】:

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


}
}

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 classBall class 中的所有内容都运行良好。问题出在哪里?

【问题讨论】:

    标签: java swing paintcomponent repaint


    【解决方案1】:

    Super 工作正常,但您对它的作用的解释是错误的。您的问题是您正在尝试使用继承来解决继承无法解决的问题。您需要在实际可视化和使用的 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));
            }
        }
    
    }
    

    【讨论】:

    • 哦,谢谢,现在可以了。 :) 我使用 KeyListener 是因为我不打算做大事,事实上我自 2014 年以来就没有使用过“清晰”的 Java(没有游戏插件的扩展库),现在我必须从一开始就提醒这一点. :D
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-22
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多