简单的GUI倒计时应该如何工作? [英] How the simples GUI countdown is supposed to work?

查看:134
本文介绍了简单的GUI倒计时应该如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写简单的GUI倒计时。我在互联网上找到了一些代码,但它对我来说已经过于花哨了。我想尽量保持简单。所以,我只想要一个窗口说你剩下10秒钟。秒数应该每秒从10减少到0.我写了一个代码。我认为我接近工作解决方案。但我仍然遗漏了一些东西。你能请求帮助我找出问题所在吗?这是我的代码:

I am trying to write the simples GUI countdown. I found in Internet some code but it is already too fancy for me. I am trying to keep it as simple as possible. So, I just want to have a window saying "You have 10 second left". The number of second should decrease every second from 10 to 0. I wrote a code. And I think I am close to the working solution. But I still missing something. Could you pleas help me to find out what is wrong? Here is my code:

import javax.swing.*;

public class Countdown {

    static JLabel label;

    // Method which defines the appearance of the window.   
    private static void showGUI() {
        JFrame frame = new JFrame("Simple Countdown");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JLabel label = new JLabel("Some Text");
        frame.add(label);
        frame.pack();
        frame.setVisible(true);
    }

    // Define a new thread in which the countdown is counting down.
    static Thread counter = new Thread() {
        public void run() {
            for (int i=10; i>0; i=i-1) {
                updateGUI(i,label);
                try {Thread.sleep(1000);} catch(InterruptedException e) {};
            }
        }
    };

    // A method which updates GUI (sets a new value of JLabel).
    private static void updateGUI(final int i, final JLabel label) {
        SwingUtilities.invokeLater(new Runnable(i,label) {

            public Runnable(int i, JLabel label) {
                this.i = i;
                this.label = label;
            }

            public void run() {
                label.setText("You have " + i + " seconds.");
            }

        });
    }

    // The main method (entry point).
    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                showGUI();
                //counter.start();
            }
        });
        //counter.start();
    }

}

我有几个具体问题此代码:

And I have several concrete question about this code:


  1. 我应该在哪里放置 counter.start(); ? (在我的代码中,我把它放在2个位置。哪一个是正确的?)

  1. Where should I place the counter.start();? (In my code I put it on 2 places. Which one is correct?)

为什么编译器会抱怨Runnable的构造函数?它说我有一个无效的方法声明,我需要指定返回的类型。

Why compiler complains about the constructor for Runnable? It says that I have an invalid method declaration and I need to specify the returned type.

ADDED:
我做了建议的更正。然后我执行代码并得到:

ADDED: I made the suggested corrections. And then I execute the code and get:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at Worker.run(Worker.java:12)

在行中的Worker.java中12我有: label.setText(你有+ i +秒。);

In the Worker.java in the line 12 I have: label.setText("You have " + i + " seconds.");.

推荐答案

在runnable中调用 counter.start()

Call counter.start() inside the runnable:

// The main method (entry point).
public static void main(String[] args) {
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            showGUI();
            counter.start();
        }
    });
}

如果你把它放在线程之外,你真的想要一个特定的调用顺序然后计数器将在GUI存在之前启动,它将失败。

You really want a specific order of invocation, if you place it outside the thread then the counter will start even before the GUI exists and it will fail on you.

对于第二个问题:

// A method which updates GUI (sets a new value of JLabel).
private static void updateGUI(final int i, final JLabel label) {
    SwingUtilities.invokeLater(new Worker(i, label));
}

这是工人:

import javax.swing.JLabel;

public class Worker implements Runnable{
    private int i;
    private JLabel label;
    public Worker(int i, JLabel label) {
        this.i = i;
        this.label = label;
    }

    public void run() {
        label.setText("You have " + i + " seconds.");
    }
}

现在主要是:

// The main method (entry point).
public static void main(String[] args) {
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            Countdown.showGUI();
            counter.start();
        }
    });
}

更新:

或者,如果您仍想使用匿名模式,那么:

UPDATE:
Or if you still want to use the anonymous pattern then:

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;

public class Countdown {

    static JLabel label;

    // Method which defines the appearance of the window.   
    public static void showGUI() {
        JFrame frame = new JFrame("Simple Countdown");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        label = new JLabel("Some Text");
        frame.add(label);
        frame.pack();
        frame.setVisible(true);
    }

    // Define a new thread in which the countdown is counting down.
    public static Thread counter = new Thread() {
        public void run() {
            for (int i=10; i>0; i=i-1) {
                updateGUI(i,label);
                try {Thread.sleep(1000);} catch(InterruptedException e) {};
            }
        }
    };

    // A method which updates GUI (sets a new value of JLabel).
    private static void updateGUI(final int i, final JLabel label) {
        SwingUtilities.invokeLater( 
            new Runnable() {
                public void run() {
                    label.setText("You have " + i + " seconds.");
                }
            }
        );
    }
}

这篇关于简单的GUI倒计时应该如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆