Swing - проблема со списками, не работающими внутри метода paintComponent

1

Я пытаюсь отобразить позиции нескольких fighters экране. Соответствующий код выглядит следующим образом:

public void run() {
        double ns = 1000000000.0 / tps;
        double delta = 0;

        int frames = 0;
        int updates = 0;

        long lastTime = System.nanoTime();
        long timer = System.currentTimeMillis();

        while (running) {
            long now = System.nanoTime();

            delta += (now - lastTime) / ns;
            lastTime = now;

            while(delta >= 1) {
                update();
                updates++;
                delta--;
            }

            frame.getContentPane().repaint();
            frames++;

            if(System.currentTimeMillis() - timer >= 1000) {
                timer += 1000;
                frame.setTitle(title + "  |  " + updates + " ups, " + frames + " fps");
                frames = 0;
                updates = 0;
            }
        }

        stop();
    }

    private void update() {

         if (Math.random() < .1) {

            Fighter newFighter = new Fighter();
            fighterList.add(newFighter);

        } 

    }
    public void paintComponent(Graphics g) {
          super.paintComponent(g);  // paint background
          setBackground(Color.BLUE);
          System.out.println(fighterList.size());
          for (int i = 0; i<fighters; i++) {
              System.out.println("Attempted");
              g.setColor(Color.GREEN);
              g.drawRect((int) fighterList.get(i).xPos,
                      (int) fighterList.get(i).yPos,
                      fighterList.get(i).radius,
                      fighterList.get(i).radius);
              System.out.println("Rendered");
          }

       }
public static void main(String[] args) {
        Game game = new Game();
        game.frame.setContentPane(new Game());
        game.frame.setResizable(false);
        game.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        game.frame.setLocationRelativeTo(null); 
        game.frame.setVisible(true); 

        game.start();


    } 

Проблема в том, что на экран ничего не рисуется. Кроме того, работает System.out.println(fighterList.size()); дает разные выходы на основе того, где он запускается - при запуске внутри paintComponent он всегда возвращает ноль, но при запуске внутри update он возвращает правильную сумму. Это проблема с областью действия, или есть что-то еще, что мне не хватает?

  • 1
    1) «Соответствующий код выглядит следующим образом:« Для более быстрой помощи, опубликуйте MCVE ( пример минимальной полной проверки ) или SSCCE (короткий, самодостаточный , правильный пример). 2) Используйте логическую и последовательную форму отступа строк и блоков кода. Отступы предназначены для облегчения отслеживания потока кода!
Теги:
swing
paint

1 ответ

2
Лучший ответ

Скорее всего, проблема синхронизации. Ваш метод paintComponent() всегда вызывается из EDT (Thread Dispatch Thread), в то время как ваш метод run() работает в своем отдельном потоке. Здесь вызывается update() который добавляет новый Fighter в список.

Вам нужна правильная синхронизация, так что обе (или все) потоки будут видеть одни и те же согласованные данные.

Кроме того, поскольку ваша модель (данные) может быть изменена во время перерисовки, вы также должны "клонировать" модель, чтобы избежать окрашивания непоследовательной модели. Или, если вы не хотите клонировать его, синхронизируйте доступ к модели, чтобы она не могла быть изменена во время ее раскраски.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню