Java Swing 如何让这个计数器工作?

3
每当我的计数器达到4时,我希望它播放一个蜂鸣声并回到“1”,然后再次计数到4并播放蜂鸣声,依此类推。
我可能不应该把这个放在一个标签里,因为计数器根本没有运行!我没有收到任何错误消息,但标签显示; 计数器是4,不计数或其他任何东西。
你能帮我使这个计数器正常工作吗?我也使用了printline,但那也出现了一些错误。
我的计数器代码如下:
button1.addActionListener(new ActionListener() {

  public void actionPerformed(ActionEvent arg0) {

    label1.setVisible(true);
    int counter = 1;

    while(counter < 5 )
    {
      label1.setText("counter  is " + counter);
      counter = counter + 1 ;
    }

    counter = 1;
    tk.beep();
  }
});

1
你遇到了什么错误? - Harry Joy
1
我没有收到任何错误信息,标签显示计数器为4并保持不变,没有计数器。 - Opoe
在更改标签的值后,请尝试调用validate()repaint() - Harry Joy
这是因为 while 循环在重绘周期之间执行,即如果您单击按钮,则标签的文本将设置为“计数器为1”,然后是2、3和4。之后,标签被重新绘制,您会看到“计数器为4”。 - Thomas
我会直接将计数器存储在ActionListener中,因为我假设您想要存储点击次数。 - Thomas
5个回答

5

创建一个新线程来计数、等待和更新GUI。

您正在事件分派线程中进行所有这些工作,这是唯一更新GUI的线程。因此,当您设置标签的文本时,它不会在屏幕上更新,直到方法返回并且事件分派线程处理重绘操作。

您需要创建一个新线程来执行此操作,而不仅仅是在立即执行的循环中运行它。只需让actionPerformed方法生成一个新的Thread来处理此操作。在该线程中循环、计数和更新,每次更新之间使用Thread.sleep等待。要更新标签文本,请创建一个新的Runnable,将其放在事件分派线程上以将标签更新为下一个值,使用SwingUtilities.invokeLater。保持这个线程在后台运行,直到您需要它。我建议在每次循环中检查关闭状态布尔值,并在设置为false时退出。这样,您可以随时清洁地关闭线程。或者,如果您希望它倒计时并发出哔哔声仅一次,则可以在一个计数迭代后使线程结束。

关于每个步骤的详细信息,在Stack Overflow上有很多问题,因此我不会在此重复这些信息。


1
也许这正是你想要的,每按下第四个按钮它就会重置并发出哔哔声。
loginButton.addActionListener(new java.awt.event.ActionListener() {

    int counter = 1;

    public void actionPerformed(ActionEvent arg0) {

        label1.setVisible(true);

        if (counter < 5) {
            label1.setText("counter  is " + counter);
            label1.repaint();
            ++counter;
        } else {
            counter = 1;
            tk.beep();
        }
    }
});

我在使用repaint()时遇到了错误,我应该在它前面加什么? - Opoe
1
@Oppe,抱歉我已经更新了,它当然应该在你的标签上。 - vickirk

1

如果我理解你的意思正确,下面的代码应该可以实现你的目标。

button1.addActionListener(new ActionListener() {

  public void actionPerformed(ActionEvent arg0) {

    label1.setVisible(true);

    Runnable runnable = new Runnable() {
           int counter =1 ;

           public void run() {
               while(true) {

                    while (counter<5)  {
                        SwingUtilties.invokeLater(new Runnable() {
                               public void run() {
                                   label1.setText("counter  is " + counter);
                               }
                        }); 

                        counter = counter + 1 ;
                        try {
                           Thread.sleep(1000);
                        }catch(InterruptedException ex) {
                            System.err.println(ex.toString());

                        }    
                    } 
                counter = 1;
                tk.beep();

                }

           }
    };

     new Thread(runnable).start();

});

1

在更改值后,您需要重新绘制。此外,我假设您实际上想要计算秒数,因此需要使用定时器来启动更改标签和可能播放声音的操作。


0

你的循环在第一个4之后停止了,再也没有被调用。由于文本变化太快,你只能看到最后的结果。

int counter = 0;
while (//when do you want it to stop?)
{
    // print what you want (using (counter % 4) + 1)
    if ((counter % 4) == 0)
    {
         tk.beep();
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接