I would like to draw a new random shape every 2 seconds.
I already have a window, that shows immediately some shapes. I tried to mess around with Timer to make new things appear in the window after a few seconds, but it didn't work, or the whole program freezes. Is it a good idea to use Timer? How should I implement it, to make it work?
import javax.swing.*;
import java.awt.*;
import java.util.Random;
class Window extends JFrame {
Random rand = new Random();
int x = rand.nextInt(1024);
int y = rand.nextInt(768);
int shape = rand.nextInt(2);
Window(){
setSize(1024,768);
setVisible(true);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public void paint(Graphics g) {
super.paint(g);
g.setColor(new Color(0, 52, 255));
switch(shape) {
case 0:
g.fillOval(x, y, 50, 50);
break;
case 1:
g.fillRect(x,y,100,100);
break;
}
repaint();
}
}
public class Main {
public static void main(String[] args) {
Window window = new Window();
}
}
I would also like to draw some random shapes. Is it ok, to use switch in paint method for this purpose? I would make a random variable, if it's 1 it would paint rectangle, if it's 2 it would paint oval etc.
First of all, do not change the way JFrame
gets painted (with other words, do not override paintComponent()
of a JFrame
). Create an extending class of JPanel
and paint the JPanel
instead. Secondly, do not override paint()
method. Override paintComponent()
. Thirdly, always run Swing applications with SwingUtilities.invokeLater()
since they should run in their own thread named EDT (Event dispatch thread). Finally, javax.swing.Timer
is what you are looking for.
Take a look at this example. It paints an oval shape in random X,Y every 1500ms.
Preview:
Source code:
import java.awt.BorderLayout;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class DrawShapes extends JFrame {
private ShapePanel shape;
public DrawShapes() {
super("Random shapes");
getContentPane().setLayout(new BorderLayout());
getContentPane().add(shape = new ShapePanel(), BorderLayout.CENTER);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(500, 500);
setLocationRelativeTo(null);
initTimer();
}
private void initTimer() {
Timer t = new Timer(1500, e -> {
shape.randomizeXY();
shape.repaint();
});
t.start();
}
public static class ShapePanel extends JPanel {
private int x, y;
public ShapePanel() {
randomizeXY();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.fillOval(x, y, 10, 10);
}
public void randomizeXY() {
x = (int) (Math.random() * 500);
y = (int) (Math.random() * 500);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new DrawShapes().setVisible(true));
}
}