2013-10-28 46 views
0

我已經爲來自Xuggler的IMediaReader編寫了一個偵聽器。 它應該在JPanel中顯示一個視頻,我可以添加到JFrame中。JFrame僅在調整大小後顯示內容(Xuggler)

我已經在類主創造了這個JFrame中:

class Window extends JFrame { 

    static IMediaReader reader; 
    static Window main; 

    public static void main(String[] args) { 



     new Thread() { 
      public void run() { 
       reader = ToolFactory.makeReader("C:/Users/André/Desktop/Detail.wmv"); 
       reader.addListener(new Player(IMediaViewer.Mode.AUDIO_VIDEO, main)); 

       while (reader.readPacket() == null) 
        do {} while(false); 
      } 
     }.start(); 

     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       main = new Window(); 
      } 
     }); 
    } 

    private Window() { 
     setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 

     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       setVisible(true); 
       setSize(700, 700); 
      } 
     }); 


    } 

    // invoked by Player with the video panel 
    public void add(final JPanel videoPanel) { 

     add(videoPanel, BorderLayout.CENTER);   
    } 
} 

它顯示了視頻,但是當我手動調整窗口的大小,這是我的問題,它纔會起作用。否則,它會顯示一個小黑方塊。

使用pack()而不是setSize()或調用repaint並沒有幫助。

類播放器的代碼不只是從我。我只是改變了一些事情:

public class Player extends MediaListenerAdapter implements IMediaListener, IMediaViewer { 

    private static Main main; 

    Player(Mode mode, Main main) { 
     setMode(mode); 
     Player.main = main; 
    } 


     @Override 
     public void onAddStream(IAddStreamEvent event) 
     { 
       [...] 
      MediaFrame frame = new MediaFrame(stream, this, main); 
       [...] 
     } 

     @Override 
     public void onVideoPicture(IVideoPictureEvent event) 
     { 

      MediaFrame frame = mFrames.get(event.getStreamIndex()); 
       frame.setVideoImage(event.getPicture(), event.getImage()); 
     } 

     static class PositionFrame extends JPanel 
     { 

      public PositionFrame(Player viewer, Main main) 
      { 
       main.add(this); 



       mFrames.add(this); 


      } 



      protected void adjustSize() 
      { 
       invalidate(); 
      } 


     } 



     private class MediaFrame extends PositionFrame 
     { 

      // the video image 

      private BufferedImage mImage; 

      // the video panel 

      private final JPanel mVideoPanel; 

      // the stream 

      private final IStream mStream; 

      // the index of the stream (incase it's closed) 

      private final int mStreamIndex; 

      /** 
      * Construct a media frame. 
      * 
      * @param defaultCloseOperation what should Swing do if the window 
      *    is closed. See the {@link javax.swing.WindowConstants} 
      *    documentation for valid values. 
      * @param stream the stream which will appear in this frame 
      * @param viewer containing media viewer 
      */ 

      public MediaFrame(IStream stream, 
       Player viewer, Main main) 
      { 
       super(viewer, main); 

       // get stream and set title based it, establish a copy of the 
       // stream since it lives in a separate thread 

       mStream = stream.copyReference(); 
       mStreamIndex = mStream.getIndex(); 

       // the panel which shows the video image 

       mVideoPanel = new JPanel() 
       { 


        public void paint(Graphics graphics) 
        { 
         paintPanel((Graphics2D) graphics); 
        } 
       }; 

       // add the videoPanel 

       add(mVideoPanel); 

       // show the frame 

       setVisible(true); 
      } 


      // set the video image 

      protected void setVideoImage(IVideoPicture picture, BufferedImage image) 
      { 
         [...] 
        } 

      protected void paintPanel(Graphics2D graphics) 
      { 
       if (mImage != null) 
        graphics.drawImage(mImage, 0, 0, null); 
      } 
     } 

} 

它是從類MediaViewer http://code.google.com/p/xuggle/source/browse/trunk/java/xuggle-xuggler/src/com/xuggle/mediatool/MediaViewer.java?r=644

編輯組成:如果我不喜歡這樣,這並不無需手動調整工作。 如果我沒有理解你的話,我不確定。

+0

嘗試調用'repaint()'? –

+0

是的,它沒有幫助。 – Andy

回答

2

你有兩個地方的代碼。

pack(); 
setSize(700, 700); 

pack()類是浪費的,因爲您在之後立即設置大小。另外,您第一次在構造函數中調用時,您還沒有添加任何東西。

嘗試在添加視頻組件後以及在使框架可見後設置尺寸或呼叫包。

根據您的編輯,我認爲問題在於您在設置組件之前將框架設置爲可見。將您的setVisible和pack()調用移至Main類的構造函數的末尾,而不是add()方法。

根據對您問題的更多編輯:正如我在評論中提到的那樣,確保在單獨調用invokeLater來分離GUI代碼以使事情發生在EDT上。因此,您需要將IMediaReader創建和線程移動到main()方法中,然後創建一個新的對SwingUtilities.invokeLater的調用,以創建一個新的Main類。順便說一下,Main是一個令人困惑的名字。

+0

如果我這樣做: – Andy

+0

class Main擴展JFrame {0} {0} {0} {0}}}}}} Main Main(); \t} \t IMediaReader reader; (){ \t private Main \t \t reader = ToolFactory.makeReader(「C:/Users/André/Desktop/Detail.wmv」); \t \t reader.addListener(new Player(IMediaViewer.Mode.AUDIO_VIDEO,this)); \t \t \t \t \t \t while(reader。readPacket()== null) \t \t \t do {} while(false); \t \t \t } \t \t //與視頻面板 \t公共無效加載(JPanel的videoPanel){ \t \t加(videoPanel,BorderLayout.CENTER)通過調用播放機; \t \t pack(); \t \t setVisible(true); \t \t} } 它也不起作用。 – Andy

+0

這還是在setVisible之前調用pack。翻轉它們。 – jzd