Skip to content

Commit

Permalink
Make player controller even smaller.
Browse files Browse the repository at this point in the history
  • Loading branch information
wrandelshofer committed Aug 18, 2024
1 parent 6a0e190 commit e31f7d0
Show file tree
Hide file tree
Showing 10 changed files with 212 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,22 @@ void open(ActionEvent event) {
}
}

@FXML
void play(ActionEvent event) {
MediaPlayerInterface player = getPlayer();
if (player != null) {
player.play();
}
}

@FXML
void pause(ActionEvent event) {
MediaPlayerInterface player = getPlayer();
if (player != null) {
player.pause();
}
}

private Stage getStage() {
Scene scene = rootPane.getScene();
return scene == null ? null : (Stage) scene.getWindow();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,6 @@ public class PlayerControlsController extends AnchorPane {
@FXML // fx:id="timeSlider"
private Slider timeSlider; // Value injected by FXMLLoader

@FXML // fx:id="volumeSlider"
private Slider volumeSlider; // Value injected by FXMLLoader
private final ObjectProperty<MediaPlayerInterface> player = new SimpleObjectProperty<>();


Expand Down Expand Up @@ -143,16 +141,13 @@ void initialize() {
assert rootPane != null : "fx:id=\"rootPane\" was not injected: check your FXML file 'PlayerControls.fxml'.";
assert timeLabel != null : "fx:id=\"timeLabel\" was not injected: check your FXML file 'PlayerControls.fxml'.";
assert timeSlider != null : "fx:id=\"timeSlider\" was not injected: check your FXML file 'PlayerControls.fxml'.";
assert volumeSlider != null : "fx:id=\"volumeSlider\" was not injected: check your FXML file 'PlayerControls.fxml'.";

ControllerPaneMouseDraggedHandler dh = new ControllerPaneMouseDraggedHandler(this);

ControllerPaneVisibleHandler vh = new ControllerPaneVisibleHandler(this);
player.addListener(this::playerChanged);
volumeSlider.disableProperty().bind(muteButton.selectedProperty());

muteButton.visibleProperty().bind(hasAudio);
volumeSlider.visibleProperty().bind(hasAudio);

timeSlider.valueProperty().addListener(this::timeSliderChanged);
}
Expand Down Expand Up @@ -195,7 +190,6 @@ private void playerChanged(Observable observable, MediaPlayerInterface oldValue,
oldValue.currentTimeProperty().removeListener(currentTimeHandler);
timeLabel.textProperty().unbind();
newValue.statusProperty().removeListener(statusChangeListener);
volumeSlider.valueProperty().unbindBidirectional(oldValue.volumeProperty());
muteButton.selectedProperty().unbindBidirectional(oldValue.muteProperty());
oldValue.getMedia().getTracks().removeListener(trackHandler);
}
Expand All @@ -208,7 +202,6 @@ private void playerChanged(Observable observable, MediaPlayerInterface oldValue,
));
newValue.currentTimeProperty().addListener(currentTimeHandler);
newValue.statusProperty().addListener(statusChangeListener);
volumeSlider.valueProperty().bindBidirectional(newValue.volumeProperty());
muteButton.selectedProperty().bindBidirectional(newValue.muteProperty());
newValue.getMedia().getTracks().addListener(trackHandler);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* @(#)FXTrack.java
* Copyright © 2024 Werner Randelshofer, Switzerland. MIT License.
*/

package org.monte.demo.javafx.movieplayer.fxplayer;

import javafx.scene.media.AudioTrack;
import org.monte.demo.javafx.movieplayer.model.AudioTrackInterface;

import java.util.Locale;
import java.util.Map;

public class FXAudioTrack implements AudioTrackInterface {
private final AudioTrack track;

public FXAudioTrack(AudioTrack track) {
this.track = track;
}

@Override
public Locale getLocale() {
return track.getLocale();
}

@Override
public Map<String, Object> getMetadata() {
return track.getMetadata();
}

@Override
public String getName() {
return track.getName();
}

@Override
public long getTrackID() {
return track.getTrackID();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,14 @@
import javafx.beans.property.ReadOnlyIntegerProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.collections.ObservableMap;
import javafx.scene.media.AudioTrack;
import javafx.scene.media.Media;
import javafx.scene.media.SubtitleTrack;
import javafx.scene.media.Track;
import javafx.scene.media.VideoTrack;
import javafx.util.Duration;
import org.monte.demo.javafx.movieplayer.model.MediaInterface;
import org.monte.demo.javafx.movieplayer.model.TrackInterface;
Expand All @@ -20,10 +25,44 @@
* Adapter for JavaFX {@link Media}.
*/
public class FXMedia implements MediaInterface {
private final ObservableList<TrackInterface> tracks = FXCollections.observableArrayList();

private final Media media;

public FXMedia(Media media) {
this.media = media;
for (Track track : media.getTracks()) {
switch (track) {
case VideoTrack t -> tracks.add(new FXVideoTrack(t));
case AudioTrack t -> tracks.add(new FXAudioTrack(t));
case SubtitleTrack t -> tracks.add(new FXSubtitleTrack(t));
default -> tracks.add(new FXTrack(track));
}
}

media.getTracks().addListener(new ListChangeListener<Track>() {
@Override
public void onChanged(Change<? extends Track> c) {
while (c.next()) {
if (c.wasRemoved()) {
tracks.subList(c.getFrom(), c.getTo()).clear();
;
}
if (c.wasAdded()) {
int i = c.getFrom();
for (Track track : c.getAddedSubList()) {
switch (track) {
case VideoTrack t -> tracks.add(i, new FXVideoTrack(t));
case AudioTrack t -> tracks.add(i, new FXAudioTrack(t));
case SubtitleTrack t -> tracks.add(i, new FXSubtitleTrack(t));
default -> tracks.add(i, new FXTrack(track));
}
i++;
}
}
}
}
});
}

@Override
Expand Down Expand Up @@ -69,9 +108,7 @@ public String getSource() {

@Override
public ObservableList<TrackInterface> getTracks() {
ObservableList<TrackInterface> result = FXCollections.observableArrayList();
media.getTracks().forEach(t -> result.add(new FXTrack(t)));
return result;
return tracks;
}


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@

/*
* @(#)FXTrack.java
* Copyright © 2024 Werner Randelshofer, Switzerland. MIT License.
*/

package org.monte.demo.javafx.movieplayer.fxplayer;

import javafx.scene.media.SubtitleTrack;
import org.monte.demo.javafx.movieplayer.model.SubtitleTrackInterface;

import java.util.Locale;
import java.util.Map;

public class FXSubtitleTrack implements SubtitleTrackInterface {
private final SubtitleTrack track;

public FXSubtitleTrack(SubtitleTrack track) {
this.track = track;
}


@Override
public Locale getLocale() {
return track.getLocale();
}

@Override
public Map<String, Object> getMetadata() {
return track.getMetadata();
}

@Override
public String getName() {
return track.getName();
}

@Override
public long getTrackID() {
return track.getTrackID();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* @(#)FXTrack.java
* Copyright © 2024 Werner Randelshofer, Switzerland. MIT License.
*/

package org.monte.demo.javafx.movieplayer.fxplayer;

import javafx.scene.media.VideoTrack;
import org.monte.demo.javafx.movieplayer.model.VideoTrackInterface;

import java.util.Locale;
import java.util.Map;

public class FXVideoTrack implements VideoTrackInterface {
private final VideoTrack track;

public FXVideoTrack(VideoTrack track) {
this.track = track;
}

@Override
public int getHeight() {
return track.getHeight();
}

@Override
public int getWidth() {
return track.getWidth();
}

@Override
public Locale getLocale() {
return track.getLocale();
}

@Override
public Map<String, Object> getMetadata() {
return track.getMetadata();
}

@Override
public String getName() {
return track.getName();
}

@Override
public long getTrackID() {
return track.getTrackID();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -332,10 +332,12 @@ protected void doStarted() throws Exception {
private void stopAudio() {
for (var t : media.getTracks()) {
if (t instanceof MonteAudioTrack mat) {
SourceDataLine sourceDataLine = mat.getSourceDataLine();
if (sourceDataLine != null) {
sourceDataLine.flush();
}
mat.dispatcher.execute(() -> {
SourceDataLine sourceDataLine = mat.getSourceDataLine();
if (sourceDataLine != null) {
sourceDataLine.flush();
}
});
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,7 @@ error.creatingPlayer=Can not play this file
view.zoomToActualSize=Zoom to Actual Size
view.zoomToFit=Zoom to Fit
view.zoomIn=Zoom in
view.zoomOut=Zoom out
view.zoomOut=Zoom out
play.menu=Play
play.menuItem=Play
pause.menuItem=Pause
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
<?import javafx.scene.input.KeyCodeCombination?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.StackPane?>
<BorderPane fx:id="rootPane" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
xmlns="http://javafx.com/javafx/22" xmlns:fx="http://javafx.com/fxml/1"
<BorderPane fx:id="rootPane" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="120.0"
minWidth="240.0" xmlns="http://javafx.com/javafx/22" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="org.monte.demo.javafx.movieplayer.MainWindowController">
<top>
<MenuBar useSystemMenuBar="true" BorderPane.alignment="CENTER">
Expand All @@ -27,6 +27,12 @@
</MenuItem>
</items>
</Menu>
<Menu mnemonicParsing="false" text="%play.menu">
<items>
<MenuItem mnemonicParsing="false" onAction="#play" text="%play.menuItem"/>
<MenuItem mnemonicParsing="false" onAction="#pause" text="%pause.menuItem"/>
</items>
</Menu>
<Menu mnemonicParsing="false" text="%view.menu">
<items>
<MenuItem mnemonicParsing="false" onAction="#zoomToActualSize" text="%view.zoomToActualSize">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,11 @@
<children>
<GridPane fx:id="controllerPane" hgap="4.0" layoutX="4.0" layoutY="100.0" maxHeight="-Infinity" maxWidth="-Infinity"
minHeight="-Infinity" minWidth="-Infinity" styleClass="controls-panel" vgap="4.0"
AnchorPane.bottomAnchor="4.0" AnchorPane.leftAnchor="4.0">
AnchorPane.bottomAnchor="4.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="24.0"/>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="48.0"/>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="40.0"/>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="48.0"/>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="40.0"/>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="48.0"/>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="24.0"/>
</columnConstraints>
Expand All @@ -31,25 +29,24 @@
<RowConstraints minHeight="10.0" prefHeight="24.0" vgrow="SOMETIMES"/>
</rowConstraints>
<children>
<Slider fx:id="volumeSlider" disable="true" max="1.0" GridPane.columnIndex="1"/>
<Button fx:id="backwardButton" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity"
minWidth="-Infinity" mnemonicParsing="false" onAction="#seekBackward" prefHeight="24.0" prefWidth="24.0"
styleClass="backward-button" GridPane.columnIndex="2" GridPane.halignment="RIGHT"/>
styleClass="backward-button" GridPane.columnIndex="1" GridPane.halignment="RIGHT"/>
<ToggleButton fx:id="playButton" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity"
minWidth="-Infinity" mnemonicParsing="false" onAction="#togglePlayPause" prefHeight="32.0"
prefWidth="32.0" styleClass="play-button" GridPane.columnIndex="3" GridPane.halignment="CENTER"/>
prefWidth="32.0" styleClass="play-button" GridPane.columnIndex="2" GridPane.halignment="CENTER"/>
<Button fx:id="forwardButton" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity"
minWidth="-Infinity" mnemonicParsing="false" onAction="#seekForward" prefHeight="24.0" prefWidth="24.0"
styleClass="forward-button" GridPane.columnIndex="4"/>
<Label fx:id="timeLabel" styleClass="time-label" text="00:00.0000" GridPane.columnIndex="2"
styleClass="forward-button" GridPane.columnIndex="3"/>
<Label fx:id="timeLabel" styleClass="time-label" text="00:00.0000" GridPane.columnIndex="1"
GridPane.columnSpan="3" GridPane.halignment="CENTER" GridPane.rowIndex="2"/>
<Slider fx:id="timeSlider" GridPane.columnSpan="7" GridPane.rowIndex="1"/>
<ToggleButton fx:id="muteButton" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity"
minWidth="-Infinity" mnemonicParsing="false" prefHeight="24.0" prefWidth="24.0"
styleClass="mute-button" GridPane.halignment="RIGHT"/>
</children>
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
<Insets bottom="8.0" left="8.0" right="8.0" top="8.0"/>
</padding>
</GridPane>
</children>
Expand Down

0 comments on commit e31f7d0

Please sign in to comment.