3

TimeElapsed私は(不変である)と呼ばれるカスタムクラスを持っています。TimeElapseda Duration(時間を追跡するために JavaFx で使用される型MediaPlayer) を受け取るコンストラクターがあります。次に、コンストラクターは を に変換しDurationますTimeElapsed

問題は、を返す必要がある関数があることTimeElapsed ObservableValueです。私が必要とするのは、次のようなことができることです:

new Binding<TimeElapsed>() {

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

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

しかし、何らかの理由でBindingジェネリックがなくDoubleBinding、値を計算するがタイプを選択できない場合にのみ、これを行うことができます。それで、私は何をすべきですか?

4

1 に答える 1

7

を使用したサンプル ソリューション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:\\Users\\Public\\Music\\Sample Music\\Dillon - 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 の進行状況プロパティを直接監視します。

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:\\Users\\Public\\Music\\Sample Music\\Dillon - 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;
    }
}
于 2013-08-14T19:10:20.517 に答える