使用一个控制器JavaFX FXML播放/暂停多个MediaView

时间:2015-05-15 12:54:27

标签: java javafx-2 javafx-8 fxml

目前,我有一个带有多个媒体视图的场景,每个场景都有自己的播放和暂停按钮,在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;

}

1 个答案:

答案 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中。