簡體   English   中英

創建一個以用戶輸入開頭的Java GUI倒數計時器

[英]create a java gui countdown timer that starts with user input

這是github 鏈接

因此,我試圖創建一個應用程序並將其分解為3個部分,其中之一是創建一個計時器。 該計時器有兩個字段:一個用於輸入分鍾,另一個用於輸入秒。 用戶應該在幾分鍾或幾秒鍾內輸入,並在應用程序屏幕上顯示倒計時。 當計時器達到0時,它將提醒用戶。 我到處搜索,找不到Java中的倒數計時器。 我發現的都是在控制台中工作的倒數計時器或已經由開發人員而非用戶設置的預定義值的倒數計時器。

我想制作一個與Google一樣的計時器Google計時器

附言:我是一個新的自學成才的程序員。 這是我的第二個Java項目,所以我沒有太多經驗。 期待任何幫助:)

這是我的代碼:

public class TestPane extends JFrame {

private LocalDateTime startTime;
private JLabel timerLabel;
private Timer timer;
private JButton startbtn;
private JTextField timeSet;
int count;
int count_2;
private Duration duration;
private JTextField minSet;
private JTextField secSet;


public TestPane() {


    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setVisible(true);
    setSize(400,400);
    getContentPane().setLayout(new CardLayout(0, 0));

    JPanel panel = new JPanel();
    getContentPane().add(panel, "name_87856346254020");
    panel.setLayout(null);

    timerLabel = new JLabel("New label");
    timerLabel.setBounds(59, 48, 194, 14);
    panel.add(timerLabel);

    startbtn = new JButton("New button");
    startbtn.setBounds(124, 187, 89, 23);
    panel.add(startbtn);

    timeSet = new JTextField(1);
    timeSet.setBounds(106, 85, 86, 20);
    panel.add(timeSet);
    timeSet.setColumns(10);

    JLabel lblHours = new JLabel("Hours");
    lblHours.setBounds(29, 88, 46, 14);
    panel.add(lblHours);

    JLabel lblMinss = new JLabel("Mins");
    lblMinss.setBounds(29, 114, 46, 14);
    panel.add(lblMinss);

    JLabel lblSecs = new JLabel("Secs");
    lblSecs.setBounds(29, 139, 46, 14);
    panel.add(lblSecs);

    minSet = new JTextField(60);
    minSet.setBounds(75, 116, 86, 20);
    panel.add(minSet);
    minSet.setColumns(10);

    secSet = new JTextField();
    secSet.setBounds(75, 147, 86, 20);
    panel.add(secSet);
    secSet.setColumns(10);


    startbtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {

                 startbtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                timeSet.getText().trim();
                if(timeSet.getText().isEmpty()) {
                    duration = Duration.ofMinutes(count_min);
                } else {
                count_hour = Integer.parseInt(timeSet.getText());                   
                duration = Duration.ofHours(count_hour);                
                }

                minSet.getText().trim();                                
                if(minSet.getText().isEmpty()) {
                    duration = Duration.ofHours(count_hour);
                } else {
                    count_min = Integer.parseInt(minSet.getText());
                    duration = Duration.ofMinutes(count_min);                   
                }

                secSet.getText().trim();
                if(secSet.getText().isEmpty() && minSet.getText().isEmpty()) {
                duration = Duration.ofHours(count_hour);        
                } 
                else if(secSet.getText().isEmpty() && timeSet.getText().isEmpty()){
                    duration = Duration.ofMinutes(count_sec);
                }
                else {                  
                    count_sec = Integer.parseInt(secSet.getText());
                    duration = duration.ofSeconds(count_sec);
                }


                if (timer.isRunning()) {
                    timer.stop();
                    startTime = null;
                    startbtn.setText("Start");
                } 
                else {
                    startTime = LocalDateTime.now();
                    timer.start();
                    startbtn.setText("Stop");
                }

            }
        });           

        timer = new Timer(500, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {

                LocalDateTime now = LocalDateTime.now();
                Duration runningTime = Duration.between(startTime, now);
                Duration timeLeft = duration.minus(runningTime);
                if (timeLeft.isZero() || timeLeft.isNegative()) {
                    timeLeft = Duration.ZERO;
                    startbtn.doClick(); // Cheat
                }

                timerLabel.setText(format(timeLeft));
            }
        });
    }

    protected String format(Duration duration) {
        long hours = duration.toHours();
        long mins = duration.minusHours(hours).toMinutes();
        long seconds = (duration.minusMinutes(mins).toMillis() / 1000) %60;
        return String.format("%02dh %02dm %02ds", hours, mins, seconds);
    }   


    public static void main(String args[]){        
        new TestPane();
    }
}

更新:到目前為止,當用戶設置小時並將分鍾和秒留為空白時,它從小時開始倒數。 與秒相同。 但是,我無法花幾分鍾來做同樣的事情。 如果我將所有內容留空(分鍾除外),則計時器不執行任何操作。 另外,我想使計時器與小時,分鍾和秒同時工作。 截至目前,它一次只能使用一個裝置。

在此處輸入圖片說明

因此,基本思想是從Swing Timer開始。 使用它來更新UI是安全的,不會阻塞UI線程,並且可以定期重復。 有關更多詳細信息,請參見如何使用Swing計時器

由於所有計時器僅保證最短的持續時間(也就是說,它們可以等待的時間比指定的延遲時間更長),因此您不能僅通過添加期望的持續時間來依賴更新狀態值。 相反,您需要能夠計算時間點之間的時間差。

為此,我將使用Java 8中引入的Date / Time API。有關更多詳細信息,請參見Period和Duration以及Date和Time類

從那里開始,只需設置一個Timer ,計算從開始時間到現在的Duration時間並格式化結果即可

import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.Duration;
import java.time.LocalDateTime;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private LocalDateTime startTime;
        private JLabel label;
        private Timer timer;

        public TestPane() {
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.insets = new Insets(2, 2, 2, 2);
            gbc.gridwidth = GridBagConstraints.REMAINDER;

            label = new JLabel("...");
            add(label, gbc);

            JButton btn = new JButton("Start");
            btn.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (timer.isRunning()) {
                        timer.stop();
                        startTime = null;
                        btn.setText("Start");
                    } else {
                        startTime = LocalDateTime.now();
                        timer.start();
                        btn.setText("Stop");
                    }
                }
            });
            add(btn, gbc);

            timer = new Timer(500, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    LocalDateTime now = LocalDateTime.now();
                    Duration duration = Duration.between(startTime, now);
                    label.setText(format(duration));
                }
            });
        }

        protected String format(Duration duration) {
            long hours = duration.toHours();
            long mins = duration.minusHours(hours).toMinutes();
            long seconds = duration.minusMinutes(mins).toMillis() / 1000;
            return String.format("%02dh %02dm %02ds", hours, mins, seconds);
        }

    }


}

倒計時器...

此計時器開始計時。 我將如何倒數呢? 我嘗試從您的鏈接中放入代碼,但無法正常工作。 這些文檔也沒有幫助我了解太多。

這需要對Date / Time API有所了解。

基本上,您需要知道預期的持續時間(計時器應運行多長時間)以及計時器已運行的時間。 據此,您可以計算剩余時間(倒計時)

為簡單起見,我以5分鍾的Duration開始...

private Duration duration = Duration.ofMinutes(5);

每當Timer ,我只需計算運行時間並計算剩余時間...

LocalDateTime now = LocalDateTime.now();
Duration runningTime = Duration.between(startTime, now);
Duration timeLeft = duration.minus(runningTime);
if (timeLeft.isZero() || timeLeft.isNegative()) {
    timeLeft = Duration.ZERO;
    // Stop the timer and reset the UI
}

我真正所做的只是使用API​​。 我知道我最后需要一個Duration (因為這是我正在格式化的格式),所以我想保留它。 由於我還需要一個“持續時間”,以表示Timer應該運行的時間長度,因此Duration類似乎是一個不錯的起點。

我原以為我可能需要計算差值between兩個Duration S(像我一樣的runningTime ),但事實證明,所有我真正想要的是(即從其他的一個減法),它們之間的區別。

剩下的就是添加檢查以確保Timer不會出現負數時間,並且您知道“計時器”或“倒數”計時器的概念。

當您處理這些類型的問題時,從“可能”如何工作的“核心概念”入手始終是一件好事-即,從弄清楚您可能在幾秒鍾內倒計時開始。 這為您提供了一些基礎工作,從那里您可以看到API提供了哪些支持以及如何利用它來發揮自己的優勢。 在這種情況下, Duration非常簡單,並且繼續為輸出的格式提供支持

例如...

import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.Duration;
import java.time.LocalDateTime;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private LocalDateTime startTime;
        private JLabel label;
        private Timer timer;

        private Duration duration = Duration.ofMinutes(5);

        public TestPane() {
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.insets = new Insets(2, 2, 2, 2);
            gbc.gridwidth = GridBagConstraints.REMAINDER;

            label = new JLabel("...");
            add(label, gbc);

            JButton btn = new JButton("Start");
            btn.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (timer.isRunning()) {
                        timer.stop();
                        startTime = null;
                        btn.setText("Start");
                    } else {
                        startTime = LocalDateTime.now();
                        timer.start();
                        btn.setText("Stop");
                    }
                }
            });
            add(btn, gbc);

            timer = new Timer(500, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    LocalDateTime now = LocalDateTime.now();
                    Duration runningTime = Duration.between(startTime, now);
                    Duration timeLeft = duration.minus(runningTime);
                    if (timeLeft.isZero() || timeLeft.isNegative()) {
                        timeLeft = Duration.ZERO;
                        btn.doClick(); // Cheat
                    }

                    label.setText(format(timeLeft));
                }
            });
        }

        protected String format(Duration duration) {
            long hours = duration.toHours();
            long mins = duration.minusHours(hours).toMinutes();
            long seconds = duration.minusMinutes(mins).toMillis() / 1000;
            return String.format("%02dh %02dm %02ds", hours, mins, seconds);
        }

    }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM