Java 间隔后在Swing JComponent中重新绘制
我被分配了一个项目,我必须使用java中的GregorianCalendar对象制作一个模拟时钟。首先,我们被告知让时钟工作,以便它在每次运行时显示正确的时间。然后我们被告知让时钟每运行一秒就重新绘制一次。我创建了一个timer对象,并认为我可以添加一个ActionListener,并在每次调用actionPerformed时重新绘制它,但很明显,重新绘制不能以这种方式使用。这是我的密码:Java 间隔后在Swing JComponent中重新绘制,java,swing,timer,repaint,graphics2d,Java,Swing,Timer,Repaint,Graphics2d,我被分配了一个项目,我必须使用java中的GregorianCalendar对象制作一个模拟时钟。首先,我们被告知让时钟工作,以便它在每次运行时显示正确的时间。然后我们被告知让时钟每运行一秒就重新绘制一次。我创建了一个timer对象,并认为我可以添加一个ActionListener,并在每次调用actionPerformed时重新绘制它,但很明显,重新绘制不能以这种方式使用。这是我的密码: import javax.swing.*; import java.awt.event.*
import javax.swing.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.awt.*;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Date;
import javax.swing.Timer;
import java.lang.Math;
public class SwingClock {
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
MyFrame frame = new MyFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ActionListener listener = new TimePrinter();
Timer t = new Timer(1000, listener);
GregorianCalendar calendar = new GregorianCalendar();
t.start();
frame.setVisible(true);
}
});
}
}
class TimePrinter implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
//I'd like to repaint here every second, but I can't
}
}
class MyFrame extends JFrame
{
public MyFrame()
{
setTitle("Swing Clock");
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
MyComponent component = new MyComponent();
add(component);
}
public static final int DEFAULT_WIDTH = 500;
public static final int DEFAULT_HEIGHT = 500;
}
class MyComponent extends JComponent
{
public void paint(Graphics g)
{
Graphics2D g2 = (Graphics2D)g;
int leftX = 50, topY = 50, width = 300, height = 300;
Rectangle2D rect = new Rectangle2D.Double(leftX, topY, width, height);
Ellipse2D clockFace = new Ellipse2D.Double();
clockFace.setFrame(rect);
g2.draw(clockFace);
double centerX = clockFace.getCenterX();
double centerY = clockFace.getCenterY();
GregorianCalendar calendar = new GregorianCalendar();
int hour = calendar.get(Calendar.HOUR_OF_DAY);
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);
double minusMinute = (90 - (minute*6))*(Math.PI/180);
double minuteCosine = Math.cos(minusMinute);
double minuteSine = Math.sin(minusMinute);
double minusSecond = (90 - (second*6))*(Math.PI/180);
double secondCosine = Math.cos(minusSecond);
double secondSine = Math.sin(minusSecond);
double hourTheta = (90-(hour+(minute/60)*30))*(Math.PI/180);
g2.draw(new Line2D.Double(centerX,centerY,centerX+50*(Math.cos(hourTheta)),
centerY - 50*(Math.sin(hourTheta))));
g2.draw(new Line2D.Double(centerX,centerY,centerX+150*(minuteCosine),centerY-150*(minuteSine)));
g2.draw(new Line2D.Double(centerX, centerY, centerX+100*secondCosine,
centerY-100*(secondSine)));
}
}
有什么办法可以解决这个问题吗?也许我弄错了?“使用Swing程序而不是重写
paint()
”,尽管正如您将看到的,这根本不是必需的。其次,你使用的是正确的。第三,为什么不简化自己,使用JLabel
实例来显示时间呢?您只需重写侦听器的构造函数:
class TimePrinter implements ActionListener
{
private MyFrame frame;
TimePrinter(MyFrame frame){
this.frame=frame;
}
public void actionPerformed(ActionEvent event)
{
frame.repaint();
}
}
MyFrame frame = new MyFrame();
ActionListener listener = new TimePrinter(frame);
嗯,你不是有一个向后的kemosabe吗?他应该重写paintComponent,而不是paint(如果他需要自定义绘制)?我可以用actionListener以这种方式重新绘制组件吗?@Tom:Swing定时器使用actionListener,所以是的,好的,使用actionListener来更改程序状态,然后在必要时调用repaint来触发重新绘制()。不过,我支持投票,只是修改了一个JLabel的文本,而不去麻烦定制绘画。@HovercraftFullOfEels,我说错了。