Me gustaría dibujar algunos círculos cada segundo y eliminarlos todos (o al menos uno) del panel.

Aquí está el código existente:

    public class DrawShape {
        ShapePanel panel;
        public DrawShape(ShapePanel panel) {
            this.panel = panel;

            Timer t = new Timer();
            t.schedule(new TimerTask() {
                long startTime = System.currentTimeMillis();
                int secondsToRun = 3;
                @Override
                public void run() {
                    if (System.currentTimeMillis() - startTime > secondsToRun * 1000) {
                        panel.deleteCircle();
                        System.out.println("\t" + panel.circles.size());
                        cancel();
                    } else {
                        panel.addCircle(new Circle((int) (Math.random() * 200), (int) (Math.random() * 200)));
                        System.out.println(panel.circles.size());
                    }
                }
            }, 0, 1000);
        }
    }

Si el tiempo es superior a 3 segundos, elimine todos los círculos; de lo contrario, continúe dibujando círculos en la pantalla.

Aquí está la clase ShapePanel :

    public class ShapePanel extends JPanel {

        public List<Circle> circles = new LinkedList<Circle>();

        public ShapePanel() {

            // Setting up the frame
            JFrame frame = new JFrame();
            frame.setSize(500, 500);
            frame.setVisible(true);
            frame.setBackground(Color.black);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(this); // adding the panel to the frame
        }

        public void addCircle(Circle circle) {
            circles.add(circle);
            this.repaint();
        }

        public void deleteCircle() {
    //        circles.remove(circles.get(0));
            circles.clear(); //remove them all
            this.repaint();

        }

        @Override
        public void paint(Graphics g) {
            for (Circle c : circles) {
                g.setColor(Color.GREEN);
                g.drawOval(c.x, c.y, Circle.radius * 2, Circle.radius * 2);
            }
        }
    }

Cuando llamo a deleteCircle (), los círculos deben eliminarse de la lista y volver a pintar. Debería terminar con una pantalla en blanco sin círculos. Creo que repintar no funciona en este caso.

P.D .: la primera vez que hago una pregunta, lo siento si es larga: D

-1
Gavriil Negoita 4 oct. 2019 a las 00:46

1 respuesta

La mejor respuesta

Entonces, dos cosas me llaman la atención de inmediato.

  1. Usando java.util.Timer

Swing NO es seguro para subprocesos y dado que java.util.Timer se ejecuta en su propio subproceso, la actualización de la interfaz de usuario (o en este caso, algo en lo que se basa la interfaz de usuario) podría causarle problemas aleatorios.

Consideraría usar un javax.swing.Timer en su lugar, ya que se activa dentro de la cola de envío de eventos (y generalmente es más fácil de usar)

  1. Sin llamar a super.paint

No tomaste en consideración lo que hace paint y no asumiste sus responsabilidades, que, en este caso, serían "preparar" el contexto Graphics para pintar.

Graphics es un recurso compartido, que se pasa a todos los componentes que se actualizaron en la pasada de pintura. Esto significa que contendrá lo que se le haya pintado previamente.

Dos recomendaciones:

  1. Como recomendación general, prefiera anular paintComponent en lugar de paint (paint hace muchos trabajos importantes, por lo que, a menos que esté dispuesto a hacerlos, generalmente es muy alto en la pintura cadena)
  2. Llame a super.paintComponent primero, antes de hacer cualquier pintura personalizada.

Recomiendo encarecidamente leer:

Y

2
MadProgrammer 3 oct. 2019 a las 21:54