如何使定时器倒计时与进度条一起?

如何使进度条慢慢降低时间限制?

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)) // 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 

对不起,我仍然找不到实际阅读代码的动机,但只是根据问题汇总了这个例子。 看看它是否给你一些想法。

请注意,它是一个SSCCE,总共只使用40行代码。

 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(); } }); } } 

从它的外观来看,所有这些代码都在一个大的Java文件中? 这是个坏主意。

你应该有一个很好的理由将一个类定义为一个内部类,从它的外观来看,你没有一个用于QuestionPanel和其他类。

至于问题,每次更新计数器时都会调用paintComponent方法,现在大约每0.1秒调用一次,但每次更新时只需按1个像素,所以在5秒结束时,你会减少关闭10 * 5像素(50)。 您应该做的是通过不同的机制更新进度条,例如计算当前处理的时间:

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

这绝对是太多的信息,而且是一个非常广泛的问题。 我说最多你只需要包含定时器所在类的代码,以及绘制进度条的类。

从略读代码,我猜你正在使用矩形来绘制进度条。 基于此,您可以采用的一种方法是使用变量来存储条形的宽度,并且每次计时器滴答时,将条形的宽度减小一定量。 然后只需将绘制的矩形的宽度设置为存储在变量中的值。