/*
* Copyright (C) 2014 Shashank Tulsyan
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package util.fx;
import javafx.animation.*;
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Worker;
import javafx.event.*;
import javafx.geometry.Pos;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.scene.text.Text;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import javafx.util.Duration;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
/**
* Example of a sidebar that slides in and out of view
*/
public class SlideOut extends Application {
private static final String[] lyrics = {
"And in the end,\nthe love you take,\nis equal to\nthe love\nyou make.",
"She came in through\nthe bathroom window\nprotected by\na silver\nspoon.",
"I've got to admit\nit's getting better,\nA little better\nall the time."
};
private static final String[] locs = {
"http://www.youtube.com/watch?v=osAA8q86COY&feature=player_detailpage#t=367s",
"http://www.youtube.com/watch?v=IM2Ttov_zR0&feature=player_detailpage#t=30s",
"http://www.youtube.com/watch?v=Jk0dBZ1meio&feature=player_detailpage#t=25s"
};
WebView webView;
public static void main(String[] args) throws Exception {
launch(args);
}
public void start(final Stage stage) throws Exception {
stage.setTitle("Slide out YouTube demo");
// create a WebView to show to the right of the SideBar.
webView = new WebView();
webView.getEngine().getLoadWorker().stateProperty().addListener(new ChangeListener<Worker.State>() {
@Override public void changed(ObservableValue<? extends Worker.State> ov, Worker.State t, Worker.State t1) {
if (t1.equals(Worker.State.SUCCEEDED)) {
Document d = webView.getEngine().documentProperty().get();
NodeList nl = d.getElementsByTagName("*");
for (int i = 0; i < nl.getLength(); i++) {
System.out.println(nl.item(i).getTextContent());
}
}
}
});
webView.setPrefSize(800, 600);
// create a sidebar with some content in it.
final Pane lyricPane = createSidebarContent();
SideBar sidebar = new SideBar(250, lyricPane);
VBox.setVgrow(lyricPane, Priority.ALWAYS);
// layout the scene.
final BorderPane layout = new BorderPane();
Pane mainPane = VBoxBuilder.create().spacing(10)
.children(
sidebar.getControlButton(),
webView
).build();
layout.setLeft(sidebar);
layout.setCenter(mainPane);
// show the scene.
Scene scene = new Scene(layout);
scene.getStylesheets().add(getClass().getResource("slideout.css").toExternalForm());
stage.setScene(scene);
stage.show();
}
private BorderPane createSidebarContent() {// create some content to put in the sidebar.
final Text lyric = new Text();
lyric.getStyleClass().add("lyric-text");
final Button changeLyric = new Button("New Song");
changeLyric.getStyleClass().add("change-lyric");
changeLyric.setMaxWidth(Double.MAX_VALUE);
changeLyric.setOnAction(new EventHandler<ActionEvent>() {
int lyricIndex = 0;
@Override
public void handle(ActionEvent actionEvent) {
lyricIndex++;
if (lyricIndex == lyrics.length) {
lyricIndex = 0;
}
lyric.setText(lyrics[lyricIndex]);
webView.getEngine().load(locs[lyricIndex]);
}
});
changeLyric.fire();
final BorderPane lyricPane = new BorderPane();
lyricPane.setCenter(lyric);
lyricPane.setBottom(changeLyric);
return lyricPane;
}
/**
* Animates a node on and off screen to the left.
*/
class SideBar extends VBox {
/**
* @return a control button to hide and show the sidebar
*/
public Button getControlButton() {
return controlButton;
}
private final Button controlButton;
/**
* creates a sidebar containing a vertical alignment of the given nodes
*/
SideBar(final double expandedWidth, Node... nodes) {
getStyleClass().add("sidebar");
this.setPrefWidth(expandedWidth);
this.setMinWidth(0);
// create a bar to hide and show.
setAlignment(Pos.CENTER);
getChildren().addAll(nodes);
// create a button to hide and show the sidebar.
controlButton = new Button("Collapse");
controlButton.getStyleClass().add("hide-left");
// apply the animations when the button is pressed.
controlButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent actionEvent) {
// create an animation to hide sidebar.
final Animation hideSidebar = new Transition() {
{
setCycleDuration(Duration.millis(250));
}
protected void interpolate(double frac) {
final double curWidth = expandedWidth * (1.0 - frac);
setPrefWidth(curWidth);
setTranslateX(-expandedWidth + curWidth);
}
};
hideSidebar.onFinishedProperty().set(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent actionEvent) {
setVisible(false);
controlButton.setText("Show");
controlButton.getStyleClass().remove("hide-left");
controlButton.getStyleClass().add("show-right");
}
});
// create an animation to show a sidebar.
final Animation showSidebar = new Transition() {
{
setCycleDuration(Duration.millis(250));
}
protected void interpolate(double frac) {
final double curWidth = expandedWidth * frac;
setPrefWidth(curWidth);
setTranslateX(-expandedWidth + curWidth);
}
};
showSidebar.onFinishedProperty().set(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent actionEvent) {
controlButton.setText("Collapse");
controlButton.getStyleClass().add("hide-left");
controlButton.getStyleClass().remove("show-right");
}
});
if (showSidebar.statusProperty().get() == Animation.Status.STOPPED && hideSidebar.statusProperty().get() == Animation.Status.STOPPED) {
if (isVisible()) {
hideSidebar.play();
} else {
setVisible(true);
showSidebar.play();
}
}
}
});
}
}
}