我已经分配了一个项目,我必须使用java中的GregorianCalendar对象制作模拟时钟。首先,我们被告知让时钟工作,以便它在每次运行中显示适当的时间。然后我们被告知让它每秒运行一次。我制作了一个计时器对象,并认为我可以添加一个ActionListener,并在每次调用actionPerformed时重新绘制它,但重绘显然不能以这种方式使用。这是我的代码:在间隔之后重新绘制Swing JComponent
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)));
}
}
有关如何解决此问题的任何想法?也许我错了?
恩,你没有那个倒退kemosabe - 他**应该**重写paintComponent,而不是绘画(如果他需要做自定义绘画)? –
我可以使用actionListener以这种方式重绘组件吗? – Tom
@Tom:Swing Timers使用ActionListeners,所以很好,使用ActionListener来更改程序状态,然后在必要时通过调用repaint()来触发重绘。然而,我第二次投票只是改变了JLabel的文本,而不是为了定制绘画而烦恼。 –