Java 操作侦听器仅在调试模式下工作

Java 操作侦听器仅在调试模式下工作,java,swing,actionlistener,vlcj,Java,Swing,Actionlistener,Vlcj,我在使用vlcj的媒体播放器上有一个动作监听器。当我在调试模式下运行程序时,操作侦听器会在视频完成时触发,但当我在eclipse中正常运行时,它不会触发 我的行动听众 public static void youtubeGui(){ Main.playing = true; final JFrame f = new JFrame(); f.setLocation(100,100); f.setSize(1000,600); f.setDefaultClo

我在使用vlcj的媒体播放器上有一个动作监听器。当我在调试模式下运行程序时,操作侦听器会在视频完成时触发,但当我在eclipse中正常运行时,它不会触发

我的行动听众

public static void youtubeGui(){

    Main.playing = true;
    final JFrame f = new JFrame();
    f.setLocation(100,100);
    f.setSize(1000,600);
    f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    f.setVisible(true);

    Canvas c = new Canvas();
    c.setBackground(Color.black);
    JPanel p = new JPanel();
    p.setLayout(new BorderLayout());
    p.add(c);
    f.add(p);

    NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(),"C:\\Program Files\\VideoLAN\\VLC");
    Native.loadLibrary(RuntimeUtil.getLibVlcLibraryName(), LibVlc.class);

    MediaPlayerFactory mpf = new MediaPlayerFactory();
    EmbeddedMediaPlayer emp = mpf.newEmbeddedMediaPlayer(new Win32FullScreenStrategy(f));
    emp.setVideoSurface(mpf.newVideoSurface(c));

    emp.setPlaySubItems(true);
    String str = Insert.videoQueue.peek();
    emp.prepareMedia(str);
    emp.play();
    Main.playing = true;
    try {
        TimeUnit.SECONDS.sleep(4);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    emp.addMediaPlayerEventListener(new MediaPlayerEventAdapter() {
        @Override
        public void finished(MediaPlayer mediaPlayer) {
            Insert.videoQueue.remove();
            System.out.println("aaaaa");
            f.setVisible(false);
            f.dispose(); 
            Main.playing = false;
        }
    });

}
检查新的插入方法

public static void addCheck(String locationIn) throws IOException {

    String fileLine = "";
    String a = "";

    while (true) {
        Scanner inFile = new Scanner(new FileReader(
        locationIn));
        while (inFile.hasNext()) {
            fileLine = inFile.nextLine();
        }

        if (fileLine.contains("watch?v=") && fileLine.contains("!add") && !fileLine.equals(a)) {
            a = fileLine;
            String result = fileLine.substring(fileLine.indexOf("[URL]") + 5, fileLine.indexOf("[/URL]"));
            videoQueue.add(result);
            result = "";
            if(Main.playing == false){
                Gui.youtubeGui();
            }
        }

        inFile.close();
    }
}

我猜是因为我怀疑你发布的代码没有说明全部情况

我看到在Eclipse中运行普通模式和调试模式时,垃圾收集器的行为有所不同

如果查看
youtubeGui
方法,则将
mpf
emp
声明为本地堆变量。当该方法退出时,似乎没有任何其他东西保持这两个变量固定,以便引用的对象符合垃圾收集的条件

如果您的
emp
对象确实是垃圾收集的,这可能解释了为什么您从未看到侦听器被激活

在调试模式下,垃圾收集可能已延迟,而在非调试模式下,垃圾收集运行得更快

您可能会想,媒体播放器怎么会因为视频仍在播放而被垃圾收集?好的,媒体播放器已经在JVM之外创建了一些本机资源,没有任何东西会因为Java媒体播放器对象被垃圾收集而显式地破坏这些本机资源。在不确定的时间之后通常会发生的是本机崩溃


因此,我建议重新安排您的代码,这样您就可以保留对媒体播放器(可能还有媒体播放器工厂)的硬引用。

我猜您有一个GUI线程问题,您的GUI由于在GUI的事件线程上运行的长时间运行的代码而被阻塞,但如果我能证明这一点,我会倒霉的,因为我不完全理解你的代码。请考虑创建和发布一个有效的。如果你把代码格式化得更好,使它遵循java标准,我们就更容易理解和阅读。我已经格式化了你的代码可读性,但我强烈建议你自己做这件事,尤其是通过给你的代码适当的缩进,通常每个块有4个空格,并确保同一块上的所有代码都处于相同的缩进级别。格式化是非常重要的,因为如果您的代码不是标准的可接受格式,那么它就不太可读,如果它不可读,那么调试和理解就很困难。否决票似乎很不公平,我见过比这更糟糕的问题