2

我编写了代码来驱动差动驱动机器人通过我选择的固定路径。我试图让代码从命令行运行:java StartRobot 或者能够在浏览器中运行应用程序和 Applet。我的代码如下:

import java.awt.*;
import javax.swing.*;
import java.util.ArrayList;
import java.util.List;

class DifferentialDriveRobot {

public static void main(String[] args) {
    new DifferentialDriveRobot();
}

public DifferentialDriveRobot() {
    EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            createAndShowGUI();
        }
    });
}

public void createAndShowGUI() {
    JFrame frame = new JFrame("Differential Drive Robot");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLayout(new BorderLayout());
    Robots robots = new Robots();
    frame.add(robots);
    frame.setSize(400,400);
    frame.setVisible(true);

    new Thread(new Drive(robots)).start();
}

public static int random(int maxRange) {
    return (int) Math.round((Math.random() * maxRange));
}

public class Robots extends JPanel {
    private List<Bot> robots;

    public Robots() {
        robots = new ArrayList<Bot>(1);
        robots.add(new Bot(Color.red));
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g.create();
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        for(Bot robot : robots) {
            robot.paint(g2d);
        }
        g2d.dispose();
    }

    public List<Bot> getRobots() {
        return robots;
    }
}

public class Drive implements Runnable {
    private Robots parent;

    public Drive(Robots parent) {
        this.parent = parent;
    }

    @Override
    public void run() {
        int width = getParent().getWidth();
        int height = getParent().getHeight();
        for(Bot robot : getParent().getRobots()) {
            int x = 5;
            int y = 5;
            int diameter = robot.getDiameter();
            if(x + diameter > width) {
                x = width - diameter;
            }
            if(y + diameter > height) {
                y = height - diameter;
            }
            robot.setX(x);
            robot.setY(y);
        }

        while(getParent().isVisible()) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    getParent().repaint();
                }
            });
            for(Bot robot : getParent().getRobots()) {
                move(robot);
            }

            try {
                Thread.sleep(100);
            } catch(InterruptedException ex) {}
        }
    }

    public Robots getParent() {
        return parent;
    }

    public void move(Bot robot) {
        int diameter = robot.getDiameter();
        double v1 = robot.getV1();
        double v2 = robot.getV2();
        double x = robot.getX();
        double y = robot.getY();
        double theta = robot.getTheta();
        double dx, dy, dtheta;
        int time = robot.getTime();

        dx = 0.5*(Math.cos(Math.toRadians(theta)))*(v1+v2);
        dy = 0.5*(Math.sin(Math.toRadians(theta)))*(v1+v2);
        dtheta = (-1)*(0.5*(v2-v1));

        if((x + dx < 0 || x + diameter + dx > getParent().getWidth()) || (y + dy < 0 || y + diameter + dy > getParent().getHeight())) {
            v1 = 0;
            v2 = 0;
        } else {
            if(time == 50) {
                v2 = 0;
            } else if(time > 50 && time < 300 && theta == 89.5) {
                v1 = v2 = 1;
            } else if(time > 300 && time < 450) {
                v1 = 1;
                v2 = 3;
            }
            if(time > 400 && theta == -89.0 && time < 500) {
                v1 = 5;
                v2 = 5;
            }
            if(time > 500 && time < 550) {
                v1 = v2 = 0;
            } else if(time > 550 && time < 600) {
                v1 = v2 = -2;   
            } else if(time > 600) {
                v1 = v2 = 0;
            }
        }

        x = x + dx;
        y = y + dy;
        theta = theta + dtheta;
        time = time + 1;
        robot.setTheta(theta);
        robot.setV1(v1);
        robot.setV2(v2);
        robot.setX(x);
        robot.setY(y);
        robot.setTime(time);
    }
}

public class Bot {
    private Color color;
    private double x, y;
    private int diameter;
    private double v1, v2;
    private double theta;
    private int time;

    public Bot(Color color) {
        setColor(color);
        v1 = 1;
        v2 = 1;
        diameter = 30;
        theta = 0;
        time = 0;
    }

    public int getTime() {
        return time;
    }

    public void setTime(int time) {
        this.time = time;
    }

    public int getDiameter() {
        return diameter;
    }

    public void setColor(Color color) {
        this.color = color;
    }

    public void setX(double x) {
        this.x = x;
    }

    public void setY(double y) {
        this.y = y;
    }

    public void setTheta(double theta) {
        this.theta = theta;
    }

    public Color getColor() {
        return color;
    }

    public double getX() {
        return x;
    }

    public double getY() { 
        return y;
    }

    public double getV1() {
        return v1;
    }

    public double getV2() {
        return v2;
    }

    public double getTheta() {
        return theta;
    }

    public void setV1(double v1) {
        this.v1 = v1;
    }

    public void setV2(double v2) {
        this.v2 = v2;
    }

    protected void paint(Graphics2D g2d) {
        double x = getX();
        double y = getY();
        double v1 = getV1();
        double v2 = getV2();
        g2d.rotate(Math.toRadians(theta),x,y);
        g2d.setColor(getColor());
        g2d.fillRect((int)x, (int)y, getDiameter(), getDiameter());
        g2d.setColor(Color.black);
        g2d.fillOval((int)x+9,(int)y-5,15,15);
        g2d.fillOval((int)x+9,(int)y+20,15,15);
    }
}
}

在过去,我可以通过将以下内容添加到我的 .java 文件中来完成此操作:

public class StartRobot extends JApplet {

public void init() {
EventQueue.invokeLater(new Runnable() {
    public void run() {
        DifferentialDriveRobot panel = new DifferentialDriveRobot();
        getContentPane.add(panel);
    }
});
}

public static void main(String[] args) {
    //Schedule a job for the event-dispatching thread:
    //creating and showing this application's GUI.
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
    DifferentialDriveRobot panel = new DifferentialDriveRobot();
            panel.createAndShowGUI();
        }
    });
}
}

但是,这会在编译时引发错误。我认为这是因为我的主类DifferentialDriveRobot 没有扩展JPanel,而是我完成此操作的子类。有没有快速解决这个问题?

4

1 回答 1

5

该类DifferentialDriveRobot是不能添加到小程序的非组件类。它是一个导致JFrame创建并添加您的Robot面板类的类。如果您在浏览器中运行小程序,这将导致JFrame出现 ,这通常是不可取的。

您可以将类定义Robot为您的小程序:

public class Robot extends JApplet {

  public void init() {
     ...
  }

然后将小程序添加到您的main方法中:

public static void main(String[] args) {
   JFrame frame = new JFrame("Applet Demo");
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   frame.setSize(500, 400);
   JApplet applet = new Robot();
   applet.init();
   applet.start();
   frame.add(applet);
   frame.setVisible(true);
}

如果您希望小程序作为应用程序运行,一个不错的选择是将其完全转换为JFrame基于应用程序的应用程序并使用Java Web Start进行部署。

于 2012-11-27T22:18:25.083 回答