【问题标题】:Play/Pause Multiple MediaViews With One Controller JavaFX FXML使用一个控制器 JavaFX FXML 播放/暂停多个 MediaView
【发布时间】:2015-05-15 12:54:26
【问题描述】:

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

}

【问题讨论】:

  • 我无法从您的描述中看出您目前是如何实现的;您可能需要显示一些代码。
  • 关于你的问题,我可以推断你不想同时玩MediaPlayer。为什么需要多个MediaViews

标签: java javafx-2 javafx-8 fxml


【解决方案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"/>

<!-- ... -->

您可能需要做一些工作以确保正确地传达 URL;另外,如果你想使用 SceneBuilder,你需要将 ControlledMediaView 及其 FXML 打包成一个 jar 文件并导入到 SceneBuilder。

【讨论】:

    猜你喜欢
    • 2015-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多