Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Repaint() method calling in another class

I have a problem with repaint() method in my Java code. I want to call it in another class but I can't, something doesn't work at all. I've searched on forums, but nothing was able to help me out.

My 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 where I created 2DGraphics for moving shapes:

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

And Key class where I put KeyListener for move the shapes by key pressing:

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

}
}

But something is wrong with this code: super method doesn't work for Key class. Everything in Ball class is working well. Where is the problem?

like image 339
McDaniel Avatar asked Mar 12 '16 14:03

McDaniel


1 Answers

Super works fine, but your interpretation of what it does is wrong. Your problem is that you're trying to use inheritance to solve a problem that isn't solved with inheritance. You need to call repaint() on the actual visualized and used Ball instance, not on an instance of some completely different class, Key, that inappropriately extends from Ball. First off, make Key not extend Ball, pass in a true Ball reference into Key and the solution will fall from that.

Perhaps do something like this:

f.addKeyListener(new Key(b));

and

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

Note, myself, I'd use Key Bindings for this, not a KeyListener, since then I wouldn't have to futz with keyboard focus.

For example:

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

}
like image 126
Hovercraft Full Of Eels Avatar answered Oct 11 '22 18:10

Hovercraft Full Of Eels