让两个对象在SwingBot中移动

时间:2014-02-27 04:39:57

标签: java swing timer paintcomponent

我正在尝试这样做,以便在按下命令时两个形状都会移动。我的问题是:如何让蓝色多边形与黄色矩形一起移动?无论我做什么,我似乎无法弄明白。任何帮助表示赞赏!谢谢!

编辑:删除定时器代码(用于不同的东西)

import javax.swing.JFrame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import javax.swing.JComponent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.Color;
import java.awt.Polygon;
import java.util.Scanner;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.Timer;

public class Original {

    public static void main(String[] args) {    
        // contruction of new JFrame object
        JFrame frame = new JFrame();    
        // mutators
        frame.setSize(400,400);
        frame.setTitle("SwingBot");    
        // program ends when window closes
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);    
        Robot r = new Robot();
        frame.add(r);
        // voila!
        frame.setVisible(true);
        // your Scanner-based command loop goes here        
        int noend = 0;
        System.out.println("Type a Command:");
        while(noend == 0)
        {
             Scanner input = new Scanner(System.in);
             String command = input.next(); 
             if(command.equals("left"))
                 r.moveBot(-10,0);

             if(command.equals("right"))
                 r.moveBot(10,0);

             if(command.equals("down"))
                 r.moveBot(0,10);

             if(command.equals("up"))
                 r.moveBot(0,-10);
        }            
        // call methods on the Robot instance like w.moveBot(10,10) in response to
        // user input
    }    

    public static class Robot extends JComponent
    {
        private Rectangle rect = new Rectangle(20,60);
        private Polygon poly = new Polygon();

        public void paintComponent(Graphics g)
        {
            Graphics2D g2 = (Graphics2D) g;               
            // set the color
            g2.setColor(Color.ORANGE);                
            // draw the shape`
            g2.fill(rect);                
            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); 
                super.paintComponent(g);
                g.setColor(Color.BLUE);
                g.drawPolygon(poly);                
        }

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

2 个答案:

答案 0 :(得分:4)

建议:

  • 请勿使用paintComponent方法创建形状。
  • 创建它们时,为它们提供可以更改的变量
  • Timer或按键,或者您尝试移动它们的位置,更改这些变量并致电repaint()
  • 对于多个对象,您可以拥有interface Shape Shape,其中每个move()都有move()方法可以调用。
  • 遍历这些对象的数据结构并调用它们的Shape方法,然后重绘()`
  • drawShape(Graphics g)可以使用Shape方法,您可以在paintComponent方法中循环浏览drawShape(g)的数据结构并调用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); } }); } }

您可以查看this answer作为示例。

enter image description here


更新

以上是我上面提到的所有观点的一个例子。

enter image description here

{{1}}

答案 1 :(得分:2)

正如@peeskillet已经在你的paintComponent方法中指出的那样,每次调用时都会重新创建poly对象...意味着它从未移动过,事实上潜在的NullPointerException等待发生...

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

相反,请在构造函数中为Robot面板创建poloygon。

此示例还演示了Initial Threadskey bindings以及Stroking and Filling Graphics Primitives

enter image description here

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

    }
}

请确保您全权归功于@peeskillet,我只想强调您可能会考虑的一些问题区域和解决方案