【问题标题】:How to create a LinkedList that adds a circle after every 10 seconds and removes the first element (circle) after every 15 seconds如何创建每 10 秒后添加一个圆圈并在每 15 秒后删除第一个元素(圆圈)的 LinkedList
【发布时间】:2019-09-15 19:49:39
【问题描述】:

我已经完成了随机化圆圈,现在我的挑战是像实际队列一样将圆圈添加到直线队列(我希望圆圈从左到右排队,最好在框架的顶部。当我调用 removeCircle (),我希望圆圈离开队列并向下移动框架。你能帮我使用 addCircle() 和 removeCircle() 方法吗?提前谢谢你。

public class AirTrafficLanding
{
private static void createAndShowUI()
{
    PlanePanel panel = new PlanePanel(1);

    JFrame frame = new JFrame("Air traffic Landing System");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
    frame.add( panel );
    frame.pack();
    frame.setVisible( true );

    panel.startAnimation();
}

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

}

static class PlanePanel extends JPanel implements ActionListener
{
    private ArrayList<Plane> planes = new ArrayList<Plane>();

    public PlanePanel(int planeCount)
    {
        Dimension screenSize =  Toolkit.getDefaultToolkit().getScreenSize();

        setLayout( null );
        setBackground( Color.BLACK );

        Random random = new Random();

        for (int i = 0; i < planeCount; i++)
        {
            Plane plane = new Plane();
            plane.setRandomColor(true);
            plane.setLocation(0, 700);
            //plane.setLocation(random.nextInt(screenSize.width), random.nextInt(screenSize.height));
            plane.setMoveRate(32, 32, 1, 1, true);
            plane.setSize(32, 32);
            planes.add( plane );
        }
    }

    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);

        for (Plane plane: planes)
        {
            plane.draw(g);
        }
    }

    public void startAnimation()
    {
        Timer timer = new Timer(55, this);
        timer.start();
    }

    public void actionPerformed(ActionEvent e)
    {
        move();
        repaint();
    }

    private void move()
    {
        for (Plane plane : planes)
        {
            plane.move(this);
        }
    }
}

static class Plane
{
    public Color color = Color.BLACK;

    public int x = 0;
    public int y = 0;
    public int width  = 1;
    public int height = 1;

    private int moveX = 1;
    private int moveY = 1;
    private int directionX = 1;
    private int directionY = 1;
    private int xScale = moveX;
    private int yScale = moveY;

    private boolean randomMove = false;
    private boolean randomColor = false;
    private Random myRand = null;

    public Plane()
    {
        myRand = new Random();
        setRandomColor(randomColor);
    }

    public void move(JPanel parent)
    {
        int iRight = parent.getSize().width;
        int iBottom = parent.getSize().height;

        x += 5 + (xScale * directionX);
        y += 5 + (yScale * directionY);

        if (x <= 0)
        {
            x = 0;
            directionX *= (-1);
            xScale = randomMove ? myRand.nextInt(moveX) : moveX;
            if (randomColor) setRandomColor(randomColor);
        }

        if (x >= iRight - width)
        {
            x = iRight - width;
            directionX *= (-1);
            xScale = randomMove ? myRand.nextInt(moveX) : moveX;
            if (randomColor) setRandomColor(randomColor);
        }

        if (y <= 0)
        {
            y = 0;
            directionY *= (-1);
            yScale = randomMove ? myRand.nextInt(moveY) : moveY;
            if (randomColor) setRandomColor(randomColor);
        }

        if (y >= iBottom - height)
        {
            y = iBottom - height;
            directionY *= (-1);
            yScale = randomMove ? myRand.nextInt(moveY) : moveY;
            if (randomColor) setRandomColor(randomColor);
        }
    }

    public void draw(Graphics g)
    {
        g.setColor(color);
        g.fillOval(x, y, width, height);
    }

    public void setColor(Color c)
    {
        color = c;
    }

    public void setLocation(int x, int y)
    {
        this.x = x;
        this.y = y;
    }

    public void setMoveRate(int xMove, int yMove, int xDir, int yDir, boolean randMove)
    {
        this.moveX = xMove;
        this.moveY = yMove;
        directionX  = xDir;
        directionY  = yDir;
        randomMove  = randMove;
    }

    public void setRandomColor(boolean randomColor)
    {
        this.randomColor = randomColor;

        switch (myRand.nextInt(3))
        {
            case 0:  color = Color.ORANGE;
                     break;
            case 1:  color = Color.GREEN;
                     break;
            case 2:  color = Color.RED;
                     break;
            default: color = Color.BLACK;
                     break;
        }
    }

    public void setSize(int width, int height)
    {
        this.width  = width;
        this.height = height;
    }
}

}

我希望从队列中的零个圆圈开始,然后每隔 10 秒添加一个圆圈。我希望每 15 秒后有一个圆圈从队列移动到队列底部。我已经完成了随机化圆圈,现在我的挑战是将圆圈添加到像实际队列一样的直线队列中(我希望圆圈从左到右排队,最好是在框架的顶部。当我调用 removeCircle() 时,我希望圆圈离开队列并向下移动框架。你能帮我解决 addCircle() 和 removeCircle() 方法吗?提前谢谢你。

【问题讨论】:

  • 我正在为我的作业寻求帮助。非常感谢任何帮助。
  • 我设法得到了这个,但在创建 LinkedList 以将圆圈保持在队列中时仍然面临挑战。我在这里粘贴我的代码
  • 为什么需要 LinkedLIst。只需使用 ArrayList。您可以创建 2 个摆动计时器。当“添加”计时器触发时,您将一个圆圈添加到 ArrayList。当“删除”计时器触发时,您从 ArrayList 的索引 0 中删除圆圈。所以你的基本逻辑是正确的。但是,您不需要 Timer 的 ActionListner 中的循环。计时器是循环。它将每 10/15 秒生成一个事件。如果您希望每 10/15 秒发生一次,为什么要为 Timer 使用 40 毫秒?
  • @camickr 谢谢。我现在正在使用 ArrayList。我设法取得了进展。我创建了一个应用程序。我在添加和删除方面遇到了挑战。我的程序现在可以添加 3 个圆圈,但它们不在队列中。我要他们排队。并在 5 秒后移除一圈。 10秒后加一圈。我不知道是否有办法让我分享我的代码。
  • 两个摆动计时器的问题是我得到的异常:ConcurrentModificationException。我怎样才能摆脱它??

标签: java swing canvas


【解决方案1】:

解决问题应该一次解决一个问题。在开始测试之前不要尝试编写整个程序。

因此,将您的程序分解为基础:

  1. 您需要一个计时器来让动画移动每个对象。因此,首先将单个对象添加到 ArrayList,然后当 Timer 触发时,您遍历 ArrayList 并移动每个对象。 ArrayList 中只有一个对象启动也没关系。

  2. 然后创建另一个 Timer,它每 15 秒触发一次,以将另一个对象添加到 ArrayList。

  3. 然后你添加逻辑给这个对象一个随机的颜色

  4. 然后你添加逻辑来给这个对象一个优先级。

  5. 完成上述所有操作后,您可以添加另一个 Timer 以从 ArrayList 中删除和对象。

您的代码的基本结构需要更改。

  1. 您不应该使用静态变量。因此,您需要重新设计类的结构。
  2. 您应该有一个 CirclePanel 类。此类将包含绘制对象所需的属性,因此它将包含 ArrayList。它还需要像“addCircle()”和“removeCircle()”这样的方法。这些方法将由适当的 Timer 调用。
  3. 您需要为所有定时器使用 Swing Timer,而不是 util Timer。当 Swing Timer 触发时,代码将在 Event Dispatch Thread 上执行单线程,这应该可以防止 ConcurrentModificationException 发生。

查看:How do I paint multiple objetcs that move at different speeds in Java? 以获取有助于重组的示例。

它并不能满足您的所有需求,但它是一个好的开始。它将为对象的 ArrayList 设置动画。因此,您需要修改代码以一次填充 ArrayList 一个对象并一次删除一个对象。

编辑:

如果您想添加更多圈子,则需要另一个计时器。使用我提供给您的原始代码,您可以执行以下操作:

public void startAnimation()
{
    //Timer timer = new Timer(75, this);
    //timer.start();

    Timer timer = new Timer(1000, new ActionListener()
    {
        @Override
        public void actionPerformed(ActionEvent e)
        {
            move();
            repaint();
        }
    });
    timer.start();

    Timer timer2 = new Timer(3000, new ActionListener()
    {
        @Override
        public void actionPerformed(ActionEvent e)
        {
            addBalls(1);
        }
    });
    timer2.start();
}

所以第一个 Timer 对 ArrayList 中的球进行动画处理。第二个 Timer 将一个新球添加到 ArrayList。

我会让你编写定时器来从 ArrayList 中删除一个球。我已经建议这是 ActionListener 中的单个语句。

【讨论】:

  • 我正在寻求帮助以在队列中添加圈子。就像在直线队列中一样,在 Frame 上的某个区域,最好是在队列的顶部。 .之后,我想在 15 秒后从队列中删除一个圆圈。当调用 removeCircle() 方法时,我希望一个圆圈从队列移动到圆圈的底部。你能帮忙吗?我面临挑战@camickr。
  • 编辑了我的代码。你能协助 addCircle() 方法和 removeCircle() 方法吗?我希望每 10 秒后将一个圆圈添加到队列中。每 15 秒删除一次圆圈。
  • @TOUREDEEZ,你试过什么?除了您重命名类之外,我没有看到对代码的任何更改。你有没有听过我的任何建议?为什么你仍然只有一个 Timer?我已经说过您需要额外的计时器来执行“添加”和“删除”逻辑?您在哪里尝试这样做?为什么将“addBalls(...)”方法移到构造函数中?保持的重点是分开的,因此您可以随时添加更多球。见编辑。
  • 谢谢@camickr。但是看起来我在按照您的建议构建我的谁代码时遇到了挑战。你能帮忙吗?我已经注意到计时器的问题。再次感谢您。
  • BallAnimation4.java:35:错误:BallPanel 不是抽象的,并且不会覆盖 ActionListener 静态类中的抽象方法 actionPerformed(ActionEvent) BallPanel 扩展 JPanel 实现 ActionListener ^ BallAnimation4.java:110:错误:找不到符号 addBalls(1); ^ 符号:方法 addBalls(int) 2 个错误
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-05
  • 1970-01-01
  • 2016-02-21
  • 2019-07-19
  • 1970-01-01
  • 2012-11-12
相关资源
最近更新 更多