/** * FXyzSampler_backup.java * * Copyright (c) 2013-2016, F(X)yz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of F(X)yz, any associated website, nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL F(X)yz BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package org.fxyz3d.ExtrasAndTests; import org.fxyz3d.FXyzSampleBase; import org.fxyz3d.FXyzSample; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URISyntaxException; import java.net.URL; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.Map; import javafx.application.Application; import javafx.beans.Observable; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.geometry.Rectangle2D; import javafx.scene.Node; import javafx.scene.Scene; import javafx.scene.SceneAntialiasing; import javafx.scene.control.Label; import javafx.scene.control.TextField; import javafx.scene.control.TreeCell; import javafx.scene.control.TreeItem; import javafx.scene.control.TreeView; import javafx.scene.layout.HBox; import javafx.scene.layout.Priority; import static javafx.scene.layout.Region.USE_COMPUTED_SIZE; import static javafx.scene.layout.Region.USE_PREF_SIZE; import javafx.scene.layout.StackPane; import javafx.scene.layout.VBox; import javafx.scene.paint.Color; import javafx.stage.Screen; import javafx.stage.Stage; import javafx.util.Callback; import org.fxyz3d.model.EmptySample; import org.fxyz3d.model.Project; import org.fxyz3d.model.SampleTree.TreeNode; import org.fxyz3d.model.WelcomePage; import org.fxyz3d.util.SampleScanner; public class FXyzSampler_backup extends Application { public static final String GLASS_BLACK_SMOKE = FXyzSampler_backup.class.getResource("cyanBlackGlass.css").toExternalForm(); ; private Map<String, Project> projectsMap; private Stage stage; private HBox rootContainer; private VBox leftContainer; private StackPane centerContainer; private VBox rightContainer; private FXyzSample selectedSample; private TreeView<FXyzSample> samplesTreeView; private TreeItem<FXyzSample> root; public static void main(String[] args) { launch(args); } @Override public void start(final Stage stage) throws Exception { Application.setUserAgentStylesheet(GLASS_BLACK_SMOKE); this.stage = stage; // primaryStage.getIcons().add(new Image("/org/controlsfx/samples/controlsfx-logo.png")); projectsMap = new SampleScanner().discoverSamples(); buildSampleTree(null); rootContainer = new HBox(); // --- left hand side leftContainer = new VBox(); leftContainer.setSpacing(3.0); // search box final TextField searchBox = new TextField(); searchBox.setPromptText("Search"); searchBox.getStyleClass().addAll("search-box", "fxyz3d-control"); searchBox.textProperty().addListener((Observable o) -> { buildSampleTree(searchBox.getText()); }); searchBox.setFocusTraversable(false); // treeview samplesTreeView = new TreeView<>(root); samplesTreeView.setShowRoot(false); samplesTreeView.getStyleClass().add("samples-tree"); samplesTreeView.setMinWidth(USE_PREF_SIZE); samplesTreeView.setMaxWidth(Double.MAX_VALUE); samplesTreeView.setCellFactory(new Callback<TreeView<FXyzSample>, TreeCell<FXyzSample>>() { @Override public TreeCell<FXyzSample> call(TreeView<FXyzSample> param) { return new TreeCell<FXyzSample>() { @Override protected void updateItem(FXyzSample item, boolean empty) { super.updateItem(item, empty); if (empty) { setText(""); } else { setText(item.getSampleName()); } } }; } }); samplesTreeView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<TreeItem<FXyzSample>>() { @Override public void changed(ObservableValue<? extends TreeItem<FXyzSample>> observable, TreeItem<FXyzSample> oldValue, TreeItem<FXyzSample> newSample) { if (newSample == null) { return; } else if (newSample.getValue() instanceof EmptySample) { FXyzSample selectedSample = newSample.getValue(); Project selectedProject = projectsMap.get(selectedSample.getSampleName()); System.out.println(selectedProject); if (selectedProject != null) { changeToWelcomeTab(selectedProject.getWelcomePage()); } return; } selectedSample = newSample.getValue(); changeSample(); } }); samplesTreeView.setFocusTraversable(false); samplesTreeView.getStyleClass().add("fxyz3d-control"); VBox.setVgrow(searchBox, Priority.NEVER); VBox.setVgrow(samplesTreeView, Priority.ALWAYS); leftContainer.getChildren().addAll(searchBox, samplesTreeView); leftContainer.setPrefSize(USE_PREF_SIZE, USE_COMPUTED_SIZE); HBox.setHgrow(leftContainer, Priority.SOMETIMES); // center stack centerContainer = new StackPane(); centerContainer.setPrefSize(USE_COMPUTED_SIZE, USE_COMPUTED_SIZE); HBox.setHgrow(centerContainer, Priority.ALWAYS); // by default we'll show the welcome message of first project in the tree // if no projects are available, we'll show the default page List<TreeItem<FXyzSample>> projects = samplesTreeView.getRoot().getChildren(); if (!projects.isEmpty()) { TreeItem<FXyzSample> firstProject = projects.get(0); samplesTreeView.getSelectionModel().select(firstProject); } else { changeToWelcomeTab(null); } rightContainer = new VBox(); rightContainer.setPrefSize(USE_PREF_SIZE, Double.MAX_VALUE); HBox.setHgrow(rightContainer, Priority.SOMETIMES); // scene root rootContainer = new HBox(leftContainer, centerContainer, rightContainer); rootContainer.setAlignment(Pos.CENTER); rootContainer.setSpacing(5); rootContainer.setPadding(new Insets(3)); rootContainer.setPrefSize(USE_COMPUTED_SIZE, USE_COMPUTED_SIZE); rootContainer.setFillHeight(true); // put it all together Scene scene = new Scene(rootContainer, 1024, 800, true, SceneAntialiasing.BALANCED); scene.setFill(Color.gray(0.6)); stage.setScene(scene); // set width / height values to be 75% of users screen resolution Rectangle2D screenBounds = Screen.getPrimary().getVisualBounds(); stage.setWidth(screenBounds.getWidth() * 0.75); stage.setHeight(screenBounds.getHeight() * .75); //stage.setMinWidth(grid.getPrefWidth()); stage.setTitle("FXyz-Sampler!"); stage.show(); rootContainer.getStyleClass().addAll("client-root"); } private String getUserInterfaceFXML(){ String fxmlPath = "", userDir; userDir = System.getProperty("user.dir"); return fxmlPath; } /*========================================================================== * TreeView ==========================================================================*/ protected void buildSampleTree(String searchText) { // rebuild the whole tree (it isn't memory intensive - we only scan // classes once at startup) root = new TreeItem<>(new EmptySample("FXyz-Sampler")); root.setExpanded(true); for (String projectName : projectsMap.keySet()) { final Project project = projectsMap.get(projectName); if (project == null) { continue; } // now work through the project sample tree building the rest TreeNode n = project.getSampleTree().getRoot(); root.getChildren().add(n.createTreeItem()); } // with this newly built and full tree, we filter based on the search text if (searchText != null) { pruneSampleTree(root, searchText); // FIXME weird bug in TreeView I think samplesTreeView.setRoot(null); samplesTreeView.setRoot(root); } // and finally we sort the display a little sort(root, (o1, o2) -> o1.getValue().getSampleName().compareTo(o2.getValue().getSampleName())); } private void sort(TreeItem<FXyzSample> node, Comparator<TreeItem<FXyzSample>> comparator) { node.getChildren().sort(comparator); for (TreeItem<FXyzSample> child : node.getChildren()) { sort(child, comparator); } } // true == keep, false == delete private boolean pruneSampleTree(TreeItem<FXyzSample> treeItem, String searchText) { // we go all the way down to the leaf nodes, and check if they match // the search text. If they do, they stay. If they don't, we remove them. // As we pop back up we check if the branch nodes still have children, // and if not we remove them too if (searchText == null) { return true; } if (treeItem.isLeaf()) { // check for match. Return true if we match (to keep), and false // to delete return treeItem.getValue().getSampleName().toUpperCase().contains(searchText.toUpperCase()); } else { // go down the tree... List<TreeItem<FXyzSample>> toRemove = new ArrayList<>(); for (TreeItem<FXyzSample> child : treeItem.getChildren()) { boolean keep = pruneSampleTree(child, searchText); if (!keep) { toRemove.add(child); } } // remove the unrelated tree items treeItem.getChildren().removeAll(toRemove); // return true if there are children to this branch, false otherwise // (by returning false we say that we should delete this now-empty branch) return !treeItem.getChildren().isEmpty(); } } /*========================================================================== * Sample Content Area =========================================================================*/ private void changeToWelcomeTab(WelcomePage wPage) { //change to index above 0 -> 0 will be content header overlay centerContainer.getChildren().removeIf(index-> centerContainer.getChildren().indexOf(index) == 0 && index instanceof StackPane); if (null == wPage) { wPage = getDefaultWelcomePage(); } centerContainer.getChildren().addAll(wPage.getContent()); } private WelcomePage getDefaultWelcomePage() { // line 1 Label welcomeLabel1 = new Label("Welcome to FXSampler!"); welcomeLabel1.setStyle("-fx-font-size: 2em; -fx-padding: 0 0 0 5;"); // line 2 Label welcomeLabel2 = new Label( "Explore the available UI controls and other interesting projects " + "by clicking on the options to the left."); welcomeLabel2.setStyle("-fx-font-size: 1.25em; -fx-padding: 0 0 0 5;"); WelcomePage wPage = new WelcomePage("Welcome!", new VBox(5, welcomeLabel1, welcomeLabel2)); return wPage; } protected void changeSample() { if (selectedSample == null) { return; } if (!centerContainer.getChildren().isEmpty()) { centerContainer.getChildren().clear(); rightContainer.getChildren().clear(); } updateTab(); } private void updateTab() { centerContainer.getChildren().addAll(buildSampleTabContent(selectedSample)); rightContainer.getChildren().add(selectedSample.getControlPanel()); } /*========================================================================== * Source Code Methods ==========================================================================*/ private String getResource(String resourceName, Class<?> baseClass) { Class<?> clz = baseClass == null ? getClass() : baseClass; return getResource(clz.getResourceAsStream(resourceName)); } private String getResource(InputStream is) { try (BufferedReader br = new BufferedReader(new InputStreamReader(is))) { String line; StringBuilder sb = new StringBuilder(); while ((line = br.readLine()) != null) { sb.append(line); sb.append("\n"); } return sb.toString(); } catch (IOException e) { e.printStackTrace(); return ""; } } private String getSourceCode(FXyzSample sample) { String sourceURL = sample.getSampleSourceURL(); try { // try loading via the web or local file system URL url = new URL(sourceURL); InputStream is = url.openStream(); return getResource(is); } catch (IOException e) { // no-op - the URL may not be valid, no biggy } return getResource(sourceURL, sample.getClass()); } private String formatSourceCode(FXyzSample sample) { String sourceURL = sample.getSampleSourceURL(); String src; if (sourceURL == null) { src = "No sample source available"; } else { src = "Sample Source not found"; try { src = getSourceCode(sample); } catch (Throwable ex) { ex.printStackTrace(); } } // Escape '<' by "<" to ensure correct rendering by SyntaxHighlighter src = src.replace("<", "<"); String template = getResource("/fxsampler/util/SourceCodeTemplate.html", null); return template.replace("<source/>", src); } private String formatCss(FXyzSample sample) { String cssUrl = sample.getControlStylesheetURL(); String src; if (cssUrl == null) { src = "No CSS source available"; } else { src = "Css not found"; try { src = new String( Files.readAllBytes(Paths.get(getClass().getResource(cssUrl).toURI())) ); } catch (URISyntaxException | IOException ex) { ex.printStackTrace(); } } // Escape '<' by "<" to ensure correct rendering by SyntaxHighlighter src = src.replace("<", "<"); String template = getResource("/fxsampler/util/CssTemplate.html", null); return template.replace("<source/>", src); } private Node buildSampleTabContent(FXyzSample sample) { return FXyzSampleBase.buildSample(sample, stage); } }