I've made a circle move around (in a circle), but now my application won't move on to the other tasks as I got myself caught in a loop.
How do I get out of this and still have my circle moving in the background?
- I know it is because I keep calling the method draw();, but how should I else keep this circle being drawn?
public class MyFrame extends JPanel {
int xc = 150, yc = 150, r = 100, diam = 50;
double inc = Math.PI/360, theta = 0;
public void draw(Graphics g) {
Timer timer = new Timer(0, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
theta = theta inc;
repaint();
System.out.println(theta);
}
});
timer.setDelay(20);
timer.start();
}
@Override
public void paint(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON ); //smooth the border around the circle
g2d.rotate(theta, xc, yc);
g2d.setColor(Color.blue);
g2d.drawOval(xc r - diam / 2, yc r - diam / 2, diam, diam);
draw(g);
}
}
CodePudding user response:
Separate the looping, the timer, from the painting. Let the timer change the state of the key variable(s) and then call repaint. So you can create and start the Timer outside of a painting method, such as within a constructor, and leave the paintComponent to concentrate on one thing and one thing alone, painting, and not changing state:
public class MyPanel extends JPanel {
int xc = 150, yc = 150, r = 100, diam = 50;
double inc = Math.PI/360, theta = 0;
public MyPanel () {
Timer timer = new Timer(20, e -> {
theta = inc;
repaint();
});
timer.start();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON );
g2d.rotate(theta, xc, yc);
g2d.setColor(Color.blue);
g2d.drawOval(xc r - diam / 2, yc r - diam / 2, diam, diam);
}
}