今天在写代码的时候想实现一个定时功能:1.每隔一段时间就改变一次JLabel标签的text的颜色,2.通过一个计数器来决定改换成什么颜色,3.JLabel在JPanel中覆盖的paintComponent(Graphics g)中更改,4.用的是JLabel的setForeground()5.在注册的ActionListener中只调用repaint();现在问题是,当我启动timer的时,不论你的延迟设置的有多长,他都是立即不断的发送事件,相当于是delay = 0;但是启动timer后去getDelay()又不是零,还有就是即使你调用了stop()他仍然在继续产生事件,这是怎么回事呢~请大家帮忙想一下,希望我叙述清楚了...

解决方案 »

  1.   

    愿意看代码来解决问题的朋友:import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;public class MyTest extends JFrame { private MyPanel myPanel = null;
    public MyTest(){
    myPanel = new MyPanel();

    this.add(myPanel);
    this.pack();
    this.setVisible(true);
    }

    public void startTimer(){
    myPanel.startTimer();
    }
    /**
     * @param args
     */
    public static void main(String[] args) {
    // TODO 自动生成方法存根
    MyTest m = new MyTest();
    m.startTimer();
    }}class MyPanel extends JPanel implements ActionListener{
    private JLabel label = null;
    private Timer timer = null;
    private int fontCounter = 0;
    private int timesCounter = 0; public MyPanel(){
    label = new JLabel("Sample Text!");
    label.setFont(new Font("宋体",Font.PLAIN,12)); this.setPreferredSize(new Dimension(100,100));
    this.setBackground(Color.WHITE);
    this.setLayout(null); label.setBounds(0, 0, 100, 100); this.add(label);
    }
    public void paintComponent(Graphics g){
    super.paintComponent(g);
    // 改换JLabel的字体颜色
    switch(fontCounter){
    case 0:
    label.setForeground(Color.red);
    break;
    case 1:
    label.setForeground(Color.yellow);
    break;
    case 2:
    label.setForeground(Color.blue);
    break;
    case 3:
    label.setForeground(Color.green);
    break;
    default:
    label.setForeground(Color.black);
    break;
    }
    fontCounter = (fontCounter + 1) % 4;
    // 当次数计数器到10之后就停止timer
    timesCounter += 1;
    if(timesCounter == 10){
    timer.stop();
    timesCounter = 0;
    }
    }

    public void actionPerformed(ActionEvent e){
    repaint();
    }

    public void startTimer(){
    timer = new Timer(5000,this);
    timer.start();
    }}
      

  2.   

    paintComponent(Graphics g)方法并不是只有你主动调用时才会执行,当控件的内容有所改变时该控件会自动调用自己的paintComponent(Graphics g)。
    在你重写的paintComponent(Graphics g)方法中改变了label的前景色,而这个label是添加到MyPanel中的,于是MyPanel又会立即自动调用paintComponent(Graphics g),这样又立即改变了label的前景色,label的前景色改变后又会立即调用paintComponent(Graphics g),如此循环往复永不停止。
    解决方法:
    将paintComponent(Graphics g)中的switch块放到actionPerformed()中即可,其它不用改变,如下:
    public void actionPerformed(ActionEvent e) {
    switch (fontCounter) {
    case 0:
    label.setForeground(Color.red);
    break;
    case 1:
    label.setForeground(Color.yellow);
    break;
    case 2:
    label.setForeground(Color.blue);
    break;
    case 3:
    label.setForeground(Color.green);
    break;
    default:
    label.setForeground(Color.black);
    break;
    }
    repaint();
    }
      

  3.   

    哦~是这样啊~明白~谢谢了哈还有就是一般UI组件在构造时paint()跟paintComponent()哪个先调用呢?
      

  4.   

    正如2楼所说!
    paintComponent()是Swing提供的JComponent加入的,而paint是早期AWT的Component自带的方法,其实功能应该是一样的,只不过Swing引入了代理和MVC的一些设计思想,更加强大而已