我正在尝试创建一个数字时钟然后添加到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);
}
}
答案 0 :(得分:4)
基本上,您有上下文问题。 g2
中没有ActionListener
内容,但还有其他问题需要先解决......
请勿在{{1}}方法中创建ActionListener
或Timer
,实际上您应该完全避免覆盖paint
。
paint
可能会调用paint
,但由于您忽略了调用paintComponent
,因此不会发生这种情况,因此永远不会调用您的super.paint
方法。但是,您应该避免在paintComponent
方法
paint
相反,在构造函数之类的东西中创建paintComponent
和Timer
。当ActionListener
勾选/触发Timer
方法时,只需更新您想要绘制的值,然后调用actionPerformed
。
在repaint
方法中,进行实际渲染。
答案 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()));
}
}