加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

如何在JavaFx中创建自定义绑定类型

发布时间:2020-12-15 04:12:43 所属栏目:Java 来源:网络整理
导读:我有一个名为TimeElapsed的自定义类(它是不可变的). TimeElapsed有一个构造函数,它接受一个Duration(这是 JavaFx MediaPlayer中用来跟踪时间的类型).然后构造函数将持续时间转换为TimeElapsed. 问题是我有一个需要返回TimeElapsed ObservableValue的函数.我
我有一个名为TimeElapsed的自定义类(它是不可变的). TimeElapsed有一个构造函数,它接受一个Duration(这是 JavaFx MediaPlayer中用来跟踪时间的类型).然后构造函数将持续时间转换为TimeElapsed.

问题是我有一个需要返回TimeElapsed ObservableValue的函数.我需要的是能够做这样的事情:

new Binding<TimeElapsed>() {

     {
          super.bind(player.duration())
     }

     @Override
     protected TimeElapsed computeValue() {
          return new TimeElapsed(player.duration());
     }
}

但由于某种原因,没有Binding泛型,你只能使用DoubleBinding和类似的东西,你在那里计算值,但不能选择类型.所以我该怎么做?

解决方法

使用 ObjectBinding<TimeElapsed>的样品溶液.

关键方法

/* @return an ObjectBinding of immutable TimeElapsed objects for the player */
private ObjectBinding<TimeElapsed> createElapsedBindingByBindingsAPI(
        final MediaPlayer player
    ) {
    return Bindings.createObjectBinding(
        new Callable<TimeElapsed>() {
            @Override
            public TimeElapsed call() throws Exception {
                return new TimeElapsed(player.getCurrentTime());
            }
        },player.currentTimeProperty()
    );
}

完整的可执行示例

更改样本中的MEDIA_PATH以匹配您所需的媒体.

import javafx.application.Application;
import javafx.beans.binding.*;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.scene.media.*;
import javafx.stage.Stage;
import javafx.util.Duration;

import java.io.File;
import java.net.MalformedURLException;
import java.util.concurrent.Callable;

/** Displays progress (time elapsed in seconds) of playing a media file. */    
public class TimeElapsedBinding extends Application {
    private static final String MEDIA_PATH = 
        "C:UsersPublicMusicSample MusicDillon - Thirteen Thirtyfive.mp3";

    public static void main(String[] args) { launch(args); }

    @Override public void start(Stage stage) throws Exception {
        final MediaView   mediaView    = createMediaView();
        final MediaPlayer player       = mediaView.getMediaPlayer();
        final Label       elapsedLabel = new Label();

        ObjectBinding<TimeElapsed> elapsedBinding =
            createElapsedBindingByBindingsAPI(player);
        StringBinding elapsedStringBinding =
            createStringBindingByBindingsAPI(elapsedBinding);

        elapsedLabel.textProperty().bind(
                elapsedStringBinding
        );

        StackPane layout = new StackPane();
        layout.setStyle("-fx-background-color: cornsilk; -fx-padding: 20px;");
        layout.getChildren().setAll(
                mediaView,elapsedLabel
        );

        stage.setScene(new Scene(layout));
        stage.show();
    }

    /* @return an ObjectBinding of immutable TimeElapsed objects for the player */
    private ObjectBinding<TimeElapsed> createElapsedBindingByBindingsAPI(
            final MediaPlayer player
        ) {
        return Bindings.createObjectBinding(
            new Callable<TimeElapsed>() {
                @Override
                public TimeElapsed call() throws Exception {
                    return new TimeElapsed(player.getCurrentTime());
                }
            },player.currentTimeProperty()
        );
    }

    /* @return a string binding to an ObjectBinding of immutable TimeElapsed objects */
    private StringBinding createStringBindingByBindingsAPI(
            final ObjectBinding<TimeElapsed> elapsedBinding
        ) {
        return Bindings.createStringBinding(
                new Callable<String>() {
                    @Override
                    public String call() throws Exception {
                        return String.format(
                                "%.0f",elapsedBinding.getValue().getElapsed()
                        );
                    }
                },elapsedBinding
        );
    }

    /* @Return a new MediaView from a predefined MEDIA_PATH string */
    private MediaView createMediaView() throws MalformedURLException {
        String mediaURI = new File(MEDIA_PATH).toURI().toURL().toExternalForm();

        Media media = new Media(mediaURI);
        MediaPlayer player = new MediaPlayer(media);
        MediaView mediaView = new MediaView(player);
        player.play();

        return mediaView;
    }

    /** immutable TimeElapsed class. */
    class TimeElapsed {
        private final double elapsed;

        TimeElapsed(Duration duration) {
            elapsed = duration.toSeconds();
        }

        public double getElapsed() {
            return elapsed;
        }
    }
}

以上仅作为样本提供,以适应在ObjectBinding中使用不可变对象的问题框架,而不是跟踪播放媒体进度的最有效方式.

替代实施

如果不需要在ObjectBinding中使用不可变对象,我会直接监视MediaPlayer的progress属性,类似于下面的代码:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.StackPane;
import javafx.scene.media.*;
import javafx.stage.Stage;

import java.io.File;
import java.net.MalformedURLException;

public class MediaProgressMonitoring extends Application {
    private static final String MEDIA_PATH = "C:UsersPublicMusicSample MusicDillon - Thirteen Thirtyfive.mp3";

    public static void main(String[] args) { launch(args); }

    @Override public void start(Stage stage) throws Exception {
        final MediaView   mediaView = createMediaView();
        final MediaPlayer player    = mediaView.getMediaPlayer();
        final ProgressBar progress  = new ProgressBar(0);
        progress.setPrefWidth(800);

        player.currentTimeProperty().addListener((observable) ->
            progress.setProgress(
                player.getCurrentTime().toMillis() / 
                player.getTotalDuration().toMillis()
            )
        );

        StackPane layout = new StackPane();
        layout.setStyle("-fx-background-color: cornsilk; -fx-padding: 20px;");
        layout.getChildren().setAll(
                mediaView,progress
        );

        stage.setScene(new Scene(layout));
        stage.show();
    }

    private MediaView createMediaView() throws MalformedURLException {
        String mediaURI = new File(MEDIA_PATH).toURI().toURL().toExternalForm();

        Media media = new Media(mediaURI);
        MediaPlayer player = new MediaPlayer(media);
        MediaView mediaView = new MediaView(player);
        player.play();

        return mediaView;
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读