Есть ли способ изменить размер моего JFrame без рисования лишних форм? - PullRequest
0 голосов
/ 08 мая 2019

Я пишу программу, которая рисует случайные фигуры в окне с интервалом.Я хочу, чтобы фигуры были сохранены в массиве, так как позже мне потребуется извлечь информацию о каждой из текстового файла.Это работает нормально, пока я не пытаюсь изменить размер окна.Всякий раз, когда я растягиваю его, появляется много новых фигур (быстрее, чем предполагалось), возможно, каждый раз, когда я изменяю размер, вызывается beacuse repaint (), но я не могу понять, как это предотвратить.Другими словами, как я могу предотвратить появление лишних объектов при изменении размера?

Буду признателен за любые советы, не только те, которые имеют непосредственное отношение к моему вопросу, но и любой из сделанных мной вариантов программирования.Я новичок.

Надеюсь, я дал понять.Я буду рад предоставить более подробную информацию, если вам нужно.

public Window() {
        setTitle("shapes");
        setSize(800, 600);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setBackground(Color.DARK_GRAY);
        setVisible(true);
    }

 public void paint(Graphics g) {
        addShape();
        g.clearRect(1,1, getWidth(), getHeight());
        for (Figure figure : myFigures) {
            figure.draw(g);
            System.out.println(figure.toString());
        }
    }

  public Thread drawThread() {
        return new Thread(() -> {
            while (true) {
                repaint();
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
    }

private void addShape() {
        int whichFigure = (int) (Math.random() * 3);
        switch (whichFigure) {
            case 1:
                myFigures.add(new Oval((int) (Math.random() * getWidth()), (int) (Math.random() * getHeight()), (int) (Math.random() * 100), (int) (Math.random() * 100)));
                System.out.println("oval added");
                break;
            case 2:
                myFigures.add(new Rectangle((int) (Math.random() * getWidth()), (int) (Math.random() * getHeight()), (int) (Math.random() * 100), (int) (Math.random() * 100)));
                System.out.println("rect added");
                break;
        }
    }

}

1 Ответ

3 голосов
/ 08 мая 2019

Вы не должны вызывать addShape из метода рисования. По мере того как вы обнаруживаете, вы не можете контролировать вызов методов рисования. Изменение размера - не единственное, что может вызвать рисование. Переместить или поднять окно можно. Даже навести курсор мыши на окно можно. Никогда не меняйте свои данные способом рисования.

Измените ваши данные в другом месте, например, прямо перед вызовом repaint (). Все операции Swing должны выполняться в потоке диспетчеризации событий AWT, и данные, используемые операциями Swing, также должны быть изменены в этом потоке (если вы не предпримете шаги, чтобы сделать код безопасным для потока, например, синхронизацию). Самый простой способ регулярно выполнять код в этом потоке - использовать класс javax.swing.Timer :

public Timer drawThread() {
    return new Timer(1000, new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent event) {
            addShape();
            repaint();
        }
    });
}

Обратите внимание, что, как и в Thread, для таймера должен быть вызван метод start () (или restart () ).

...