JFrame仅在调整大小后显示内容(Xuggler)

时间:2013-10-28 11:25:00

标签: java swing xuggler

我为Xuggler的IMediaReader编写了一个监听器。 它应该在JPanel中显示我可以添加到JFrame的视频。

我在类main中创建了这个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()或调用重绘没有帮助。

班级守则不只是来自我。我刚改变了一些事情:

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

编辑:如果我这样做,如果没有手动调整大小,它将无法正常工作。 如果我没有理解你,我就不会感到害羞。

1 个答案:

答案 0 :(得分:2)

您可以在两个地方使用此代码。

 pack();
 setSize(700, 700);

pack()类很浪费,因为您之后会立即设置大小。此外,第一次调用构造函数时,您还没有添加任何内容。

在添加视频组件后以及使框架可见后,尝试设置尺寸或调用包。

根据您的修改,我认为问题是您在组件到位之前设置框架可见。将setVisible和pack()调用移动到Main类的构造函数的末尾,而不是add()方法。

基于对您的问题的更多编辑:正如我在评论中提到的,请确保在单独调用invokeLater时将GUI代码分开,以便在EDT上发生事情。因此,您需要将IMediaReader创建和线程开始移动到main()方法,然后创建一个新的SwingUtilities.invokeLater调用,创建一个新的Main类。顺便说一句,Main是一个令人困惑的类名。