2015-05-04 3 views
0

Я использую нить, чтобы перерисовать JPanel (видя, как repaint() является потокобезопасным).Thread.join() не работает как ожидалось

Вот метод paintComponent:

public void paintComponent(Graphics g) { 
    super.paintComponent(g); 
    //Print statement so I know where my program is at. 
    System.out.println("Repainting world..."); 
    g.drawImage(worldImage, x, y, 6144, 4608, null); 
} 

У меня есть поток, который начинается внутри KeyListener всякий раз, когда пользователь нажимает определенную кнопку

метод Run:

public void run(){ 
       game.repaint(); 
} 

Наконец, вот мои призывы к нити, использующей вышеуказанный метод:

//NOTE: I've tried this without the if statement, made no difference 
if(!gameThread.isAlive()){ 
    gameThread.start(); 
    try { 
      gameThread.join(); 
    } catch (InterruptedException e) { 
      e.printStackTrace(); 
    } 
} 

Я уверен, что в этом случае (поскольку он находится в KeyListener), Thread.join() останавливает EDT до тех пор, пока этот метод выполнения не будет выполнен.

Проблема заключается в том, что Thread.join бросает InterruptedException всякий раз, когда я снова нажимаю кнопку, независимо от того, как долго я жду. Это заставляет меня поверить, что где-то его повесили в области, где нить не остановит ее выполнение. Я просто не могу сказать, где его можно повесить.

+2

Вы не можете создать тему несколько раз. Это то, что вы делаете? Почему вы называете join() в первую очередь? Чего вы пытаетесь достичь? Предоставьте полную минимальную программу, воспроизводящую проблему. –

+1

Кроме того, почему вы используете фоновый поток, чтобы сделать один вызов 'repaint()'? Это не имеет никакого смысла, поскольку вы обычно используете фоновый поток для вызова долгого кода, например, длинные циклы, а не для того, чтобы сделать один вызов метода. Пожалуйста, объясните детали вашей программы, которую вы пытаетесь достичь, и все это, потому что я чувствую, что вы захотите переструктурировать эту программу. Похоже, вы хотите создать игровой цикл какого-то типа, но пренебрегли тем, чтобы поместить любой цикл в фоновый поток или использовать таймер Swing (мой выбор, если бы это был мой). –

+0

@JBNizet Я пытаюсь перекрасить 2 компонента в отдельных случаях, но они оба перерисовываются внутри «KeyListener», что означает, что обе поставлены в очередь на «EDT», что делает его медленным, и делает его очень прерывистым. Из того, что показало меня в googling, казалось, что Thread.join() остановит поток, если это не так, мне нужно знать, как остановить его (поскольку «Thread.interrupt» обычно не одобряется). После того, как они нажмут кнопку, я снова вызываю 'Thread.start()', да. –

ответ

1

Если я это понимаю ... вы вызываете перерисовку() из вашей игры. Поскольку repake() выполняется на EDT, я думаю, что вы заблокировали его от выполнения в силу того факта, что gameThread.join() блокирует EDT (поскольку он запускается EDT, т. Е. Из вашего обработчика KeyListener).

Смежные вопросы