【问题标题】:Java: Optimizing a while(true) loop [duplicate]Java:优化while(true)循环[重复]
【发布时间】:2019-02-19 14:30:01
【问题描述】:

我正在创建一个获取时间并将其显示在 JFrame 中的程序(它还将背景更新为颜色 #[HOUR][MIN][SEC],如 on rhysperry.co.nf )。我的问题是定时器接缝仅每 2-4 秒更新一次(在低端机器上)。我有代码,想知道如何优化一个已经很小的程序。

由于我还没有完全理解 Java,请容忍不良的编码习惯。

这是我的代码 - Window.java:

import javax.swing.*;
import java.awt.*;
import java.io.IOException;
import java.io.InputStream;
import java.util.Calendar;
import java.util.concurrent.TimeUnit;


public class Window {
    /**
     * Simple color changing clock based on the website the website <a href="http://rhysperry.co.nf">rhysperry.co.nf</a>
     *
     * @author Rhys Perry
     */
    public static void main(String[] args) throws IOException, FontFormatException, InterruptedException {

        //Import font
        InputStream in = Window.class.getResourceAsStream("Lato-Hairline.ttf");
        Font font = Font.createFont(Font.TRUETYPE_FONT, in).deriveFont(50f);

        //Initialise the Frame, Panel and label
        JFrame frame= new JFrame("Hex Clock");

        JPanel panel = new JPanel();
        panel.setLayout(new FlowLayout());

        JLabel label = new JLabel();
        label.setFont(font);
        label.setPreferredSize(new Dimension(200, 350));
        label.setForeground(Color.WHITE);

        //Merge Frame, Panel and "This is a test")Label. Make window visible
        panel.add(label);
        frame.add(panel);
        frame.setSize(700, 400);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        //Setup calendar
        Calendar calendar;

        //Initialise some variables to do with time management
        String formattedhour;
        String formattedmin;
        String formattedsec;

        //Main loop to get the time and update the background ad Label
        while(true) {
            //Get hours, minutes and seconds
            calendar = Calendar.getInstance();
            int hour = calendar.get(Calendar.HOUR_OF_DAY);
            if (hour < 10) { formattedhour = "0" + hour; } else { formattedhour = hour + "";}
            int min = calendar.get(Calendar.MINUTE);
            if (min < 10) { formattedmin = "0" + min; } else { formattedmin = min + "";}
            int sec = calendar.get(Calendar.SECOND);
            if (sec < 10) { formattedsec = "0" + sec; } else { formattedsec = sec + "";}

            //Format and update the necessary components
            String time = formattedhour + ":" + formattedmin + " " + formattedsec;
            label.setText(time);
            String hex = "#" + formattedhour + formattedmin + formattedsec;
            panel.setBackground(Color.decode(hex));
            panel.repaint();
        }

    }

}

【问题讨论】:

  • 你不需要“优化”那个while循环,你需要摆脱它。完全地。而是使用适当的工具在 Swing GUI 中重复代码,Swing Timer。请查看教程链接。
  • 您最好摆脱繁忙的循环并使用Timer 来更新屏幕。一个例子是this question
  • 老兄,你的代码吃掉了 CPU 打开任务管理器并在运行时检查 CPU 使用率。这就是为什么看到实际变化有点晚了。
  • 谢谢,我去看看。 **每个经验丰富的程序员都可能讨厌该代码

标签: java swing loops time


【解决方案1】:

您可以改用 javax.swing.Timmer。它在时间间隔后重复执行任务。 https://docs.oracle.com/javase/7/docs/api/javax/swing/Timer.html

   ActionListener taskPerformer = new ActionListener() {
        public void actionPerformed(ActionEvent evt) {
            //...Perform a task...

        }
    };
    Timer timer = new Timer(10 ,taskPerformer);
    timer.start();

【讨论】:

  • 永远不要使用 0 作为定时器延迟。使用一个有意义的值,这是合理的。您可能还想稍微改进一下答案,使其更加充实。
  • 我很抱歉我的愚蠢,但我似乎无法让它工作。如何让在 actionPerformed() 之外定义的变量在 actionPerformed() 中工作?
  • 为类创建全局变量。或者我一直喜欢的最好方法是在类中创建一个公共函数并在 actionPerformed() 中调用它。
猜你喜欢
  • 2018-03-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-13
  • 1970-01-01
  • 2016-03-18
  • 2023-03-18
  • 1970-01-01
  • 2023-04-01
相关资源
最近更新 更多