以特定间隔更新DrawString

时间:2014-01-05 09:27:15

标签: java swing timer calendar paintcomponent

我正在尝试创建一个数字时钟然后添加到JPanel,现在当我在DrawString方法之外调用taskPerformer但是在内部时,它不会画出字符串!为什么会这样,我将如何实现这个类,以便每秒重绘一次?

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;     
import javax.swing.JComponent;
import javax.swing.JPanel;
import java.util.Date;
import java.util.Calendar;
import java.util.GregorianCalendar;
import javax.swing.Timer;

class DrawDate extends JPanel {
public Date ddate;
public Calendar ccalendar = new GregorianCalendar();
Date time;

public DrawDate() {
    this.ddate = new Date();
    time = this.ccalendar.getTime();
}

 public void paint(Graphics g) {
final Graphics2D g2 = (Graphics2D)g;
Font font = new Font("Arial", Font.PLAIN, 50);
g2.setFont(font);
//THIS DRAWS THE STRING
g2.drawString(time.toString() , 100, 100); 

ActionListener taskPerformer = new ActionListener() {
    public void actionPerformed(ActionEvent evt) {
        Calendar ccalendar = new GregorianCalendar();
        Date time = ccalendar.getTime();
            //THIS DOES NOT DRAW A STRING.
            g2.drawString(time.toString() , 200, 100);

    }
};
final Timer timer = new Timer(1000, taskPerformer);
timer.start();


}
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    super.setBackground(new Color(100,100,100));
    paint(g);
}

}

3 个答案:

答案 0 :(得分:4)

基本上,您有上下文问题。 g2中没有ActionListener内容,但还有其他问题需要先解决......

请勿在{{1​​}}方法中创建ActionListenerTimer,实际上您应该完全避免覆盖paint

paint可能会调用paint,但由于您忽略了调用paintComponent,因此不会发生这种情况,因此永远不会调用您的super.paint方法。但是,您应该避免在paintComponent方法

中调用paint

相反,在构造函数之类的东西中创建paintComponentTimer。当ActionListener勾选/触发Timer方法时,只需更新您想要绘制的值,然后调用actionPerformed

repaint方法中,进行实际渲染。

请查看Performing Custom PaintingPainting in AWT and Swing了解详情

答案 1 :(得分:3)

请参阅代码中的评论提示..

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Date;
import java.util.Calendar;
import java.util.GregorianCalendar;

class DrawDate extends JPanel {

    public Date ddate;
    public Calendar ccalendar = new GregorianCalendar();
    Date time;

    public DrawDate() {
        this.ddate = new Date();
        time = this.ccalendar.getTime();

        ActionListener taskPerformer = new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                    Calendar ccalendar = new GregorianCalendar();
                    Date time = ccalendar.getTime();
                    //THIS DOES DRAW A STRING.
                    repaint();
            }
        };
        final Timer timer = new Timer(1000, taskPerformer);
        timer.start();

        // this will invoke repaint()
        // if called within a paint/paintComponent - infinite loop
        super.setBackground(new Color(100,100,100));
    }

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        final Graphics2D g2 = (Graphics2D)g;
        Font font = new Font("Arial", Font.PLAIN, 50);
        g2.setFont(font);

        // update the time
        time = new Date();
        //THIS DRAWS THE STRING
        g2.drawString(time.toString() , 10, 100);
    }

    public Dimension getPreferredSize() {
        return new Dimension(600,150);
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                JOptionPane.showMessageDialog(null, new DrawDate());
            }
        };
        SwingUtilities.invokeLater(r);
    }
}

答案 2 :(得分:3)

试试这个:

  

datePanel.add(new ClockPane());

  public class ClockPane extends JPanel {

        private JLabel clock;

        public ClockPane() {
            setLayout(new BorderLayout());
            clock = new JLabel();
            clock.setHorizontalAlignment(JLabel.CENTER);
            clock.setFont(UIManager.getFont("Label.font").deriveFont(Font.BOLD, 32f));
            tickTock();
            add(clock);

            Timer timer = new Timer(500, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    tickTock();
                }
            });
            timer.setRepeats(true);
            timer.setCoalesce(true);
            timer.setInitialDelay(0);
            timer.start();
        }

        public void tickTock() {
            clock.setText(DateFormat.getDateTimeInstance().format(new Date()));
        }
    }