1

I'm trying to move a rectangle drawn by Graphics2D over, but it just doesn't work. When I do x += 1; It actually moves it 1 pixel over and stops. if I do say, x += 200; It moves it 200 pixels over ONCE not in every update, but ONCE.

public void paint(Graphics g)
{
    super.paint(g);

    g.setColor(Color.WHITE);
    g.fillRect(0, 0, this.getWidth(), this.getHeight());

    g.setColor(Color.RED);
    g.fillRect(x, 350, 50, 50);

    x += 1;
}

int x is called outside void paint to make sure it's not incremented as 150 each time. Draws fine, just doesn't move, I tried using a thread and using a while loop so while the thread is running, it moves, but no luck.

YayCoding
  • 55
  • 1
  • 2
  • 12

2 Answers2

4

Instead of using a while loop or a different thread, you should be using a java.swing.Timer for animation. Here's the basic construct

Timer(int delay, ActionListener listener)

where delay is the time you want to be delayed between repaints, and listener is the listener with the callback function to perform. You could do something like this, where you change the x location, then call repaint();

    ActionListener listener = new AbstractAction() {
        public void actionPerformed(ActionEvent e) {
            if (x >= D_W) {
                x = 0;
                drawPanel.repaint();
            } else {
                x += 10;
                drawPanel.repaint();
            }
        }
    };
    Timer timer = new Timer(250, listener);
    timer.start();

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class KeyBindings extends JFrame {

    private static final int D_W = 500;
    private static final int D_H = 200;
    int x = 0;
    int y = 0;

    DrawPanel drawPanel = new DrawPanel();

    public KeyBindings() {
        ActionListener listener = new AbstractAction() {
            public void actionPerformed(ActionEvent e) {
                if (x >= D_W) {
                    x = 0;
                    drawPanel.repaint();
                } else {
                    x += 10;
                    drawPanel.repaint();
                }
            }
        };
        Timer timer = new Timer(100, listener);
        timer.start();
        add(drawPanel);

        pack();
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        setVisible(true);
    }

    private class DrawPanel extends JPanel {

        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.GREEN);
            g.fillRect(x, y, 50, 50);
        }

        public Dimension getPreferredSize() {
            return new Dimension(D_W, D_H);
        }
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                new KeyBindings();
            }
        });
    }
}

enter image description here

Here's a running example

Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
  • Is it possible to use an image instead of this rectangle? I tried it with g.drawImage(...) but that didn't help. – tamaramaria Apr 29 '19 at 10:11
0

Use Affine Transformations. By simply using the AffineTransform class you can translate the graphics object along the screen on the x or y axis.

Here is a link with info on the class and its functions etc.: https://docs.oracle.com/javase/8/docs/api/java/awt/geom/AffineTransform.html

Here is another website that will give you examples on translation as well as other transformations: http://zetcode.com/gfx/java2d/transformations/

And when incrementing x or y to translate, you must call the repaint() function to repaint the graphics object.

VicDid
  • 175
  • 2
  • 20