2013-06-12 5 views
-1

나는 mp3plugin.jar 라이브러리를 사용하고 있으며 내 음악은 훌륭하게 작동합니다. 유일한 문제는 프로그램이 시작될 때 JFrame이 표시되지 않는다는 것입니다.음악 재생 중 JFrame이 표시되지 않습니까?

package com.org.pong; 
import javax.sound.sampled.*; 
import javax.sound.*; 
import java.io.*; 
import java.net.URL; 

public class Music { 

    Music(String url) { 

     int total, totalToRead, numBytesRead, numBytesToRead; 
     byte[] buffer; 
     boolean stopped; 
     AudioFormat wav; 
     TargetDataLine line; 
     SourceDataLine lineIn; 
     DataLine.Info info; 
     File file; 
     FileInputStream fis; 

     // AudioFormat(float sampleRate, int sampleSizeInBits, 
     // int channels, boolean signed, boolean bigEndian) 
     wav = new AudioFormat(44100, 16, 2, true, false); 
     info = new DataLine.Info(SourceDataLine.class, wav); 

     buffer = new byte[1024 * 333]; 
     numBytesToRead = 1024 * 333; 
     total = 0; 
     stopped = false; 

     if (!AudioSystem.isLineSupported(info)) { 
      System.out.print("no support for " + wav.toString()); 
     } 
     try { 
      // Obtain and open the line. 
      lineIn = (SourceDataLine) AudioSystem.getLine(info); 
      lineIn.open(wav); 
      lineIn.start(); 
      fis = new FileInputStream(file = new File(url)); 
      totalToRead = fis.available(); 

      while (total < totalToRead && !stopped) { 
       numBytesRead = fis.read(buffer, 0, numBytesToRead); 
       if (numBytesRead == -1) 
       break; 
       total += numBytesRead; 
       lineIn.write(buffer, 0, numBytesRead); 
      } 

     } catch (LineUnavailableException ex) { 
      ex.printStackTrace(); 
     } catch (FileNotFoundException nofile) { 
      nofile.printStackTrace(); 
     } catch (IOException io) { 
      io.printStackTrace(); 
     } 
    } 

} 
+1

그것이 내가이 이전 질문 post..try 사용에 OCUR 것 U 말했다고 재미는'그것은 재미 없어 – nachokk

+0

을 SwingWorker'. 실제로 슬프다. –

+0

@nachokk 죄송합니다. 나는 다른 스레드에 관심을 기울이지 않았다. –

답변

2

이것은 Event Dispatching Thread를 차단하고 있음을 나타냅니다. 이렇게하면 차단을 중지 할 때까지 UI 요소가 업데이트되지 않습니다.

만하면 코드를보고하는 데, 나는

while (total < totalToRead && !stopped) { 
    numBytesRead = fis.read(buffer, 0, numBytesToRead); 
    if (numBytesRead == -1) 
    break; 
    total += numBytesRead; 
    lineIn.write(buffer, 0, numBytesRead); 
} 

당신의 Music 클래스를 실행하거나 그 자체 내에서 루프를 실행하거나하는 백그라운드 스레드를 만들어보십시오 ... 당신의 범인이 여기에 제안했다 배경 스레드입니다.

이 오히려 원유 예입니다

예를 작업과 업데이트 자세한 내용

에 대한 Concurrency in Swing에서 살펴 보자. 일반적으로 나는 음악 재생에 대한 책임을지는 하나의 Thread을 가지지 만, 중단되어 다른 노래를 연주하게 될 수도 있지만 이는 단지 개념 증명 일뿐입니다.

import java.awt.BorderLayout; 
import java.awt.EventQueue; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileNotFoundException; 
import java.io.IOException; 
import javax.sound.sampled.AudioFormat; 
import javax.sound.sampled.AudioSystem; 
import javax.sound.sampled.DataLine; 
import javax.sound.sampled.LineUnavailableException; 
import javax.sound.sampled.SourceDataLine; 
import javax.sound.sampled.TargetDataLine; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class TestMusic { 

    public static void main(String[] args) { 
     new TestMusic(); 
    } 

    public TestMusic() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       Music.play("/play/some/music/white/boy"); 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new JLabel("Look Ma, no hands")); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public static class Music { 

     public static void play(final String url) { 

      new Thread(new Runnable() { 

       @Override 
       public void run() { 
        new Music(url); 
       } 
      }).start(); 

     } 

     private int total, totalToRead, numBytesRead, numBytesToRead; 
     private byte[] buffer; 
     private boolean stopped; 
     private AudioFormat wav; 
     private TargetDataLine line; 
     private SourceDataLine lineIn; 
     private DataLine.Info info; 
     private File file; 
     private FileInputStream fis; 

     public Music(String url) { 


      // AudioFormat(float sampleRate, int sampleSizeInBits, 
      // int channels, boolean signed, boolean bigEndian) 
      wav = new AudioFormat(44100, 16, 2, true, false); 
      info = new DataLine.Info(SourceDataLine.class, wav); 

      buffer = new byte[1024 * 333]; 
      numBytesToRead = 1024 * 333; 
      total = 0; 
      stopped = false; 

      if (!AudioSystem.isLineSupported(info)) { 
       System.out.print("no support for " + wav.toString()); 
      } 
      try { 
       // Obtain and open the line. 
       lineIn = (SourceDataLine) AudioSystem.getLine(info); 
       lineIn.open(wav); 
       lineIn.start(); 
       fis = new FileInputStream(file = new File(url)); 
       totalToRead = fis.available(); 

       while (total < totalToRead && !stopped) { 
        numBytesRead = fis.read(buffer, 0, numBytesToRead); 
        if (numBytesRead == -1) { 
         break; 
        } 
        total += numBytesRead; 
        lineIn.write(buffer, 0, numBytesRead); 
       } 

      } catch (LineUnavailableException ex) { 
       ex.printStackTrace(); 
      } catch (FileNotFoundException nofile) { 
       nofile.printStackTrace(); 
      } catch (IOException io) { 
       io.printStackTrace(); 
      } 
     } 
    } 
} 
+0

그래서 음악 클래스에 스레드를 추가하고 시작하겠습니까? –

+0

그럴 가능성은 – MadProgrammer

+0

나는 그것을 시도하고 결과는 동일했다. –

2

이 코드의 실행 시간이 긴 비트와 스윙 이벤트 처리 쓰레드를 차단하는 전형적인 예이다 : 나는 음악을 추가하기 전에, 그것은 perfectly.This 근무하는 것은 음악에 대한 내 코드입니다. 스레드가 구성 요소를 페인팅하거나 사용자와 상호 작용할 수 없으므로 GUI가 중단됩니다. 해결 방법 : 음악의 배경 스레드를 사용하여 GUI의 이벤트 스레드를 차단하지 마십시오.

+0

+1 태그 - 내기 : P – MadProgrammer

+0

@MadProgrammer :하지만 더 완벽합니다. 1 + –

+0

@HovercraftFullOfEels : 백그라운드 스레드는 어떻게 만들 수 있습니까? –