Java-在运行时摆动计时器,带有启用/禁用按钮

Java-在运行时摆动计时器,带有启用/禁用按钮,java,swing,timer,do-while,Java,Swing,Timer,Do While,在这里搜索了三天,找到了一些答案,但不知道如何实施解决方案。因此,我将代码恢复到第一个版本,并决定询问 我的代码有两个问题,关于线程和并发性的阅读并没有解释如何多使用swing定时器,如何在循环中启动和停止定时器,以及如何在定时器启动时禁用按钮,以及如何在定时器停止时重新启用 当你点击按钮时,它将滚动模具,计时器必须按顺序执行该次数并停止,但如果模具编号为6,则必须在 “do{timer loop}while(die==6);” 在我的代码中,按钮不会被禁用。若滚动6,计时器将立即关闭,而无需等

在这里搜索了三天,找到了一些答案,但不知道如何实施解决方案。因此,我将代码恢复到第一个版本,并决定询问

我的代码有两个问题,关于线程和并发性的阅读并没有解释如何多使用swing定时器,如何在循环中启动和停止定时器,以及如何在定时器启动时禁用按钮,以及如何在定时器停止时重新启用

当你点击按钮时,它将滚动模具,计时器必须按顺序执行该次数并停止,但如果模具编号为6,则必须在

“do{timer loop}while(die==6);”

在我的代码中,按钮不会被禁用。若滚动6,计时器将立即关闭,而无需等待完成之前的移动,并且您可以在所有操作完成之前单击按钮,使JLabel移动更加混乱

有人能告诉我怎么做吗?我还有更多的东西要写,需要看看这个例子,并从中学习

求你了

提前感谢您的理解

代码如下:

    import java.awt.EventQueue;
    import java.awt.Toolkit;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import static java.lang.Math.random;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JButton;
    import javax.swing.Timer;

    public class RunPhysics extends JFrame {
        private final int waits = 200;
        private JLabel blackBoard = new JLabel();
        private JLabel label = new JLabel("a=F/m -> O");
        private JButton roll = new JButton("Roll");
        private int labelX = 10;
        private int labelY = 60;
        private int die;
        private Timer timer;

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

        public RunPhysics() {
            setSize(1000, 200);
            setTitle("Running Physics");
            setLayout(null);
            setDefaultCloseOperation(DISPOSE_ON_CLOSE);
            setVisible(true);
            getContentPane().add(blackBoard);
            blackBoard.setBounds(10, 10, 980, 280);
            blackBoard.add(label);
            blackBoard.add(roll);
            label.setBounds(30, 50, 100, 20);
            roll.setBounds(10, 10, 60, 30);


            roll.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent roller) {
                    do {labelX = 10;
                        die = (int)(random()*6+1);
                        roll.setEnabled(false);
        System.out.println(die + " was rolled.");
                        timer = new Timer( waits, new ActionListener() {
                            @Override
                            public void actionPerformed(ActionEvent mover) {
                                Toolkit.getDefaultToolkit().beep();
                                label.setLocation(labelX, labelY);    
                                if (labelX >= 900) {((Timer)mover.getSource()).stop();}
                                else { labelX+=36; }
                            }
                        });
                        timer.start();
                    } while (die == 6); // “Dice” is the plural form of the singular noun “Die”.
                    roll.setEnabled(true);
        System.out.println("~~~~~~~~~~~~~~~~~~~~");
                }
            });
        }
    }

按钮的ActionListener负责启动动画。因此,您所要做的就是设置组件的属性,然后启动动画。所以它可能看起来像:

roll.addActionListener(new ActionListener()
{
    @Override
    public void actionPerformed(ActionEvent roller)
    {
        // disable the roll button
        // set the labelX to its start value
        // set the label location
        // start the timer
    }
});
timer = new Timer( waits, new ActionListener()
{
    @Override
    public void actionPerformed(ActionEvent mover)
    {
        // do the basic animation

        // 1. increment the labelX value
        // 2. set the location of the label

        // determine when to stop the animation 

        if (your stop condition is satisfied)
        {
            // stop the timeer
            // enable the roll button

            int die = (int)(random()*6+1);
            System.out.println(die + " was rolled.");

            //  auto restart the animation

            if (die > 4) // make it easier to test auto repeat
            {
                // Reset the component properties and restart the timer.
                // The code here is the same as the code for the roll button
                // that is why I suggested you create a method
            }
        }
    }
});
计时器ActionListener然后负责:

  • 原创动画
  • 确定何时停止动画
  • 根据骰子的滚动重新启动动画
  • 因此,代码应该在类的构造函数中定义(而不是在按钮的ActionListener中),并且可能类似于:

    roll.addActionListener(new ActionListener()
    {
        @Override
        public void actionPerformed(ActionEvent roller)
        {
            // disable the roll button
            // set the labelX to its start value
            // set the label location
            // start the timer
        }
    });
    
    timer = new Timer( waits, new ActionListener()
    {
        @Override
        public void actionPerformed(ActionEvent mover)
        {
            // do the basic animation
    
            // 1. increment the labelX value
            // 2. set the location of the label
    
            // determine when to stop the animation 
    
            if (your stop condition is satisfied)
            {
                // stop the timeer
                // enable the roll button
    
                int die = (int)(random()*6+1);
                System.out.println(die + " was rolled.");
    
                //  auto restart the animation
    
                if (die > 4) // make it easier to test auto repeat
                {
                    // Reset the component properties and restart the timer.
                    // The code here is the same as the code for the roll button
                    // that is why I suggested you create a method
                }
            }
        }
    });
    
    再次说明这个答案的要点是理解分离

  • 用户开始某种处理
  • 让计时器负责其动画,并知道何时停止/重新启动动画

  • 它可能不完全是您想要的,但应该为您提供更好的结构的基础,以实现您的确切需求。

    阅读有关线程和并发性的内容并不能解释如何多使用swing timer,如何在循环中启动和停止计时器
    ——这是因为计时器
    取代了循环。摆脱循环。计时器将在您指定的时间段生成一个事件。是的,计时器将一步一步地循环移动JLabel。它取代了原来的for循环。现在,如何将它放入另一个计时器中,以替换WHILE?您不需要WHILE循环!当某些事件发生时,您停止计时器。也许用户点击了一个按钮或键入了一个特定的键。我正在尝试摆脱DO。事件是如果单击按钮滚动6,则计时器循环必须再次运行,如果不是6,则计时器循环不运行。请看代码。创建一个包含两个按钮的框架,开始和停止。启动按钮将启动计时器。当计时器启动时,您只需显示当前时间。停止按钮将停止计时器。一旦了解了基于用户事件启动/停止计时器的基本知识,就可以将这些知识应用到实际应用程序中。这个过程就是简化问题的方法。如果你仍然无法使用这些代码,你可以在论坛上发布一些简单的代码。谢谢。我一直在尝试这个方法,花了一些时间来更好地理解它。需要从根本上改变思维方式,20年的循序渐进式结构只是一种负担。计时器自行循环我们告诉它的内容,在我们引导它时动态地分支,并在我们放置下一个任务时循环它们。