1
0
Fork 0

Implemented playback

master
Ambrose Chua 2015-10-07 22:43:26 +08:00
parent 03b82d5973
commit e6071248ff
5 changed files with 145 additions and 32 deletions

View File

@ -1,6 +1,7 @@
package io.makerforce.undefined;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
@ -14,33 +15,41 @@ import java.util.concurrent.TimeUnit;
public class Main extends Application {
private Stage mainStage;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
public void start(Stage initStage) throws Exception {
Parent splashRoot = FXMLLoader.load(getClass().getResource("view/splash.fxml"));
Scene splashScene = new Scene(splashRoot, 300, 200);
primaryStage.initStyle(StageStyle.UNDECORATED);
primaryStage.setScene(splashScene);
primaryStage.show();
initStage.initStyle(StageStyle.UNDECORATED);
initStage.setScene(splashScene);
initStage.toFront();
initStage.show();
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
executor.schedule(() -> {
Parent root = null;
try {
root = FXMLLoader.load(getClass().getResource("view/interface.fxml"));
} catch (IOException e) {
e.printStackTrace();
}
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 640, 480));
primaryStage.show();
primaryStage.toFront();
executor.shutdown();
}, 2, TimeUnit.SECONDS);
Platform.runLater(() -> {
initStage.close();
Parent root = null;
try {
root = FXMLLoader.load(getClass().getResource("view/interface.fxml"));
} catch (IOException e) {
e.printStackTrace();
System.exit(284);
}
mainStage = new Stage(StageStyle.DECORATED);
mainStage.setTitle("Undefined");
mainStage.setScene(new Scene(root, 640, 480));
mainStage.show();
executor.shutdown();
});
}, 1500, TimeUnit.MILLISECONDS);
}
}

View File

@ -0,0 +1,11 @@
package io.makerforce.undefined.model;
import javafx.util.Duration;
public class Util {
public static String durationToString(Duration d) {
int sec = (int) d.toSeconds();
return String.format((sec < 0 ? "-" : "") + "%d:%02d", (sec < 0 ? -sec : sec) / 60, ((sec < 0 ? -sec : sec) % 60));
}
}

View File

@ -1,5 +1,10 @@
package io.makerforce.undefined.view;
import io.makerforce.undefined.model.Util;
import javafx.application.Platform;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ChangeListener;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
@ -7,10 +12,16 @@ import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.VBox;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.util.Duration;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class InterfaceController {
@FXML
private VBox leftPane;
@ -58,9 +69,14 @@ public class InterfaceController {
@FXML
private ImageView statusIcon;
private MediaPlayer player;
private BooleanProperty isPlaying = new SimpleBooleanProperty(false);
public InterfaceController() {
player = new MediaPlayer(new Media("http://ambrose.makerforce.io/audio.mp3"));
}
@ -68,12 +84,88 @@ public class InterfaceController {
// UI Bindings
currentImage.fitWidthProperty().bind(leftPane.widthProperty());
currentImage.fitHeightProperty().bind(currentImage.fitWidthProperty());
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
executor.schedule(() -> {
Platform.runLater(() -> {
currentImage.fitWidthProperty().bind(leftPane.widthProperty());
currentImage.fitHeightProperty().bind(currentImage.fitWidthProperty());
});
executor.shutdown();
}, 100, TimeUnit.MILLISECONDS);
// Raw bindings
showList.setItems(showListItems);
((SelectionModel) showList.selectionModelProperty().get()).clearAndSelect(0);
player.muteProperty().bind(muteToggle.selectedProperty());
player.volumeProperty().bind(volumeSlider.valueProperty());
// Player events
// Playback status
player.statusProperty().addListener((observable, oldValue, s) -> {
if (
s == MediaPlayer.Status.PAUSED ||
s == MediaPlayer.Status.READY ||
s == MediaPlayer.Status.STOPPED ||
s == MediaPlayer.Status.UNKNOWN ||
s == MediaPlayer.Status.HALTED
) {
pausePlayButtonIcon.setImage(playIcon);
isPlaying.setValue(false);
} else {
pausePlayButtonIcon.setImage(pauseIcon);
isPlaying.setValue(true);
}
});
// Update slider position when music plays.
ChangeListener<Duration> updateSlider = (observable, oldValue, c) -> {
playbackSlider.setValue(c.toMillis() / player.getTotalDuration().toMillis());
playbackTimeLabel.setText(Util.durationToString(player.getCurrentTime()));
};
player.currentTimeProperty().addListener(updateSlider);
// Update labels.
playbackSlider.valueProperty().addListener((observable1, oldValue1, v) -> {
Duration d = new Duration(v.doubleValue() * player.getTotalDuration().toMillis());
playbackTimeLabel.setText(Util.durationToString(d));
playbackLeftLabel.setText(Util.durationToString(d.subtract(player.getTotalDuration())));
});
// Seek when slider is released.
playbackSlider.valueChangingProperty().addListener((observable, oldValue, c) -> {
if (c) {
player.currentTimeProperty().removeListener(updateSlider);
} else {
player.currentTimeProperty().addListener(updateSlider);
player.seek(new Duration(playbackSlider.getValue() * player.getTotalDuration().toMillis()));
}
});
}
@FXML
private void pausePlay() {
if (isPlaying.get()) {
player.pause();
} else {
player.play();
}
}
@FXML
private void nextTrack() {
}
@FXML
private void previousTrack() {
}

View File

@ -16,7 +16,7 @@
<children>
<HBox alignment="CENTER" spacing="7.0">
<children>
<Button fx:id="previousButton" mnemonicParsing="false">
<Button fx:id="previousButton" mnemonicParsing="false" onAction="#previousTrack">
<graphic>
<ImageView fitHeight="16.0" fitWidth="16.0" opacity="0.75" pickOnBounds="true"
preserveRatio="true">
@ -32,7 +32,7 @@
<Font size="1.0"/>
</font>
</Button>
<Button fx:id="pausePlayButton" mnemonicParsing="false">
<Button fx:id="pausePlayButton" mnemonicParsing="false" onAction="#pausePlay">
<graphic>
<ImageView fx:id="pausePlayButtonIcon" fitHeight="24.0" fitWidth="24.0" opacity="0.75"
pickOnBounds="true" preserveRatio="true">
@ -48,12 +48,12 @@
<Font size="1.0"/>
</font>
</Button>
<Button fx:id="nextButton" mnemonicParsing="false">
<Button fx:id="nextButton" mnemonicParsing="false" onAction="#nextTrack">
<graphic>
<ImageView fitHeight="16.0" fitWidth="16.0" opacity="0.75" pickOnBounds="true"
preserveRatio="true">
<image>
<Image url="@/icons/previous2.32.png"/>
<Image url="@/icons/next2.32.png"/>
</image>
</ImageView>
</graphic>
@ -72,9 +72,10 @@
<Separator orientation="VERTICAL"/>
<HBox alignment="CENTER" spacing="7.0" HBox.hgrow="ALWAYS">
<children>
<Label fx:id="playbackTimeLabel" text="1:50"/>
<Slider fx:id="playbackSlider" prefHeight="16.0" prefWidth="156.0" HBox.hgrow="ALWAYS"/>
<Label fx:id="playbackLeftLabel" text="-2:21"/>
<Label fx:id="playbackTimeLabel" text="0:00"/>
<Slider fx:id="playbackSlider" prefHeight="16.0" prefWidth="156.0" HBox.hgrow="ALWAYS" min="0.0"
max="1.0"/>
<Label fx:id="playbackLeftLabel" text="-0:00"/>
</children>
<HBox.margin>
<Insets/>
@ -99,7 +100,8 @@
<Font size="1.0"/>
</font>
</ToggleButton>
<Slider fx:id="volumeSlider" prefHeight="16.0" prefWidth="64.0"/>
<Slider fx:id="volumeSlider" max="1.0" min="0.0" prefHeight="16.0" prefWidth="64.0"
value="1.0"/>
</children>
</HBox>
<Separator orientation="VERTICAL"/>

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ProgressIndicator?>
<?import javafx.scene.layout.AnchorPane?>
@ -8,18 +7,18 @@
<AnchorPane xmlns:fx="http://javafx.com/fxml/1" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity"
minWidth="-Infinity" prefHeight="200.0" prefWidth="300.0" xmlns="http://javafx.com/javafx/8.0.40">
<children>
<Label layoutX="31.0" layoutY="24.0" text="Undefined">
<Label layoutX="31.0" layoutY="20.0" text="Undefined">
<font>
<Font name="System Bold" size="48.0"/>
</font>
</Label>
<Label layoutX="31.0" layoutY="83.0" text="Stream your music privately. ">
<Label layoutX="31.0" layoutY="79.0" text="Stream your music privately. ">
<font>
<Font size="18.0"/>
</font>
</Label>
<ProgressIndicator layoutX="134.0" layoutY="144.0" prefHeight="32.0" prefWidth="32.0"/>
<Label layoutX="92.0" layoutY="114.0" text="http://undefinedapp.com/">
<ProgressIndicator layoutX="134.0" layoutY="142.0" prefHeight="32.0" prefWidth="32.0"/>
<Label layoutX="92.0" layoutY="110.0" text="http://undefinedapp.com/">
<font>
<Font size="10.0"/>
</font>