2012-12-16 29 views
1

在我的程序中,我在背景中顯示帶有歌曲的圖像。 歌曲完成後,我需要關閉幀和JInternalFrame。 下面是代碼:JFrame行爲怪異

package projectfinal; 
import javax.swing.*; 
import java.io.File; 
import java.io.IOException; 

/* MORE IMPORTS */ 
public class ImagePanel extends javax.swing.JFrame { 

    public static class audio extends JApplet { 

     private static final int EXTERNAL_BUFFER_SIZE = 128000; 

     public void aaudio() { 

      String strFilename = "E:/zehreelay.wav"; 
      File soundFile = new File(strFilename); 


      AudioInputStream audioInputStream = null; 
      try { 
       audioInputStream = AudioSystem.getAudioInputStream(soundFile); 
      } catch (Exception e) { 

       e.printStackTrace(); 
       System.exit(1); 
      } 


      AudioFormat audioFormat = audioInputStream.getFormat(); 

      SourceDataLine line = null; 
      DataLine.Info info = new DataLine.Info(SourceDataLine.class, 
       audioFormat); 
      try { 
       line = (SourceDataLine) AudioSystem.getLine(info); 

       line.open(audioFormat); 
      } catch (LineUnavailableException e) { 
       e.printStackTrace(); 
       System.exit(1); 
      } catch (Exception e) { 
       e.printStackTrace(); 
       System.exit(1); 
      } 
      line.start(); 
      int nBytesRead = 0; 
      byte[] abData = new byte[EXTERNAL_BUFFER_SIZE]; 
      while (nBytesRead != -1) { 
       try { 
        nBytesRead = audioInputStream.read(abData, 0, abData.length); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
       if (nBytesRead >= 0) { 
        int nBytesWritten = line.write(abData, 0, nBytesRead); 
       } 

      } 
      line.drain(); 

      line.close(); 

      jInternalFrame1.setVisible(false); 
      /** 
      * closing internal frame 
      */ 
     } 
    } 

    /** 
    * Creates new form NewJFrame 
    */ 
    public ImagePanel() { 

     initComponents(); 

    } 

    @SuppressWarnings("unchecked") 
// <editor-fold defaultstate="collapsed" desc="Generated Code"> 
    private void initComponents() { 

     jInternalFrame1 = new javax.swing.JInternalFrame(); 
     jLabel1 = new javax.swing.JLabel(); 
     jLabel2 = new javax.swing.JLabel(); 
     jLabel3 = new javax.swing.JLabel(); 
     jLabel4 = new javax.swing.JLabel(); 
     jLabel5 = new javax.swing.JLabel(); 
     jLabel6 = new javax.swing.JLabel(); 

     javax.swing.GroupLayout jInternalFrame1Layout = new javax.swing.GroupLayout(jInternalFrame1.getContentPane()); 

     //////////more code//////////////////////////////////// 
     jInternalFrame1.getContentPane().setLayout(jInternalFrame1Layout); 
     jInternalFrame1.addComponentListener(new java.awt.event.ComponentAdapter() { 

      public void componentHidden(java.awt.event.ComponentEvent evt) { 
       hiden(evt); 
      } 
     }); 
     /////adding a listner for component/// 
    } 

    public static void main(String args[]) { 


     start(); 

    } 

    private void hiden(java.awt.event.ComponentEvent evt) { 

     setVisible(false); 
    } 

    public static void start() { 
     java.awt.EventQueue.invokeLater(new Runnable() { 

      public void run() { 
       new ImagePanel().setVisible(true); 
      } 
     }); 
     audio obj = new audio(); 
     obj.aaudio(); 
    } 
    private static javax.swing.JInternalFrame jInternalFrame1; 
    private javax.swing.JLabel jLabel1; 
    private javax.swing.JLabel jLabel10; 
    private javax.swing.JLabel jLabel11; 
    private javax.swing.JLabel jLabel2; 
    private javax.swing.JLabel jLabel3; 
/////more variables...////// 
} 

此代碼是好的,但是當我嘗試了沒有添加組件偵聽器, 就是getRootPane().SetVisible(false)jInternalFrame1.getContentPane().setVisible(false)setVisible(false)他們都不是工作,但它的工作只有在添加一個隱藏的偵聽器組件之後。爲什麼?有什麼理由?那麼JInternalFrame怎麼樣了(JInternalFrame.setVisible(false))?這與rootPane()有關嗎?

+0

Swing GUI對象應該在[事件調度線程](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html)上的_only_上構建和操作。 – trashgod

+0

@trashgod那麼爲什麼它能正常工作,如果我們只是通常說setVisible(false)?爲什麼不在這種情況下? –

+0

Trashgod是對的。爲什麼你不能將調用包裝在SwingUtilities.invokeLater中? – StanislavL

回答

4

Initial Threads所述,「初始線程通過調用invokeLaterinvokeAndWait來調度GUI創建任務。」您正試圖在相同的初始線程上播放聲音並操作GUI。相反,在初始線程上啓動聲音並在EDT上構建GUI,如here所示,或者啓動單獨的線程來播放聲音,如here所示。

我不想使用AWT調度線程。

權利,你不希望使用AWT事件調度線程來播放聲音,但你必須使用它的GUI。

這個問題有些沒有答案。播放聲音很輕鬆,所以必須由單個EDT處理。

我只能推測,使用不同的組件會改變足夠的時間以影響平臺上的結果。在程序正確同步之前,總會有一些環境在其中工作,有些環境會在其中失敗。基本規則是這樣的:不要阻止EDT。另請參見answeranswerJava Sound標籤。

+0

謝謝。但是,這個問題有點沒有解決。播放聲音是輕的,所以必須由我上面詳細說明的單個EDT –

+0

處理。 – trashgod

+0

幹得好:) java仍然有很多漏洞 –