Java repaint () метод не работает, когда я пытаюсь удалить фигуры с панели - PullRequest
0 голосов
/ 04 октября 2019

Я хотел бы рисовать несколько кругов каждую секунду и удалять их все (или хотя бы один) с панели.

Вот существующий код:

    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);
        }
    }

Если времябольше 3 секунд, удалите все круги, иначе продолжайте рисовать круги на экране.

Вот класс 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);
            }
        }
    }

Когда я вызываю deleteCircle (), круги должны быть удалены из списка и перекрашены. Я должен закончить с пустым экраном без кругов в нем. Я думаю, что в этом случае перекраска не работает.

PS: впервые задаю вопрос, извините, если он длинный: D

1 Ответ

1 голос
/ 04 октября 2019

Итак, две вещи сразу бросаются в глаза.

  1. Использование java.util.Timer

Swing НЕ является потокобезопасным, так как java.util.Timer работает в своем собственном потокеобновление пользовательского интерфейса (или, в данном случае, того, на что опирается пользовательский интерфейс) может привести к случайным проблемам.

Я бы рассмотрел использование вместо этого javax.swing.Timer, так как он запускается в очереди отправки событий (икак правило, проще в использовании)

Не звонит super.paint

Вы не приняли во внимание то, что делает paint, и не смогли взять на себя его обязанности, которые в данном случае означали бы "подготовить"Graphics контекст для рисования.

Graphics является общим ресурсом, который передается всем компонентам, обновленным на этапе рисования. Это означает, что он будет содержать то, что когда-либо было нарисовано ранее.

Две рекомендации:

  1. В качестве общей рекомендации предпочтительнее переопределить paintComponent вместо paint (paintвыполняет много важных заданий, поэтому, если вы не хотите их выполнять, как правило, они находятся высоко в цепочке красок)
  2. Сначала позвоните super.paintComponent, прежде чем приступить к какой-либо пользовательской раскраске.

Я очень рекомендую прочитать:

и

...