All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ensemble.pages.SamplePage Maven / Gradle / Ivy

The newest version!

/*
 * Copyright (c) 2008, 2012 Oracle and/or its affiliates.
 * All rights reserved. Use is subject to license terms.
 *
 * This file is available and licensed under the following license:
 *
 * 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 Oracle Corporation 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 THE COPYRIGHT
 * OWNER OR CONTRIBUTORS 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 ensemble.pages;

import ensemble.*;
import ensemble.model.SampleInfo;
import ensemble.sampleproject.SampleProjectBuilder;
import ensemble.util.Utils;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.effect.BlendMode;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.Clipboard;
import javafx.scene.input.DataFormat;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.paint.CycleMethod;
import javafx.scene.paint.LinearGradient;
import javafx.scene.paint.Stop;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Text;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.FileChooser;

import javax.swing.filechooser.FileSystemView;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import javafx.application.ConditionalFeature;
import javafx.application.Platform;
import javafx.geometry.Pos;
import javafx.scene.text.TextAlignment;

/**
 * SamplePage
 */
public class SamplePage extends Page {
    private static WebEngine engine = null;
    private static WebView webView = null;
    private SampleInfo sampleInfo;
    private Class sampleClass;
    private String rawCode;
    private String htmlCode;

    public SamplePage(String name, String sourceFileUrl) throws IllegalArgumentException {
        super(name);
        String unqualifiedClassName = sourceFileUrl.substring(sourceFileUrl.lastIndexOf('/')+1,
                sourceFileUrl.length()-5);
        try {
            // load src into String
            StringBuilder builder = new StringBuilder();
            URI uri = new URI(sourceFileUrl);
            InputStream in = uri.toURL().openStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            String line;
            while((line = reader.readLine()) != null) {
                builder.append(line);
                builder.append('\n');
            }
            reader.close();
            // parse sample info
            sampleInfo = new SampleInfo(sourceFileUrl, unqualifiedClassName, builder.toString());
            // load class
            sampleClass = getClass().getClassLoader().loadClass(sampleInfo.getClassName());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (URISyntaxException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // Add API back references
        Ensemble2 ensemble2 = Ensemble2.getEnsemble2();
        for (String apiClassPath : sampleInfo.getApiClasspaths()) {
            String path = Pages.API_DOCS+'/'+apiClassPath.replace('.','/');
            DocPage docPage = (DocPage) ensemble2.getPages().getPage(path);
            if (docPage != null) {
                docPage.getRelatedSamples().add(this);
//            } else {
//                System.err.println("Failed to find documentation page for classpath ["+apiClassPath+"] from @see in sample ["+sourceFileUrl+"]");
            }
        }
    }

    public SamplePage(SamplePage pageToClone) {
        super(pageToClone.getName());
        this.sampleInfo = pageToClone.sampleInfo;
        this.sampleClass = pageToClone.sampleClass;
    }

    public SampleInfo getSampleInfo() {
        return sampleInfo;
    }

    @Override public Node createView() {
        // check if 3d sample and on supported platform
        //System.out.println("sampleClass.getSuperclass() == Sample3D.class = " + (sampleClass.getSuperclass() == Sample3D.class));
        //System.out.println("Platform.isSupported(ConditionalFeature.SCENE3D) = " + Platform.isSupported(ConditionalFeature.SCENE3D));
        if (sampleClass.getSuperclass() == Sample3D.class && !Platform.isSupported(ConditionalFeature.SCENE3D)) {
            Label error =  new Label("JavaFX 3D is currently not supported on your configuration.");
            error.setStyle("-fx-text-fill: orangered; -fx-font-size: 1.4em;");
            error.setWrapText(true);
            error.setAlignment(Pos.CENTER);
            error.setTextAlignment(TextAlignment.CENTER);
            return error;
        }
        //  load the code
        loadCode();
        try {
            // create main grid
            //final FlowSafeVBox main = new FlowSafeVBox();
            final VBox main = new VBox(8);
            main.getStyleClass().add("sample-page");
            // create header
            Label header = new Label(getName());
            header.getStyleClass().add("page-header");
            main.getChildren().add(header);
            // create sample area
            final StackPane sampleArea = new StackPane();
            VBox.setVgrow(sampleArea, Priority.SOMETIMES);
            main.getChildren().add(sampleArea);
            // create sample
            final Sample sample = (Sample)sampleClass.newInstance();
            sampleArea.getChildren().add(sample);
            // create sample controls
            Node sampleControls = sample.getControls();
            if(sampleControls != null) {
                Label subHeader = new Label("Play with these:");
                subHeader.getStyleClass().add("page-subheader");
                main.getChildren().add(subHeader);
                main.getChildren().add(sampleControls);
            }
            // create code view
            WebView webView = getWebView();
            webView.setPrefWidth(300);
            engine.loadContent(htmlCode);
            ToolBar codeToolBar = new ToolBar();
            codeToolBar.setId("code-tool-bar");
            final Button saveProjectButton = new Button("Save Netbeans Project...");
            saveProjectButton.setOnAction(new EventHandler() {
                @Override public void handle(ActionEvent actionEvent) {
                    File initialDir = FileSystemView.getFileSystemView().getDefaultDirectory();
                    ///System.out.println("initialDir = " + initialDir);
                    FileChooser fileChooser = new FileChooser();
                    fileChooser.setTitle("Save Netbeans Project As:");
                    fileChooser.setInitialDirectory(initialDir);
                    File result = fileChooser.showSaveDialog(saveProjectButton.getScene().getWindow());
                    if (result != null) SampleProjectBuilder.createSampleProject(result, sampleInfo.getSourceFileUrl(), sampleInfo.getResourceUrls());
                }
            });
            Button copyCodeButton = new Button("Copy Source");
            copyCodeButton.setOnAction(new EventHandler() {
                @Override public void handle(ActionEvent actionEvent) {
                    Map clipboardContent = new HashMap();
                    clipboardContent.put(DataFormat.PLAIN_TEXT, rawCode);
                    clipboardContent.put(DataFormat.HTML, htmlCode);
                    Clipboard.getSystemClipboard().setContent(clipboardContent);
                }
            });
            codeToolBar.getItems().addAll(saveProjectButton,copyCodeButton);
            BorderPane codeTabPane = new BorderPane();
            codeTabPane.setTop(codeToolBar);
            codeTabPane.setCenter(webView);

            // create border pane for main content and sidebar
            BorderPane borderPane = new BorderPane();
            borderPane.setCenter(main);
            borderPane.setRight(createSideBar(sample));
            ScrollPane scrollPane = new ScrollPane();
            scrollPane.getStyleClass().add("noborder-scroll-pane");
            scrollPane.setContent(borderPane);
            scrollPane.setFitToWidth(true);
            scrollPane.setFitToHeight(true);
            scrollPane.setMinWidth(725);
            // create tab pane
            final TabPane tabPane = new SamplePageView(sample);
            tabPane.setId("source-tabs");
            final Tab sampleTab = new Tab();
            sampleTab.setText("Sample");
            sampleTab.setContent(scrollPane);
            sampleTab.setClosable(false);
            final Tab sourceTab = new Tab();
            sourceTab.setText("Source Code");
            sourceTab.setContent(codeTabPane);
            sourceTab.setClosable(false);
            tabPane.getSelectionModel().selectedItemProperty().addListener(new InvalidationListener() {
                @Override public void invalidated(Observable ov) {
                    if (tabPane.getSelectionModel().getSelectedItem() == sampleTab) {
                        sample.play();
                    } else {
                        sample.stop();
                    }
                }
            });
            tabPane.getTabs().addAll(sampleTab,sourceTab);
            return tabPane;
        } catch (Exception e) {
            e.printStackTrace();
            return new Text("Failed to create sample because of ["+e.getMessage()+"]");
        }
    }

    private Node createSideBar(Sample sample) {
        GridPane sidebar = new GridPane();
        sidebar.getStyleClass().add("right-sidebar");
        sidebar.setMaxWidth(Double.MAX_VALUE);
        sidebar.setMaxHeight(Double.MAX_VALUE);
        int sideRow = 0;
        // create side bar content
        // description
        Label discTitle = new Label("Description");
        discTitle.getStyleClass().add("right-sidebar-title");
        GridPane.setConstraints(discTitle, 0, sideRow++);
        sidebar.getChildren().add(discTitle);
        Text disc = new Text(sampleInfo.getDescription());
        disc.setWrappingWidth(200);
        disc.getStyleClass().add("right-sidebar-body");
        GridPane.setConstraints(disc, 0, sideRow++);
        sidebar.getChildren().add(disc);
        // docs
        if (sampleInfo.getApiClasspaths()!=null && sampleInfo.getApiClasspaths().length>0) {
            Separator separator = new Separator();
            GridPane.setConstraints(separator, 0, sideRow++);
            sidebar.getChildren().add(separator);
            Label docsTitle = new Label("API Documentation");
            docsTitle.getStyleClass().add("right-sidebar-title");
            GridPane.setConstraints(docsTitle, 0, sideRow++);
            sidebar.getChildren().add(docsTitle);
            for (String docPath:sampleInfo.getApiClasspaths()) {
                Hyperlink link = new Hyperlink(docPath);
                link.setOnAction(new GoToPageEventHandler(Pages.API_DOCS+'/'+docPath.replace('.','/')));
                GridPane.setConstraints(link, 0, sideRow++);
                sidebar.getChildren().add(link);
            }
        }
        // related
        if (sampleInfo.getRelatesSamplePaths()!=null && sampleInfo.getRelatesSamplePaths().length>0) {
            Separator separator = new Separator();
            GridPane.setConstraints(separator, 0, sideRow++);
            sidebar.getChildren().add(separator);
            Label relatedTitle = new Label("Related");
            relatedTitle.getStyleClass().add("right-sidebar-title");
            GridPane.setConstraints(relatedTitle, 0, sideRow++);
            sidebar.getChildren().add(relatedTitle);
            for (String relatedPath:sampleInfo.getRelatesSamplePaths()) {
                String[] parts = relatedPath.split("/");
                Hyperlink link = new Hyperlink(parts[parts.length-1]);
                //convert path
                String path = "";
                for(String part:parts) {
                    path = path+'/'+ SampleHelper.formatName(part);
                }
                link.setOnAction(new GoToPageEventHandler(Pages.SAMPLES+path));
                ///System.out.println("Pages.SAMPLES+path==>" + Pages.SAMPLES + path);
                GridPane.setConstraints(link, 0, sideRow++);
                sidebar.getChildren().add(link);
            }
        }
        // resources
        // TODO add back in later
//        if (resourceUrls!=null && resourceUrls.length>0) {
//            Separator separator = new Separator();
//            separator.setLayoutInfo(new GridLayoutInfo(sideRow++, 0));
//            sidebar.getChildren().add(separator);
//            Label docsTitle = new Label("Resources");
//            docsTitle.getStyleClass().add("right-sidebar-title");
//            docsTitle.setLayoutInfo(new GridLayoutInfo(sideRow++, 0));
//            sidebar.getChildren().add(docsTitle);
//            for (String resourceUrl:resourceUrls) {
//                String[] parts = resourceUrl.split("/");
//                Hyperlink link = new Hyperlink(parts[parts.length-1]);
//                link.setLayoutInfo(new GridLayoutInfo(sideRow++, 0));
//                sidebar.getChildren().add(link);
//            }
//        }
        // sample extras
        Node sampleExtras = sample.getSideBarExtraContent();
        if (sampleExtras != null) {
            Separator separator = new Separator();
            GridPane.setConstraints(separator, 0, sideRow++);
            sidebar.getChildren().add(separator);
            Label docsTitle = new Label(sample.getSideBarExtraContentTitle());
            docsTitle.getStyleClass().add("right-sidebar-title");
            GridPane.setConstraints(docsTitle, 0, sideRow++);
            sidebar.getChildren().add(docsTitle);
            GridPane.setConstraints(sampleExtras, 0, sideRow++);
            sidebar.getChildren().add(sampleExtras);
        }
        return sidebar;
    }

    private Node getIcon() {
        URL url = sampleClass.getResource(sampleClass.getSimpleName()+".png");
        if (url != null) {
            ImageView imageView = new ImageView(new Image(url.toString()));
            return imageView;
        } else {
            ImageView imageView = new ImageView(new Image(Ensemble2.class.getResource("images/icon-overlay.png").toString()));
            imageView.setMouseTransparent(true);
            Rectangle overlayHighlight = new Rectangle(-8,-8,130,130);
            overlayHighlight.setFill(new LinearGradient(0,0.5,0,1,true, CycleMethod.NO_CYCLE, new Stop[]{ new Stop(0,Color.BLACK), new Stop(1,Color.web("#444444"))}));
            overlayHighlight.setOpacity(0.8);
            overlayHighlight.setMouseTransparent(true);
            overlayHighlight.setBlendMode(BlendMode.ADD);
            Rectangle background = new Rectangle(-8,-8,130,130);
            background.setFill(Color.web("#b9c0c5"));
            Group group = new Group(background);
            Rectangle clipRect = new Rectangle(114,114);
            clipRect.setArcWidth(38);
            clipRect.setArcHeight(38);
            group.setClip(clipRect);
            Node content = createIconContent();
            if (content != null) {
                content.setTranslateX((int)((114-content.getBoundsInParent().getWidth())/2)-(int)content.getBoundsInParent().getMinX());
                content.setTranslateY((int)((114-content.getBoundsInParent().getHeight())/2)-(int)content.getBoundsInParent().getMinY());
                group.getChildren().add(content);
            }
            group.getChildren().addAll(overlayHighlight,imageView);
            // Wrap in extra group as clip dosn't effect layout without it
            return new Group(group);
        }
    }

    public Node createIconContent() {
        try {
            Method createIconContent = sampleClass.getDeclaredMethod("createIconContent");
            return (Node)createIconContent.invoke(sampleClass);
        } catch (NoSuchMethodException e) {
            System.err.println("Sample ["+getName()+"] is missing a icon.");
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return null;
    }

    public Node createTile() {
        Button tile = new Button(getName().trim(),getIcon());
        tile.setMinSize(140,145);
        tile.setPrefSize(140,145);
        tile.setMaxSize(140,145);
        tile.setContentDisplay(ContentDisplay.TOP);
        tile.getStyleClass().clear();
        tile.getStyleClass().add("sample-tile");
        tile.setOnAction(new EventHandler() {
            public void handle(Event event) {
                Ensemble2.getEnsemble2().goToPage(SamplePage.this);
            }
        });
        return tile;
    }

    protected WebView getWebView() {
        if (engine == null) {
            webView = new WebView();
            webView.setContextMenuEnabled(false);
            engine = webView.getEngine();
        }
        return webView;
    }

    private String shCoreJs;
    private String shBrushJScript;
    private String shCoreDefaultCss;


    private void loadCode() {
        // load syntax highlighter
        if (shCoreJs == null) shCoreJs = Utils.loadFile(Ensemble2.class.getResource("syntaxhighlighter/shCore.js")) +";";
        if (shBrushJScript == null) shBrushJScript = Utils.loadFile(Ensemble2.class.getResource("syntaxhighlighter/shBrushJava.js"));
        if (shCoreDefaultCss == null) shCoreDefaultCss =
                Utils.loadFile(Ensemble2.class.getResource("syntaxhighlighter/shCoreDefault.css")).replaceAll("!important","");
        // load and convert source
        String source = SampleProjectBuilder.loadAndConvertSampleCode(sampleInfo.getSourceFileUrl());
        // store raw code
        rawCode = source;
        // escape < & >
        source = source.replaceAll("&","&");
        source = source.replaceAll("<","<");
        source = source.replaceAll(">",">");
        source = source.replaceAll("\"",""");
        source = source.replaceAll("\'","'");
        // create content
        StringBuilder html = new StringBuilder();
        html.append("\n");
        html.append("    \n");
        html.append("    \n");
        html.append("    \n");
        html.append("    \n");
        html.append("\n");
        html.append("    
\n");
        html.append(source);
        html.append('\n');
        html.append(
                "    
\n" + " \n" + "\n" + "\n"); htmlCode = html.toString(); } public static class SamplePageView extends TabPane { private Sample sample; public SamplePageView(Sample sample) { super(); this.sample = sample; } public void stop() { sample.stop(); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy