JFrame仅在调整大小后才显示内容(Xuggler) [英] JFrame displays content only after resizing (Xuggler)

查看:134
本文介绍了JFrame仅在调整大小后才显示内容(Xuggler)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

我已经在主类中创建了这个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()或调用重绘无济于事.

Player类的代码不仅来自我.我刚刚更改了一些内容:

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类组成 解决方案

您在两个地方都有这段代码.

 pack();
 setSize(700, 700);

pack()类非常浪费,因为您随后要立即设置大小.另外,第一次调用构造函数时,您甚至还没有添加任何东西.

在添加视频组件之后并且使框架可见之后,请尝试设置大小或调用包.

根据您的编辑,我相信问题是您要在组件安装到位之前将框架设置为可见.将setVisible和pack()调用移到Main类而不是add()方法的构造函数的末尾.

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

I Have written a listener for an IMediaReader from Xuggler. It should show a video in a JPanel what i can add to a JFrame.

I have created this JFrame in the class main:

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);        
    }
}

It shows the video but it only works when i resize the window manually and that is my problem. Else, it shows a small black square.

Using pack() instead of setSize() or invoke repaint doesn't help.

The Code of class Player isn't just from me. I've just changed some things:

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);
            }
        }

}

It is made up from the class MediaViewer http://code.google.com/p/xuggle/source/browse/trunk/java/xuggle-xuggler/src/com/xuggle/mediatool/MediaViewer.java?r=644

EDIT: If I do it like this, it doesn't work without resizing manually. I'm not shure if I have unterstood you right.

解决方案

You have this code in two places.

 pack();
 setSize(700, 700);

The pack() class is wasteful since you are setting the size immediately afterwards. Also, the first time you call in your constructor you haven't even added anything yet.

Try setting the size or calling pack after you have added the video component and after you have made the frame visible.

Based on your edits, I believe the issue is that you are setting the frame visible before the component is in place. Move your setVisible and pack() calls to the end of your constructor for the Main class instead of the add() method.

Based on more edits to your question: As I mentioned in the comments, make sure you separate off the GUI code in a separate call to invokeLater to get things happening on the EDT. Therefore you need to move your IMediaReader creation and thread starting into your main() method, then after that create a new call to SwingUtilities.invokeLater that creates a new Main, class. By the way, Main is a confusing name for a class.

这篇关于JFrame仅在调整大小后才显示内容(Xuggler)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆