2013-04-16 1 views
1

내 프로그램에서 사용하기 위해 Music Loop in Java의 뮤직 플레이어 클래스를 채택했지만 이상한 문제가 발생했습니다. 음악을 시작하고 멈추는 버튼이 있습니다. 한 번 클릭하면 음악이 올바르게 시작되고 프로그램이 계속 정상적으로 실행됩니다. 다시 클릭하면 음악이 멈추고 프로그램은 잘 유지됩니다. 버튼을 세 번 클릭하면 문제가 발생합니다. 음악이 정상적으로 재생되기 시작하지만 나머지 프로그램이 응답하지 않습니다. 다음은 MusicPlayer 클래스에있는 것입니다. 여기 음악을 다시 시작하는 중 문제가 발생했습니다.

import java.io.*; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import sun.audio.AudioPlayer; 
import sun.audio.AudioStream; 

public class MusicPlayer extends Thread { 
private AudioStream as; 
private AudioPlayer player; 
private boolean playback; 
private String fileLoc = MusicPlayer.class.getClassLoader().getResource("resources/Yamaha-TG-77-Acoustic-Bass-C4.wav").toString(); 
private String edittedLoc = fileLoc.substring(6); 

public void run() { 
    try 
    { 
     startPlayback(); 
    } catch (FileNotFoundException ex) 
    { 
     Logger.getLogger(MusicPlayer.class.getName()).log(Level.SEVERE, null, ex); 
    } catch (IOException ex) 
    { 
     Logger.getLogger(MusicPlayer.class.getName()).log(Level.SEVERE, null, ex); 
    } 
} 
public void startPlayback() throws FileNotFoundException, IOException 
{ 
    playback = true; 
    System.out.println(edittedLoc); 
    as = new AudioStream(new FileInputStream(edittedLoc)); 
    AudioPlayer.player.start(as); 
    try { 
     do { 
     } while (as.available() > 0 && playback); 
     if (playback) { 
      startPlayback(); 
     } 
    } catch (IOException ex) { 
     Logger.getLogger(MusicPlayer.class.getName()).log(Level.SEVERE, null, ex); 
    } 

} 

public void stopPlayback() throws IOException 
{ 
    playback = false; 
    AudioPlayer.player.stop(as); 
} 
} 

class MusicClick implements ActionListener 
{ 
    @Override 
    public void actionPerformed(ActionEvent e) 
    { 
     Game tempGame = getGame(); 
     if (tempGame.getMusicInitialized() == false) 
     { 
      tempGame.getMusicPlayer().start(); 
      tempGame.setMusicInitialized(true); 
      tempGame.setMusicPlaying(true); 
     } 
     else if (tempGame.getMusicInitialized() == true) 
     { 
      if (tempGame.getMusicPlaying() == false) 
      { 
       try 
       { 
        tempGame.getMusicPlayer().startPlayback(); 
       } catch (FileNotFoundException ex) 
       { 
        Logger.getLogger(GUI.class.getName()).log(Level.SEVERE, null, ex); 
       } catch (IOException ex) 
       { 
        Logger.getLogger(GUI.class.getName()).log(Level.SEVERE, null, ex); 
       } 
       tempGame.setMusicPlaying(true); 
      } 
      else if (tempGame.getMusicPlaying() == true) 
      { 
       try 
       { 
        tempGame.getMusicPlayer().stopPlayback(); 
       } catch (IOException ex) 
       { 
        Logger.getLogger(GUI.class.getName()).log(Level.SEVERE, null, ex); 
       } 
       tempGame.setMusicPlaying(false); 
      } 
     } 
    } 
} 

좋아 음악을 제어하는 ​​버튼, 내가 제안했다으로 대신 클립을 사용했습니다. 자, 이걸 가지고 있어요

이것은 내가 원하는 방식대로 작동하지만, 한 가지 질문이 있습니다. resumePlay() 메서드의 경우 clip.start()를 수행하려고했지만 어떤 이유로 클립을 다시 시작하지 않고 대신에 playSound()를 다시 호출하여 작동합니다. 그 방법으로 clip.start가 작동하지 않는 이유가 있습니까? 또는 내가 음악을 멈추었을 때 스레드를 종료 할 수있는 방법은 디버거에서 각각의 playSound를 호출 할 때마다 문제가 발생할 수 있다고 생각되는 새로운 스레드가 시작된다는 것을 알았 기 때문입니다.

+0

'sun.audio' 패키지에 담그는 대신'Clip'을 사용하십시오. '클립'은 JSE의 일부이며,'태양 '은 그렇지 않습니다. [Java 사운드 정보. 페이지] (http://stackoverflow.com/tags/javasound/info)를 참조하십시오. –

답변

0

프로그램이 응답을 멈추는 경우, 내 마음에 오는 첫 번째 생각은 무한 루프가 발생했다는 것입니다. 디버그 또는

tempGame.getMusicPlayer().startPlayback(); 

이 새를 만들지 않습니다 사용 MusicClick 클래스에서 ... 루핑 변수가 실제로 변경되었는지 확인

+0

전체 프로그램이 응답하지 않습니다. 음악은 계속 재생되지만 다른 것은 응답하지 않습니다. 음악을 시작하지 않으면 게임 자체가 완벽하게 작동한다는 것을 알고 있습니다. 음악 스레드가 어떻게 든 메인 스레드를 차단했기 때문에 어쩌면 그렇게 생각할 수 있습니까? –

1

을에서 System.out.println() 당신의 루프 내부의 문을 넣어 스레드를 차단하고 응용 프로그램을 차단합니다.

+0

그래서 나는 tempGame.getMusicPlayer()를 가지고있다. start(); –

+0

'stopPlayback();'을 호출 할 때 스레드 'MusicPlayer'가 죽습니다. 음악을 다시 시작하려고하면 메인 스레드가 음악 재생을 담당합니다 (새 스레드 (.start() 메소드가 생성되지 않기 때문에) – user1595178

+0

좋아요, 메인이 음악 재생을 담당하게된다는 의미입니다. 그것을 .start()로 변경하십시오. 대신 잘못된 스레드 상태 예외가 발생합니다. –