Having two objects move in an SwingBot

懵懂的女人 提交于 2019-11-28 14:09:01
Paul Samsotha

Suggestions:

  • Don't create the shapes in the paintComponent method.
  • When creating them give them variables that can be changed
  • In the Timer or key press, or where ever you are trying to move them, change those variable and call repaint()
  • For multiple objects you can have a an interface like Shape where each Shape has a move() method that can be called.
  • Loop through an data structure of those objects and call their move() methods, then repaint()`
  • A Shape can have a drawShape(Graphics g) method, and you can loop through the data structure of Shape inside the paintComponent method and call drawShape(g)

You can see this answer for an example.


UPDATE

Here's an example of all the points I mention above.

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.List;
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 MoveShape extends JPanel {

    List<Shape> shapes;

    public MoveShape() {
        shapes = createShapeList();

        InputMap im = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
        im.put(KeyStroke.getKeyStroke("RIGHT"), "moveRight");
        ActionMap am = getActionMap();
        am.put("moveRight", new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                for (Shape sh : shapes) {
                    sh.moveRight();
                    repaint();
                }
            }
        });
    }

    private List<Shape> createShapeList() {
        List<Shape> list = new ArrayList<>();
        int xPoly[] = {75, 125, 170, 170, 200, 105, 60};
        int yPoly[] = {75, 50, 88, 111, 125, 180, 150};
        list.add(new MyPolygon(xPoly, yPoly, 6));
        list.add(new MyRectangle(75, 250, 150, 150));
        return list;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        for (Shape sh : shapes) {
            sh.drawShape(g);
        }
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(450, 450);
    }

    public class MyRectangle implements Shape {

        int x, y, width, height;

        public MyRectangle(int x, int y, int width, int height) {
            this.x = x;
            this.y = y;
            this.width = width;
            this.height = height;
        }

        @Override
        public void drawShape(Graphics g) {
            g.fillRect(x, y, width, height);
        }

        @Override
        public void moveRight() {
            x += INCREMENT;
        }

    }

    public class MyPolygon implements Shape {

        int[] xPoints;
        int[] yPoints;
        int numPoints;

        public MyPolygon(int[] xPoints, int[] yPoints, int numPoints) {
            this.xPoints = xPoints;
            this.yPoints = yPoints;
            this.numPoints = numPoints;
        }

        @Override
        public void drawShape(Graphics g) {
            g.fillPolygon(xPoints, yPoints, numPoints);
        }

        @Override
        public void moveRight() {
            for (int i = 0; i < xPoints.length; i++) {

                xPoints[i] += INCREMENT;

            }  
        }
    }

    public interface Shape {

        public static final int INCREMENT = 5;

        public void drawShape(Graphics g);

        public void moveRight();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new JFrame("Move Shapes");
                frame.add(new MoveShape());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setVisible(true);
            }
        });
    }
}

As @peeskillet has already pointed out...in your paintComponent method, you were re-creating the poly object each time it was called...meaning it never moved, and in fact was potential NullPointerException waiting to happen...

public void paintComponent(Graphics g)
{
    //...
    // This is a bad idea...        
    poly = new Polygon(xPoly, yPoly, xPoly.length);            
    //...
}

Instead, create the poloygon in the constructor to your Robot panel.

This example also demonstrates Initial Threads and key bindings and Stroking and Filling Graphics Primitives

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Original {

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setSize(400, 400);
                frame.setTitle("SwingBot");
                Robot r = new Robot();
                frame.add(r);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public static class Robot extends JComponent {

        private Rectangle rect = new Rectangle(20, 60);
        private Polygon poly = new Polygon();

        public Robot() {

            int xPoly[] = {75, 125, 170, 170, 200, 105, 60};
            int yPoly[] = {75, 50, 88, 111, 125, 180, 150};

            poly = new Polygon(xPoly, yPoly, xPoly.length);

            InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "Up");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), "Down");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), "Left");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "Right");

            ActionMap am = getActionMap();

            am.put("Up", new MoveAction(0, -10));
            am.put("Down", new MoveAction(0, 10));
            am.put("Left", new MoveAction(-10, 0));
            am.put("Right", new MoveAction(10, 0));

        }

        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D) g.create();

            // set the color
            g2.setColor(Color.ORANGE);

            // draw the shape`
            g2.fill(rect);

            g2.setColor(Color.BLUE);
            g2.setStroke(new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
            g2.drawPolygon(poly);
            g2.dispose();

        }

        public void moveBot(int x, int y) {
            // move the rectangle 
            rect.translate(x, y);
            poly.translate(x, y);
            // redraw the window
            repaint();
        }

        public class MoveAction extends AbstractAction {

            private int xDelta;
            private int yDelta;

            public MoveAction(int xDelta, int yDelta) {
                this.xDelta = xDelta;
                this.yDelta = yDelta;
            }

            @Override
            public void actionPerformed(ActionEvent e) {
                moveBot(xDelta, yDelta);
            }
        }

    }
}

Please, make sure you give all credit to @peeskillet, I just wanted to highlight some problem areas and solutions you might consider

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!