我为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
编辑:如果我这样做,如果没有手动调整大小,它将无法正常工作。 如果我没有理解你,我就不会感到害羞。
答案 0 :(得分:2)
您可以在两个地方使用此代码。
pack();
setSize(700, 700);
pack()类很浪费,因为您之后会立即设置大小。此外,第一次调用构造函数时,您还没有添加任何内容。
在添加视频组件后以及使框架可见后,尝试设置尺寸或调用包。
根据您的修改,我认为问题是您在组件到位之前设置框架可见。将setVisible和pack()调用移动到Main
类的构造函数的末尾,而不是add()
方法。
基于对您的问题的更多编辑:正如我在评论中提到的,请确保在单独调用invokeLater时将GUI代码分开,以便在EDT上发生事情。因此,您需要将IMediaReader创建和线程开始移动到main()方法,然后创建一个新的SwingUtilities.invokeLater调用,创建一个新的Main类。顺便说一句,Main是一个令人困惑的类名。