为什么我的循环 GUI 计时器没有显示? [英] Why is my looping GUI timer not showing up?

查看:54
本文介绍了为什么我的循环 GUI 计时器没有显示?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试制作一个 GUI 计时器不使用 javax.swing.Timer(有点奇怪的任务),但我无法让它工作.它应该让线程休眠 1 秒,在 seconds 上加 1,然后重复(无限).当我运行我的程序时,图标出现,但窗口没有出现.我猜我的错误是在 Thread.sleep(1000); 行或那个区域,但我不确定为什么它不起作用.Thread.sleep(millis) 与 Swing 应用程序不兼容吗?我必须多线程吗?这是我的程序:

I'm trying to make a GUI timer without using javax.swing.Timer(kind of a strange task), but I am having trouble making it work. It's supposed to sleep the thread for 1 second, add 1 to seconds, and repeat(infinitely). When I run my program, the icon shows up, but the window does not appear. I'm guessing my error is in the Thread.sleep(1000); line or in that area, but I'm not sure why it doesn't work. Is Thread.sleep(millis)not compatible with swing applications? Do I have to multithread? Here's my program:

import java.awt.*;
import javax.swing.*;

public class GUITimer extends JFrame {
    private static final long serialVersionUID = 1L;
    private int seconds = 0;

    public GUITimer() {
        initGUI();
        pack();
        setVisible(true);
        setResizable(false);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    private void initGUI(){
        JLabel title = new JLabel("Timer");
        Font titleFont = new Font(Font.SERIF, Font.BOLD, 32);
        title.setFont(titleFont);
        title.setHorizontalAlignment(JLabel.CENTER);
        title.setBackground(Color.BLACK);
        title.setForeground(Color.WHITE);
        title.setOpaque(true);
        add(title, BorderLayout.NORTH);
        JLabel timeDisplay = new JLabel(Integer.toString(seconds));//this label shows seconds
        add(timeDisplay, BorderLayout.CENTER);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        seconds++;
        initGUI();
    }

    public static void main(String[] args) {
        try {
            String className = UIManager.getCrossPlatformLookAndFeelClassName();
            UIManager.setLookAndFeel(className);
        }
        catch (Exception e) {}

        EventQueue.invokeLater(new Runnable() {
            public void run() {
                new GUITimer();
            }
        });
    }
}


我注意到当我在我的方法 initGUI() 中将 seconds 打印到控制台时,它会正确地以一秒递增的方式打印它们.所以当它看起来像:


I noticed when I print seconds in my method initGUI() to console, it prints them incrementally by one second correctly. So when it looks like:

private void initGUI() {
    System.out.println(seconds);
    //...

它每秒打印seconds 的值(JLabel 应该如何).这表明我的循环工作正常,我的 Thread.sleep(1000) 也正常.我现在唯一的问题是框架没有显示出来.

it prints the value of seconds after every second(How the JLabel should). This shows that my loop is working fine, and my Thread.sleep(1000) is OK also. My only problem now, is that the frame is not showing up.

推荐答案

你的主窗口没有出现,因为你在构造函数中调用了无限递归.GUITimer 将不会被创建并锁定主线程.

Your main window does not appear, because you called infinite recursion inside constructor. GUITimer will not be created and this lock main thread.

为此您需要使用多线程.绘制时间的主线程,第二个线程增量并将值放入标签

You need use multithreading for this aim. Main thread for drawing time, second thread increment and put value to label

例如:

import javax.swing.*;
import java.awt.*;

public class GUITimer extends JFrame
{
    private static final long serialVersionUID = 1L;
    private int seconds = 0;
    private Thread timerThread;
    private JLabel timeDisplay;

    public GUITimer()
    {
        initGUI();
        pack();
        setVisible(true);
        setResizable(false);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    private void initGUI()
    {
        JLabel title = new JLabel("Timer");
        Font titleFont = new Font(Font.SERIF, Font.BOLD, 32);
        title.setFont(titleFont);
        title.setHorizontalAlignment(JLabel.CENTER);
        title.setBackground(Color.BLACK);
        title.setForeground(Color.WHITE);
        title.setOpaque(true);
        add(title, BorderLayout.NORTH);
        timeDisplay = new JLabel(Integer.toString(seconds));//this label shows seconds
        add(timeDisplay, BorderLayout.CENTER);
    }

    public void start()
    {
        seconds = 0;
        timerThread = new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                while(true)
                {
                    timeDisplay.setText(Integer.toString(seconds++));
                    try
                    {
                        Thread.sleep(1000L);
                    }
                    catch(InterruptedException e) {}
                }
            }
        });
        timerThread.start();
    }

    public void stop()
    {
        timerThread.interrupt();
    }

    public static void main(String[] args)
    {
        try
        {
            GUITimer timer = new GUITimer();
            timer.start();
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
}

这篇关于为什么我的循环 GUI 计时器没有显示?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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