当前位置: 首页 > 知识库问答 >
问题:

JavaFX 媒体播放器 - 更新用于显示线程/任务中的“当前时间”的标签

曾瀚昂
2023-03-14

我是java的新手

我有一个小组练习,我们必须编写一个mediaplayer,它应该能够在JavaFX中播放音乐文件(不是视频)和其他功能,现在我正在处理“时间滑块”和“总持续时间”以及“当前时间”

这些东西大部分都在工作。我的问题实际上是当前时间,因为我让它在while循环中运行。所以程序不会冻结,我发现我必须创建一个任务/线程。持续时间滑块工作正常,改变滑块工作得很好。所以用户可以看到他的歌曲有多远,他甚至可以选择他想跳到的时间。

主要问题是更新当前时间。

如果我点击“播放”,就会计算总持续时间。

mp.currentTimeProperty().addListener(new InvalidationListener() {
            public void invalidated(Observable ov)
            {
                updatesValues();
            }
        });

紧接着这个方法被调用。

String setCurrentTime = "0:00";
private void updatesValues(){

    Runnable r = new Runnable() {
        public void run() {
            while (isPlaying) {


                //System.out.println(mp.getCurrentTime().toMinutes());      // Debug

                String setCurrentTime = "0:00";
private void updatesValues(){

    Runnable r = new Runnable() {
        public void run() {
            while (isPlaying) {


                //System.out.println(mp.getCurrentTime().toMinutes());      // Debug

                String currentTime = "";
                int timeCurrentTime = (int) (100 * mp.getCurrentTime().toMinutes());

                int hourCurrentTime = timeCurrentTime / 3600;
                int minCurrentTime = timeCurrentTime / 100;
                int secCurrentTime = 60 * (timeCurrentTime % 100);

                if (hourCurrentTime == 0) {
                    if(secCurrentTime < (60 * (timeCurrentTime % 100))){
                        System.out.printf("%.2s:0%.1s \n", minCurrentTime, secCurrentTime);
                        setCurrentTime = currentTime.format("%.2s:0%.1s",minCurrentTime,secCurrentTime);
                    }else{
                        System.out.printf("%.2s:%.2s \n", minCurrentTime, secCurrentTime);
                        setCurrentTime = currentTime.format("%.2s:%.2s",minCurrentTime,secCurrentTime);
                    }
                } else {
                    if(secCurrentTime < (60 * (timeCurrentTime % 100))){
                        System.out.printf("%.2:%.2s:0%.1s \n", hourCurrentTime,minCurrentTime, secCurrentTime);
                        setCurrentTime = currentTime.format("%.2s%.2s:0%.1s",hourCurrentTime,minCurrentTime,secCurrentTime);
                    }else{
                        System.out.printf("%.2s:%.2s:%.2s \n", hourCurrentTime, minCurrentTime, secCurrentTime);
                        setCurrentTime = currentTime.format("%.2:%.2s:%.2s",hourCurrentTime,minCurrentTime,secCurrentTime);
                    }

                }


                durationSlider.setValue(mp.getCurrentTime().toMillis()/ mp.getTotalDuration().toMillis() * 100);

                try
                {
                    Thread.sleep(1000);
                }
                catch(InterruptedException ex)
                {
                    Thread.currentThread().interrupt();
                }
            }
        }
    };
    displayCurrentTime.setText(setCurrentTime);
    new Thread(r).start();


}

系统输出工作正常。我只是在格式上有些问题。可能还有计算/运算部分。睡眠部分不工作,所以控制台得到spamed (prob。因为毫秒)。它看起来像:0:01 0:01 0:01 0:01 0:01 0:01 0:02 0:02等等..滑块正在工作并得到更新,但标签“显示当前时间”没有更新

一种解决方法是将“String setCurrentTime = " 0:00 ";”方法和" display current time . settext(setcurrent time);"在末尾但在新的“Thread(r)”之前。start();"

至少它现在可以工作了,但是看起来不太好。问题是,时间有时比其他时间更新得快。示例:1..2..3.4..5.6..7.8.9.0.10.11..12.13..14.15(点是每个值之间的断点)(概率。因为毫秒)

有人知道我如何解决这个问题,或者以另一种方式更新标签吗?

共有1个答案

徐淳
2023-03-14

您的代码中有一些错误。

    < li >从后台线程更新< code>durationSlider的值。JavaFX是单线程的,只能从JavaFX应用程序线程访问GUI。 < ul > < li >您可以在此处使用< code>Platform.runLater(但有一个更好的选项,请参见第4点)。
    < li >这可能也是< code>isPlaying的问题,但您没有显示它的声明。
    < li >由于< code > media player . current time 属性通常会失效,因此最终会出现大量线程。
    < li >不使用后台线程否定了前面的三点。
  • 这使您的代码更清晰。事实上,人们可能会认为format是一个实例方法。

关于第4点:

无需使用后台线程来更新durationSliderdisplayCurrentTimeMediaPlayer当前时间属性将在媒体播放时自动更新(并每次通知任何侦听器)。这些更新将在JavaFX应用程序线程上发生。您需要做的就是更新侦听器内部的UI;由于计算并不昂贵,因此可以在JavaFX应用程序线程上进行。

mp.currentTimeProperty().addListener((observable, oldTime, newTime) -> {
  durationSlider.setValue(newTime.toMillis() / mp.getTotalDuration().toMillis() * 100);
  String formattedTime = ...; // your computations
  displayCurrentTime.setText(formattedTime);
});

上面的代码使用javafx.beans.value.ChangeListener而不是InvalidationListener。它也使用lambda;但是,如果您不想使用lambda(或者还不知道它们),该代码等价于:

mp.currentTimeProperty().addListener(new ChangeListener<>() {

  @Override
  public void changed(ObservableValue<? extends Duration> observable,
                      Duration oldTime, Duration newTime) {
    durationSlider.setValue(newTime.toMillis() / mp.getTotalDuration().toMillis() * 100);
    String formattedTime = ...; // your computations
    displayCurrentTime.setText(formattedTime);
  }

});
 类似资料:
  • 我已经成功地能够从我的服务器流MP3,现在我想显示一个媒体播放器通知与控制时,歌曲开始播放。我已经遵循了一些教程如何做到这一点,但我仍然得到错误时,试图在我的应用程序中做同样的事情。 这是我尝试在音乐开始播放时显示通知的方式 这是完整的 但是,当我运行代码并单击播放按钮时,应用程序崩溃,logcat返回此错误,但没有指向特定的代码行。

  • 这可能不是一个可以接受的问题,但我现在非常绝望。 我需要一个同步java媒体播放器与快速寻找和平衡修改。 脚本: 我有一个javaFX项目,我必须在循环中播放一个非常短(50-100毫秒)的媒体文件。问题是,在重新启动之前,我需要等待一些要求。 简而言之:播放声音- javafx提供了一个我修改过的媒体播放器。 如果有人能为我指出正确的方向(图书馆/我错过的东西),我将不胜感激 ps允许的java

  • 我们有一个使用AU graph - CoreAudio API的工作应用程序来播放音频。图形始终在运行,各种源素材的播放/暂停状态在图形渲染回调函数中管理。我们成功地响应了UIEventTypeRemoteControl事件,并使用MPNowPlayingInfoCenter使用当前播放内容的元数据成功地更新了锁定屏幕。 缺少的一点是更新iOS多任务处理栏中播放/暂停按钮的状态。它始终处于“暂停”

  • 我目前在一个项目中使用Javafx 2,我可能需要长时间无限循环播放一个视频。在windows上,当视频播放时,我的proifiler工具显示非常正常的图片,cpu负载不是很重(在2个内核上运行时约为2x40-50%),内存使用峰值约为250 MB,这是正常的。但是,当我在Ubuntu机器上部署应用程序时,每个内核的cpu负载达到70%左右(尽管它是一个双核atom处理器,所以假设这是正常的),内

  • 媒体播放器类很好。然而,我无法播放存储在另一个类中的mp3文件(当鼠标单击时)。有人能检查我的密码吗? 这是我尝试用来播放音频文件的类: 当我运行程序时(在下面勾选的鼠标上),我得到了以下两个错误:错误1:线程“AWT-EventQueue-0”java.lang中的异常。不支持的操作异常:尚未实现错误2:线程“thread-3”java.llang中的例外。IllegalStateExcepti

  • 我正在开发一个包含两个活动的应用程序,一个是媒体播放器,另一个是要播放的歌曲列表,mp3播放器工作正常,从活动列表中我传递歌曲的名称和播放器工作正常。我有两个问题,如果用户播放一首歌并离开应用程序(这首歌一直在后台播放,这就是假设的工作方式),然后用户返回应用程序,搜索栏设置为0,计时器设置为0,有没有办法“保存”活动......也是如果一首歌正在播放,用户试图播放另一首歌,这首歌在前一首歌的顶部