How to make a countdown timer with a progress bar?

How can I make it so that the progress indicator slowly drops over time?

class GamePanel extends JPanel implements MouseListener, ActionListener { private JButton quit; private JButton q; private Font loadFont; public GamePanel() { setBackground(Color.blue); // sets background color this.setLayout(null); quit = new JButton("Quit"); quit.addActionListener(this); quit.setBounds(550, 700, 100, 30); this.add(quit); q = new JButton("Questions"); q.addActionListener(this); q.setBounds(100, 100, 120, 30); this.add(q); loadFont = new Font("Serif", Font.PLAIN, 30); } public void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(Color.black); g.fillRect(80, 100, 610, 560); g.setColor(Color.white); g.fillRect(90, 110, 110, 100);// 1st column g.fillRect(90, 220, 110, 100);// g.fillRect(90, 330, 110, 100);// g.fillRect(90, 440, 110, 100);// g.fillRect(90, 550, 110, 100);// g.fillRect(210, 110, 110, 100);// 2nd column g.fillRect(210, 220, 110, 100);// g.fillRect(210, 330, 110, 100);// g.fillRect(210, 440, 110, 100);// g.fillRect(210, 550, 110, 100);// g.fillRect(330, 110, 110, 100);// 3rd column g.fillRect(330, 220, 110, 100);// g.fillRect(330, 330, 110, 100);// g.fillRect(330, 440, 110, 100);// g.fillRect(330, 550, 110, 100);// g.fillRect(450, 110, 110, 100);// 4th column g.fillRect(450, 220, 110, 100);// g.fillRect(450, 330, 110, 100);// g.fillRect(450, 440, 110, 100);// g.fillRect(450, 550, 110, 100);// g.fillRect(570, 110, 110, 100);// 5th column g.fillRect(570, 220, 110, 100);// g.fillRect(570, 330, 110, 100);// g.fillRect(570, 440, 110, 100);// g.fillRect(570, 550, 110, 100);// g.setColor(Color.green); g.setFont(loadFont); g.drawString(input + ":", 100, 710); } public void actionPerformed(ActionEvent e) { String order = e.getActionCommand(); if(order.equals("Quit")) cards.show(c, "Introduction"); if(order.equals("Questions")) cards.show(c, "Questions"); } public void mousePressed(MouseEvent e) {} public void mouseReleased(MouseEvent e) {} public void mouseClicked(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} } class QuestionPanel extends JPanel implements ActionListener { private long startTime, elapsedTime; private Timer timer; private int countdown; private Font loadFont; public QuestionPanel() { setBackground(Color.pink); // sets background color this.setLayout(null); // moved into constructor from ActionPerformed: only change layout in constructor startTime = 0; elapsedTime = 0; countdown = 590; loadFont = new Font("Segoe Script", Font.BOLD, 20); if(timer == null) {// use the biggest value possible that provides your desired time keeping precision (usually no less than 15 on Windows) timer = new Timer(100, this); startTime = System.currentTimeMillis(); // gets start time in milliseconds timer.start(); } } public void paintComponent(Graphics g) { super.paintComponent(g); g.fillRect(100, 100, 600, 25); g.setColor(Color.green); g.fillRect(105, 105, countdown, 15); g.setColor(Color.black); g.setFont(loadFont); g.drawString("" + ((System.currentTimeMillis() - startTime) / 1000.0), 100, 80); // display remaining time } public void actionPerformed(ActionEvent e) { String command = e.getActionCommand(); elapsedTime = System.currentTimeMillis() - startTime; if(elapsedTime < (5000)) { countdown--; repaint(); } else { timer.stop(); if(timer == null) { timer = new Timer(500, this); timer.start(); } } if(elapsedTime >= (5000)) // can't use == here because of limited precision of system clock cards.show(c, "Correct!"); } } class AnswerPanel extends JPanel implements ActionListener { private JButton revert; public AnswerPanel() { setBackground(Color.yellow); // sets background color this.setLayout(null); revert = new JButton("Back"); revert.addActionListener(this); revert.setBounds(340, 700, 100, 30); this.add(revert); } public void paintComponent(Graphics g) { super.paintComponent(g); } public void actionPerformed(ActionEvent e) { String directive = e.getActionCommand(); if(directive.equals("Back")) cards.show(c, "Start"); } } class FailPanel extends JPanel implements ActionListener { private JButton turnaround; public FailPanel() { setBackground(Color.green); // sets background color this.setLayout(null); turnaround = new JButton("Back"); turnaround.addActionListener(this); turnaround.setBounds(340, 700, 100, 30); this.add(turnaround); } public void paintComponent(Graphics g) { super.paintComponent(g); } public void actionPerformed(ActionEvent e) { String bidding = e.getActionCommand(); if(bidding.equals("Back")) cards.show(c, "Start"); } } }// end of the entire program 
+3
source share
3 answers

Sorry, I still could not find the motivation to actually read your code, but just put together this example based on the question. See if you get some ideas.

Note that this is SSCCE and uses only 40 lines of code.

 import java.awt.event.*; import javax.swing.*; class CountDownProgressBar { Timer timer; JProgressBar progressBar; CountDownProgressBar() { progressBar = new JProgressBar(JProgressBar.VERTICAL, 0, 10); progressBar.setValue(10); ActionListener listener = new ActionListener() { int counter = 10; public void actionPerformed(ActionEvent ae) { counter--; progressBar.setValue(counter); if (counter<1) { JOptionPane.showMessageDialog(null, "Kaboom!"); timer.stop(); } } }; timer = new Timer(1000, listener); timer.start(); JOptionPane.showMessageDialog(null, progressBar); } public static void main(String[] args) { SwingUtilities.invokeLater( new Runnable() { public void run() { CountDownProgressBar cdpb = new CountDownProgressBar(); } }); } } 
+11
source

In appearance, is all this code in a large Java file? It is a bad idea.

You must have a good reason for defining a class as an inner class, and from its appearance you do not have one for QuestionPanel and others.

As for the problem, your paintComponent method is called every time your counter is updated, which is now about once every 0.1 seconds, but you only tick 1 pixel every time you update, so by the end of 5 seconds, you have cut off 10 * 5 pixels (50). What you need to do is update the progress bar with another mechanism, such as calculating the current processed time:

 long processed = System.currentTimeMillis() - startTime; double percent = Math.max(0, 1 - processed / 5000.0); int width = (int)(590 * percent); 
+4
source

This is definitely too much information and a very broad question. I would say that you only need to include the code for the class where the timer is located, and the class in which the progress bar is displayed.

When shooting the code, I assume that you are using a rectangle to draw a progress bar. Based on this, one of the ways you could do this would be to use a variable to preserve the bandwidth, and each time the timer goes off, reduce the bandwidth by a predetermined amount. Then just set the width of the rectangle drawn to the value stored in the variable.

+2
source

All Articles