目前,我有一个带有多个媒体视图的场景,每个场景都有自己的播放和暂停按钮,在fxml中。我想知道是否有一种播放/暂停的方法,即媒体视图点击其按钮而不为每个媒体视图制作播放/暂停控制器。下面是一个我不希望这样做的繁琐方式的例子。
FXML
<StackPane alignment="CENTER">
<MediaView fx:id="mediaView" styleClass="mediaView">
<mediaPlayer>
<MediaPlayer fx:id="mediaPlayer" autoPlay="false">
<media>
<Media source="@../vid/vid1.mp4"/>
</media>
</MediaPlayer>
</mediaPlayer>
</MediaView>
<Button fx:id="btn_play1" onAction="#handlePlay1" alignment="CENTER" styleClass="btn_play"/>
<Button fx:id="btn_pause1" onAction="#handlePause1" alignment="CENTER" styleClass="btn_pause" visible="false"/>
</StackPane>
<StackPane alignment="CENTER">
<MediaView fx:id="mediaView2" styleClass="mediaView">
<mediaPlayer>
<MediaPlayer fx:id="mediaPlayer2" autoPlay="false">
<media>
<Media source="@../vid/vid2.mp4"/>
</media>
</MediaPlayer>
</mediaPlayer>
</MediaView>
<Button fx:id="btn_play2" onAction="#handlePlay2" alignment="CENTER" styleClass="btn_play"/>
<Button fx:id="btn_pause2" onAction="#handlePause2" alignment="CENTER" styleClass="btn_pause" visible="false"/>
控制器
@FXML
private void handlePause1(ActionEvent event) throws IOException {
mediaPlayer.pause();
btn_pause1.setVisible(false);
btn_play1.setVisible(true);
}
@FXML
private void handlePlay1(ActionEvent event) throws IOException {
mediaPlayer.play();
btn_play1.setVisible(false);
btn_pause1.setVisible(true);
mediaActive = true;
}
@FXML
private void handlePause2(ActionEvent event) throws IOException {
mediaPlayer1.pause();
btn_pause2.setVisible(false);
btn_play2.setVisible(true);
}
@FXML
private void handlePlay2(ActionEvent event) throws IOException {
mediaPlayer1.play();
btn_play2.setVisible(false);
btn_pause2.setVisible(true);
mediaActive = true;
}
答案 0 :(得分:1)
考虑使用按钮为媒体视图创建custom component。
基本想法看起来像
package application;
import java.io.IOException;
import javafx.beans.NamedArg;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.beans.property.ReadOnlyObjectProperty ;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.scene.media.MediaPlayer;
public class ControlledMediaView extends StackPane {
@FXML
private MediaPlayer mediaPlayer ;
@FXML
private Button playButton ;
@FXML
private Button pauseButton ;
public ControlledMediaView(@NamedArg("mediaURL") String mediaURL) throws IOException {
FXMLLoader loader = new FXMLLoader(getClass().getResource("ControlledMediaView.fxml"));
loader.setRoot(this);
loader.setController(this);
loader.getNamespace().put("mediaURL", mediaURL);
loader.load();
}
public void initialize() {
playButton.visibleProperty().bind(mediaPlayer.statusProperty().isNotEqualTo(MediaPlayer.Status.PLAYING));
pauseButton.visibleProperty().bind(mediaPlayer.statusProperty().isEqualTo(MediaPlayer.Status.PLAYING));
}
@FXML
private void pause() {
mediaPlayer.pause();
}
@FXML
private void play() {
mediaPlayer.play();
}
public ReadOnlyObjectProperty<MediaPlayer.Status> statusProperty() {
return mediaPlayer.statusProperty();
}
public final MediaPlayer.Status getStatus() {
return statusProperty().get();
}
}
使用ControlledMediaView.fxml(在同一个包中):
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.media.Media?>
<?import javafx.scene.media.MediaPlayer?>
<?import javafx.scene.media.MediaView?>
<fx:root xmlns:fx="http://javafx.com/fxml/1" type="StackPane">
<MediaView fx:id="mediaView" styleClass="mediaView">
<mediaPlayer>
<MediaPlayer fx:id="mediaPlayer" autoPlay="false">
<media>
<Media source="${mediaURL}" />
</media>
</MediaPlayer>
</mediaPlayer>
</MediaView>
<Button fx:id="playButton" onAction="#play" alignment="CENTER" styleClass="btn_play" />
<Button fx:idf="pauseButton" onAction="#pause" alignment="CENTER" styleClass="btn_pause" />
</fx:root>
然后你的主要FXML可以做
<?xml version="1.0" encoding="UTF-8"?>
<?import application.ControlledMediaView?>
<!-- ... -->
<ControlledMediaView mediaURL="@../vid/vid1.mp4"/>
<ControlledMediaView mediaURL="@../vid/vid2.mp4"/>
<!-- ... -->
您可能需要稍微努力以确保正确传达网址;如果你想使用SceneBuilder,你需要将ControlledMediaView
及其FXML打包到一个jar文件中并将其导入到SceneBuilder中。