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

时间:2011-05-09 02:32:25

标签: java swing timer long-integer jprogressbar

我怎样才能使进度条慢慢降低时间限制?

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 个答案:

答案 0 :(得分:11)

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

请注意,它是一个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();
            }
        });
    }
}

答案 1 :(得分:4)

从它的外观来看,所有这些代码都在一个大的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);

答案 2 :(得分:2)

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

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