Java 获取侦听器类以更改控制器中标签的值

Java 获取侦听器类以更改控制器中标签的值,java,Java,我不熟悉Java和JavaFX——我正在制作一个小型播放器应用程序,并且发现让持续时间计时器显示在显示器上的标签上是一个挑战 我最近的一次尝试是创建一个TimeListener.java类,该类将更改播放的每首新歌的持续时间值,并将它们设置在另一个类的标签上,但这个想法是有缺陷的,因为我遇到了一个非静态错误 TrackPlayer对象类 TimeListener类 我还能怎么解决这个问题呢?我想要一个标签,它会显示像00:00:00(经过)/00:00:00(持续时间),但我确信,如果我只是让持

我不熟悉Java和JavaFX——我正在制作一个小型播放器应用程序,并且发现让持续时间计时器显示在显示器上的标签上是一个挑战

我最近的一次尝试是创建一个TimeListener.java类,该类将更改播放的每首新歌的持续时间值,并将它们设置在另一个类的标签上,但这个想法是有缺陷的,因为我遇到了一个非静态错误

TrackPlayer对象类 TimeListener类 我还能怎么解决这个问题呢?我想要一个标签,它会显示像00:00:00(经过)/00:00:00(持续时间),但我确信,如果我只是让持续时间工作,我也可以让经过的时间工作

具有相同问题但大多数(如果不是全部)功能已删除的示例

田径运动员班 TrackPlayer FXML 但是,当我这样做时,侦听器不会被初始化,因为运行时标签根本不会改变。这是我要解决的问题。如何着手修复它?

非基于FXML的示例

下面是一些示例代码,它不使用FXML,但无论是否涉及FXML,原则都是一样的。您只需向相关属性添加一个侦听器,并在其更改时执行操作。我没有像你在问题中那样设置持续时间的格式,但这很琐碎,不同于响应侦听器中的更改的问题

我应该把听众放在哪里

在没有看到完整代码的情况下很难推荐,所以我只做一些假设,并提供一些建议,让您开始。那么,让我们假设:

  • 您正在FXML中定义并嵌入自定义媒体播放器控件,类似于中概述的机制:
  • 由于某些原因,持续时间跟踪标签不是自定义媒体控件的一部分
  • 因此,FXML包含两个组件:自定义媒体播放器和持续时间标签
  • 在这种情况下,侦听器位于包含媒体播放器和持续时间标签的FXML文件的控制器中,并在该控制器的
    initialize()
    调用期间设置

    基于FXML的样本

    一般来说,对于类似这样的通用重用,您可能会如前面所述创建一个自定义控件,但为了简洁起见,此示例将只使用内置的MediaView和Label控件,而不是自定义控件

    <?xml version="1.0" encoding="UTF-8"?>
    
    <?import javafx.scene.control.Label?>
    <?import javafx.scene.layout.VBox?>
    <?import javafx.scene.media.MediaView?>
    <VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" spacing="10.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="plot.VideoPlayerController">
       <children>
          <Label fx:id="progress" text="Label" />
          <MediaView fx:id="mediaView" fitHeight="208.0" fitWidth="540.0" />
       </children>
    </VBox>
    
    控制器

    基于非FXML的样本

    下面是一些示例代码,它不使用FXML,但无论是否涉及FXML,原则都是一样的。您只需向相关属性添加一个侦听器,并在其更改时执行操作。我没有像你在问题中那样设置持续时间的格式,但这很琐碎,不同于响应侦听器中的更改的问题

    我应该把听众放在哪里

    在没有看到完整代码的情况下很难推荐,所以我只做一些假设,并提供一些建议,让您开始。那么,让我们假设:

  • 您正在FXML中定义并嵌入自定义媒体播放器控件,类似于中概述的机制:
  • 由于某些原因,持续时间跟踪标签不是自定义媒体控件的一部分
  • 因此,FXML包含两个组件:自定义媒体播放器和持续时间标签
  • 在这种情况下,侦听器位于包含媒体播放器和持续时间标签的FXML文件的控制器中,并在该控制器的
    initialize()
    调用期间设置

    基于FXML的样本

    一般来说,对于类似这样的通用重用,您可能会如前面所述创建一个自定义控件,但为了简洁起见,此示例将只使用内置的MediaView和Label控件,而不是自定义控件

    <?xml version="1.0" encoding="UTF-8"?>
    
    <?import javafx.scene.control.Label?>
    <?import javafx.scene.layout.VBox?>
    <?import javafx.scene.media.MediaView?>
    <VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" spacing="10.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="plot.VideoPlayerController">
       <children>
          <Label fx:id="progress" text="Label" />
          <MediaView fx:id="mediaView" fitHeight="208.0" fitWidth="540.0" />
       </children>
    </VBox>
    
    控制器


    我只是不明白一件事,我应该把听众放在哪里?我有一个TrackPlayer类,当您传递一个文件路径时,它具有函数,比如play、stop和构造函数中的TrackPlayer对象本身,还有一个controller类,其中我有所有按钮的函数。我一直试图找到一些关于这些东西的标准布局的东西,但我没有成功。如果我把它放在我唯一的其他侦听器(TrackPlayer的构造函数中)下面,我会得到一个错误,说控制器类中的setTime不能从静态上下文引用。我没有时间查看非现场资源,希望您在当前的答案中有足够的信息来帮助您确定应用程序的正确方法。对于以后的问题,你可以考虑在这个问题中提供一个完整的最小可编译代码,可以复制和粘贴,以便立即复制这个问题。我添加了产生相同问题的最小代码。我相信我理解问题发生的原因,但我不知道如何着手解决它。你会得到一个NullPointerException,因为你有一个TrackController的成员,你试图在不初始化的情况下使用它。你应该写:
    private TrackPlayer=new TrackPlayer(“某个文件名”)。您的代码中可能存在其他错误,这些错误将阻止它执行您想要的操作,但至少如果您正确地初始化了成员,将避免NullPointerException,并且GUI将显示。请看:是的,但如果你看我的代码,我只想在用户选择一首歌曲并决定播放它时加载一个TrackPlayer,而不是在启动时。我只是不明白一件事,我应该把听者放在哪里?我有一个TrackPlayer类,当您传递一个文件路径时,它具有函数,比如play、stop和构造函数中的TrackPlayer对象本身,还有一个controller类,其中我有所有按钮的函数。我一直试图找到一些关于这些东西的标准布局的东西,但我没有成功
    
        @FXML
        private Label runTime;
    
        ...
    
        public void setTime(String time) {
            //runTime.setText(time);
        }
    
    package logic;
    
    import javafx.beans.property.ReadOnlyObjectProperty;
    import javafx.scene.media.Media;
    import javafx.scene.media.MediaPlayer;
    import javafx.scene.media.MediaPlayer.Status;
    import javafx.util.Duration;
    
    public class TrackPlayer {
    
        private MediaPlayer player;
        private Media track;
        private String filepath;
    
        private Duration duration;
    
        public TrackPlayer(String filepath) {
            this.filepath = filepath;
            track = new Media(filepath);
            player = new MediaPlayer(track);
    
            player.setOnReady(() -> {
                duration = track.getDuration();
                System.out.println("Duration: " + duration);
            });
        }
    
        public void playSong() {
            System.out.println("Playing song");
            player.play();
        }
    
        public void pauseSong() {
            System.out.println("Pausing song");
            player.pause();
        }
    
        public void stopSong() {
            System.out.println("Stopping song");
            player.stop();
        }
    
        public Status getStatus() {
            return player.getStatus();
        }
    
        public Duration getDuration() {
            return duration;
        }
    
        public Duration getCurrentTime() {
            return player.getCurrentTime();
        }
    
        public Duration getStartTime() {
            return player.getStartTime();
        }
    
        public void setSeek(Duration duration) {
            player.seek(duration);
        }
    
        public Media getMedia() {
            return player.getMedia();
        }
    
        public ReadOnlyObjectProperty<Duration> currentTimeProperty() {
            return player.currentTimeProperty();
        }
    
        public Duration getTotalDuration() {
            return player.getTotalDuration();
        }
    }
    
    package gui;
    
    import java.io.IOException;
    import java.net.URL;
    import java.util.ResourceBundle;
    import javafx.event.ActionEvent;
    import javafx.fxml.FXML;
    import javafx.fxml.Initializable;
    import javafx.scene.control.Label;
    import javafx.scene.control.TableColumn;
    import javafx.scene.control.TableRow;
    import javafx.scene.control.TableView;
    import javafx.scene.control.cell.PropertyValueFactory;
    import logic.TrackPlayer;
    import logic.Track;
    
    public class TrackPlayerController implements Initializable {
    
        @FXML
        private TableView<Track> playingTable;
        @FXML
        private TableColumn<Track, String> playingTitleCol;
        @FXML
        private TableColumn<Track, String> playingArtistCol;
        @FXML
        private TableColumn<Track, String> playingGenreCol;
        @FXML
        private TableColumn<Track, String> playingRunTimeCol;
        @FXML
        private Label runTime;
    
        private TrackPlayer player;
    
        @Override
        public void initialize(URL fxmlFileLocation, ResourceBundle resources) {
            playingTitleCol.setCellValueFactory(new PropertyValueFactory<>("TrackTitle"));
            playingArtistCol.setCellValueFactory(new PropertyValueFactory<>("TrackArtist"));
            playingGenreCol.setCellValueFactory(new PropertyValueFactory<>("TrackGenre"));
            playingRunTimeCol.setCellValueFactory(new PropertyValueFactory<>("RunTime"));
    
            player.currentTimeProperty().addListener(observable -> {
                setTime(player.getCurrentTime()
                        + " / "
                        + player.getTotalDuration());
            });
    
            playingTable.setRowFactory(tv -> { // Function for double-click to play (load)
                TableRow<Track> row = new TableRow<>();
                row.setOnMouseClicked(event -> {
                    if (event.getClickCount() == 2 && (!row.isEmpty())) {
                        play();
                    }
                });
                return row;
            });
        }
    
        @FXML
        private void play() {
        }
    
        @FXML
        private void reset(ActionEvent e) {
        }
    
        @FXML
        private void remove(ActionEvent e) {
        }
    
        @FXML
        private void removeAll(ActionEvent e) {
        }
    
        @FXML
        private void search(ActionEvent e) throws IOException {
        }
    
        public void setTime(String time) {
            runTime.setText(time);
        }
    }
    
    package gui;
    
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.stage.Stage;
    import javafx.fxml.FXMLLoader;
    import javafx.scene.layout.BorderPane;
    
    public class TrackPlayerMain extends Application {
    
        @Override
        public void start(Stage primaryStage) throws Exception {
            BorderPane root = new BorderPane();
    
            FXMLLoader trackPlayerLoader = new FXMLLoader(getClass().getResource("TrackPlayer.fxml"));
            root.setCenter(trackPlayerLoader.load());
            TrackPlayerController trackPlayerController = trackPlayerLoader.getController();
    
            Scene scene = new Scene(root, 600, 400);
            primaryStage.setScene(scene);
            primaryStage.show();
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    
    }
    
    <?xml version="1.0" encoding="UTF-8"?>
    
    <?import javafx.scene.paint.*?>
    <?import javafx.scene.text.*?>
    <?import java.lang.*?>
    <?import java.util.*?>
    <?import javafx.scene.*?>
    <?import javafx.scene.control.*?>
    <?import javafx.scene.layout.*?>
    
    <AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="gui.TrackPlayerController">
       <children>
          <Slider fx:id="timeSlider" layoutX="9.0" layoutY="333.0" prefHeight="25.0" prefWidth="582.0" />
          <Label alignment="BOTTOM_LEFT" layoutX="23.0" layoutY="10.0" prefHeight="17.0" prefWidth="75.0" text="Now Playing" />
          <Button fx:id="play" layoutX="250.0" layoutY="361.0" mnemonicParsing="false" onAction="#play" prefHeight="25.0" prefWidth="100.0" text="Play" />
          <Button fx:id="ff" layoutX="356.0" layoutY="361.0" mnemonicParsing="false" text="&gt;&gt;" />
          <Button fx:id="rw" layoutX="211.0" layoutY="361.0" mnemonicParsing="false" text="&lt;&lt;" />
          <Button fx:id="reset" layoutX="22.0" layoutY="361.0" mnemonicParsing="false" onAction="#reset" prefWidth="59.0" text="Reset" />
          <Button fx:id="remove" layoutX="498.0" layoutY="305.0" mnemonicParsing="false" onAction="#remove" prefWidth="83.0" text="Remove" />
          <Label fx:id="runTime" alignment="TOP_CENTER" layoutX="516.0" layoutY="350.0" prefHeight="17.0" prefWidth="75.0" text="00:00 / 00:00" textFill="#00000065">
             <font>
                <Font size="11.0" />
             </font>
          </Label>
          <Button fx:id="removeAll" layoutX="401.0" layoutY="305.0" mnemonicParsing="false" onAction="#removeAll" prefHeight="25.0" prefWidth="83.0" text="Remove All" />
          <TableView fx:id="playingTable" layoutX="18.0" layoutY="32.0" prefHeight="263.0" prefWidth="563.0">
            <columns>
              <TableColumn fx:id="playingTitleCol" editable="false" prefWidth="140.75" resizable="false" text="Title" />
              <TableColumn fx:id="playingArtistCol" editable="false" prefWidth="140.75" resizable="false" text="Artist" />
                <TableColumn fx:id="playingGenreCol" editable="false" prefWidth="140.75" resizable="false" text="Genre" />
                <TableColumn fx:id="playingRunTimeCol" prefWidth="140.75" resizable="false" text="Run Time" />
            </columns>
             <columnResizePolicy>
                <TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
             </columnResizePolicy>
          </TableView>
          <Button fx:id="search" layoutX="303.0" layoutY="305.0" mnemonicParsing="false" onAction="#search" prefHeight="0.0" prefWidth="83.0" text="Search" />
       </children>
    </AnchorPane>
    
    if (player != null) {
        player.currentTimeProperty().addListener(observable -> {
            runTime.setText(player.getCurrentTime()
                    + " / "
                    + player.getTotalDuration());
        });
    }
    
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.control.Label;
    import javafx.scene.layout.VBox;
    import javafx.scene.media.*;
    import javafx.stage.Stage;
    
    public class VideoPlayerExample extends Application {
        private static final String MEDIA_LOC =
                "http://download.oracle.com/otndocs/products/javafx/oow2010-2.flv";
    
        @Override
        public void start(final Stage stage) throws Exception {
            final MediaPlayer oracleVid = new MediaPlayer(
                    new Media(MEDIA_LOC)
            );
    
            Label progress = new Label();
            oracleVid.currentTimeProperty().addListener(observable -> {
                progress.setText(
                        oracleVid.getCurrentTime()
                                + " / "
                                + oracleVid.getTotalDuration()
                );
            });
    
            VBox layout = new VBox(10, progress, new MediaView(oracleVid));
            stage.setScene(new Scene(layout, 540, 208));
            stage.show();
    
            oracleVid.play();
        }
    
        public static void main(String[] args) throws Exception {
            launch(args);
        }
    }
    
    <?xml version="1.0" encoding="UTF-8"?>
    
    <?import javafx.scene.control.Label?>
    <?import javafx.scene.layout.VBox?>
    <?import javafx.scene.media.MediaView?>
    <VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" spacing="10.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="plot.VideoPlayerController">
       <children>
          <Label fx:id="progress" text="Label" />
          <MediaView fx:id="mediaView" fitHeight="208.0" fitWidth="540.0" />
       </children>
    </VBox>
    
    import javafx.application.Application;
    import javafx.fxml.FXMLLoader;
    import javafx.scene.Parent;
    import javafx.scene.Scene;
    import javafx.stage.Stage;
    
    public class VideoPlayerApp extends Application {
        @Override
        public void start(final Stage stage) throws Exception {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("player.fxml"));
            Parent root = loader.load();
    
            stage.setScene(new Scene(root));
            stage.show();
        }
    
        public static void main(String[] args) throws Exception {
            launch(args);
        }
    }
    
    import javafx.fxml.FXML;
    import javafx.scene.control.Label;
    import javafx.scene.media.Media;
    import javafx.scene.media.MediaPlayer;
    import javafx.scene.media.MediaView;
    
    public class VideoPlayerController {    
        private static final String MEDIA_LOC =
                "http://download.oracle.com/otndocs/products/javafx/oow2010-2.flv";
    
        @FXML
        MediaView mediaView;
    
        @FXML
        Label progress;
    
        public void initialize() {
            final MediaPlayer oracleVid = new MediaPlayer(
                    new Media(MEDIA_LOC)
            );
    
            oracleVid.currentTimeProperty().addListener(observable -> {
                progress.setText(
                        oracleVid.getCurrentTime()
                                + " / "
                                + oracleVid.getTotalDuration()
                );
            });
    
            mediaView.setMediaPlayer(oracleVid);
    
            oracleVid.play();
        }    
    }