1 /* 2 * Copyright (c) 2008, 2015, Oracle and/or its affiliates. 3 * All rights reserved. Use is subject to license terms. 4 * 5 * This file is available and licensed under the following license: 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * - Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * - Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the distribution. 16 * - Neither the name of Oracle Corporation nor the names of its 17 * contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 package ensemble; 33 34 import ensemble.generated.Samples; 35 import javafx.beans.property.ReadOnlyStringProperty; 36 import javafx.beans.value.ChangeListener; 37 import javafx.beans.value.ObservableValue; 38 import javafx.event.ActionEvent; 39 import javafx.event.EventHandler; 40 import javafx.geometry.Insets; 41 import javafx.geometry.Pos; 42 import javafx.scene.Node; 43 import javafx.scene.control.Button; 44 import javafx.scene.control.ContentDisplay; 45 import javafx.scene.control.Label; 46 import javafx.scene.control.ScrollPane; 47 import javafx.scene.layout.Region; 48 import javafx.scene.layout.VBox; 49 import javafx.scene.web.WebView; 50 51 /** 52 * Ensmeble page for showing a page of documentation from the web 53 */ 54 public class DocsPage extends Region implements ChangeListener<String>, Page{ 55 private final WebView webView = new WebView(); 56 private final ScrollPane scrollPane = new ScrollPane(); 57 private final VBox sideBar = new VBox(10); 58 private final Label sideBarTitle = new Label("Related Samples:"); 59 private final PageBrowser pageBrowser; 60 private boolean isLocalChange = false; 61 private boolean showSideBar = false; 62 63 public DocsPage(PageBrowser pageBrowser) { 64 this.pageBrowser = pageBrowser; 65 getChildren().add(webView); 66 scrollPane.setContent(sideBar); 67 sideBar.setAlignment(Pos.TOP_CENTER); 68 sideBar.getChildren().add(sideBarTitle); 69 sideBarTitle.getStyleClass().add("sidebar-title"); 70 scrollPane.setFitToWidth(true); 71 sideBar.setPadding(new Insets(10)); 72 webView.getEngine().locationProperty().addListener(this); 73 } 74 75 @Override public ReadOnlyStringProperty titleProperty() { 76 return webView.getEngine().titleProperty(); 77 } 78 79 @Override public String getTitle() { 80 return webView.getEngine().getTitle(); 81 } 82 83 @Override public String getUrl() { 84 return webView.getEngine().getLocation(); 85 } 86 87 @Override public Node getNode() { 88 return this; 89 } 90 91 @Override public void changed(ObservableValue<? extends String> ov, String oldLocation, String newLocation) { 92 if (!isLocalChange) pageBrowser.externalPageChange(newLocation); 93 updateSidebar(newLocation); 94 } 95 96 public void goToUrl(String url) { 97 isLocalChange = true; 98 webView.getEngine().load(url); 99 isLocalChange = false; 100 } 101 102 @Override protected void layoutChildren() { 103 final double w = getWidth(); 104 final double h = getHeight(); 105 if (showSideBar) { 106 final double sideBarWidth = sideBar.prefWidth(-1)+14; 107 webView.resize(w - sideBarWidth, h); 108 scrollPane.setLayoutX(w - sideBarWidth); 109 scrollPane.resize(sideBarWidth, h); 110 } else { 111 webView.resize(w,h); 112 } 113 } 114 115 private void updateSidebar(String url) { 116 String key = url; 117 if (key.startsWith("https://docs.oracle.com/javase/8/javafx/api/")) { 118 key = key.substring("https://docs.oracle.com/javase/8/javafx/api/".length(), key.lastIndexOf('.')); 119 key = key.replaceAll("/", "."); 120 } else if (key.startsWith("https://docs.oracle.com/javase/8/docs/api/")) { 121 key = key.substring("https://docs.oracle.com/javase/8/docs/api/".length(), key.lastIndexOf('.')); 122 key = key.replaceAll("/", "."); 123 } 124 SampleInfo[] samples = Samples.getSamplesForDoc(key); 125 if (samples == null || samples.length == 0) { 126 sideBar.getChildren().clear(); 127 getChildren().remove(scrollPane); 128 showSideBar = false; 129 } else { 130 sideBar.getChildren().setAll(sideBarTitle); 131 for (final SampleInfo sample: samples) { 132 Button sampleButton = new Button(sample.name); 133 sampleButton.setCache(true); 134 sampleButton.getStyleClass().setAll("sample-button"); 135 sampleButton.setGraphic(sample.getMediumPreview()); 136 sampleButton.setContentDisplay(ContentDisplay.TOP); 137 sampleButton.setOnAction((ActionEvent actionEvent) -> { 138 pageBrowser.goToSample(sample); 139 }); 140 sideBar.getChildren().add(sampleButton); 141 } 142 if (!showSideBar) getChildren().add(scrollPane); 143 showSideBar = true; 144 } 145 } 146 }