Reputation: 107
So I'm trying to rotate a line every second using a Timer and a paint method. However, I'm not quite sure whats going on. Here are some of the relevant methods:
public static ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent e) {
Clock cl = new Clock();
seconds++;
cl.repaint();
}
};
public void paint(Graphics g){
super.paint(g);
Graphics2D g2 = (Graphics2D) g;
for(int c = 0; c<10; c++){
g2.setPaint(Color.BLACK);
g2.drawOval(90-c/2,90-c/2,500+c,500+c); //thick outlined circle
}
g2.setPaint(Color.WHITE);
g2.fillOval(90,90,501,501);
g2.setPaint(Color.BLACK);
g2.rotate(Math.toRadians(seconds*6));
g2.drawLine(340,340,340,90);
}
The line remains stationary. However if I add
System.out.println("tick");
to my actionPerformed method, the command line spits out "tick" 3 times a second. Any ideas as to why these things are happening?
Some context:
public static int seconds = 0;
public static int minutes = 0;
public static int hours = 0;
public static Clock cl = new Clock();
private ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("tick");
seconds++;
cl.repaint();
}
};
public static Timer timer = new Timer(1000,taskPerformer);
public static void main(String[] args){
Clock cl = new Clock();
init();
SwingUtilities.invokeLater(new Runnable(){
public void run() {
createAndShowGUI();
}
});
}
public static void init(){
timer.start();
}
public Clock() {
super("Clock");
timer.addActionListener(taskPerformer);
}
Upvotes: 0
Views: 1242
Reputation: 6618
You are creating a new clock at every tick:
public void actionPerformed(ActionEvent e) {
Clock cl = new Clock();
...
Instead you should use an existing instance.
// A field in the class:
Clock cl = new Clock();
...
// removed static so that it can access cl
private ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent e) {
seconds++;
cl.repaint();
}
};
You could also make the clock a field in the action listener, if you do not need to access it elsewhere.
Also note that you generally should not be overriding paint()
, but should override paintComponent()
instead. More about custom painting in swing here.
Edit: Now that there's more code available, it's possible to say that if you make the clock and action listener static it should work. However, you need to start the timer after the relevant components are ready:
public static void main(String[] args){
// Removed spurious clock here
SwingUtilities.invokeLater(new Runnable(){
public void run() {
createAndShowGUI();
// Start the timer once the components are ready
init();
}
});
}
The above mentioned point about not creating a clock in the action listener still stands.
Upvotes: 1