如何在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; } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |