8205136: Move StylePad demo to the open repository
authorprr
Fri, 22 Jun 2018 12:16:14 -0700
changeset 50830 5500595d8ebf
parent 50829 074148730b4e
child 50831 59c6972e39fa
8205136: Move StylePad demo to the open repository Reviewed-by: serb, erikj
make/CompileDemos.gmk
src/demo/share/jfc/Stylepad/HelloWorld.java
src/demo/share/jfc/Stylepad/README.txt
src/demo/share/jfc/Stylepad/Stylepad.java
src/demo/share/jfc/Stylepad/Wonderland.java
src/demo/share/jfc/Stylepad/resources/Stylepad.properties
src/demo/share/jfc/Stylepad/resources/StylepadSystem.properties
src/demo/share/jfc/Stylepad/resources/Stylepad_ja.properties
src/demo/share/jfc/Stylepad/resources/Stylepad_zh_CN.properties
src/demo/share/jfc/Stylepad/resources/alice.gif
src/demo/share/jfc/Stylepad/resources/bold.gif
src/demo/share/jfc/Stylepad/resources/bullets.gif
src/demo/share/jfc/Stylepad/resources/caterpillar.gif
src/demo/share/jfc/Stylepad/resources/center.gif
src/demo/share/jfc/Stylepad/resources/fg.gif
src/demo/share/jfc/Stylepad/resources/hatter.gif
src/demo/share/jfc/Stylepad/resources/italic.gif
src/demo/share/jfc/Stylepad/resources/left.gif
src/demo/share/jfc/Stylepad/resources/rabbit.gif
src/demo/share/jfc/Stylepad/resources/rabbit2.gif
src/demo/share/jfc/Stylepad/resources/right.gif
src/demo/share/jfc/Stylepad/resources/underline.gif
--- a/make/CompileDemos.gmk	Fri Jun 22 10:29:14 2018 +0530
+++ b/make/CompileDemos.gmk	Fri Jun 22 12:16:14 2018 -0700
@@ -264,6 +264,12 @@
     DEMO_SUBDIR := jfc, \
 ))
 
+$(eval $(call SetupBuildDemo, Stylepad, \
+    DEMO_SUBDIR := jfc, \
+    EXTRA_SRC_DIR := $(DEMO_SHARE_SRC)/jfc/Notepad, \
+    EXCLUDE_FILES := $(DEMO_SHARE_SRC)/jfc/Notepad/README.txt, \
+))
+
 $(eval $(call SetupBuildDemo, SampleTree, \
     DEMO_SUBDIR := jfc, \
 ))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/demo/share/jfc/Stylepad/HelloWorld.java	Fri Jun 22 12:16:14 2018 -0700
@@ -0,0 +1,208 @@
+/*
+ *
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. 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 Oracle 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.
+ */
+
+
+import java.awt.Color;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.DefaultStyledDocument;
+import javax.swing.text.Style;
+import javax.swing.text.StyleConstants;
+import javax.swing.text.StyleContext;
+
+
+/**
+ * hack to load attributed content.
+ */
+public class HelloWorld {
+
+    HelloWorld(DefaultStyledDocument doc, StyleContext styles) {
+        this.doc = doc;
+        this.styles = styles;
+        runAttr = new HashMap<String, Style>();
+    }
+
+    void loadDocument() {
+        createStyles();
+        for (int i = 0; i < data.length; i++) {
+            Paragraph p = data[i];
+            addParagraph(p);
+        }
+    }
+
+    void addParagraph(Paragraph p) {
+        try {
+            Style s = null;
+            for (int i = 0; i < p.data.length; i++) {
+                Run run = p.data[i];
+                s = runAttr.get(run.attr);
+                doc.insertString(doc.getLength(), run.content, s);
+            }
+
+            // set logical style
+            Style ls = styles.getStyle(p.logical);
+            doc.setLogicalStyle(doc.getLength() - 1, ls);
+            doc.insertString(doc.getLength(), "\n", null);
+        } catch (BadLocationException e) {
+            System.err.println("Internal error: " + e);
+        }
+    }
+
+    void createStyles() {
+        // no attributes defined
+        Style s = styles.addStyle(null, null);
+        runAttr.put("none", s);
+        s = styles.addStyle(null, null);
+        StyleConstants.setItalic(s, true);
+        StyleConstants.setForeground(s, new Color(153, 153, 102));
+        runAttr.put("cquote", s); // catepillar quote
+
+        s = styles.addStyle(null, null);
+        StyleConstants.setItalic(s, true);
+        StyleConstants.setForeground(s, new Color(51, 102, 153));
+        runAttr.put("aquote", s); // alice quote
+
+        try {
+            ResourceBundle resources = ResourceBundle.getBundle(
+                    "resources.Stylepad",
+                    Locale.getDefault());
+            s = styles.addStyle(null, null);
+            Icon alice = new ImageIcon(resources.getString("aliceGif"));
+            StyleConstants.setIcon(s, alice);
+            runAttr.put("alice", s); // alice
+
+            s = styles.addStyle(null, null);
+            Icon caterpillar = new ImageIcon(resources.getString(
+                    "caterpillarGif"));
+            StyleConstants.setIcon(s, caterpillar);
+            runAttr.put("caterpillar", s); // caterpillar
+
+            s = styles.addStyle(null, null);
+            Icon hatter = new ImageIcon(resources.getString("hatterGif"));
+            StyleConstants.setIcon(s, hatter);
+            runAttr.put("hatter", s); // hatter
+
+
+        } catch (MissingResourceException mre) {
+            // can't display image
+        }
+
+        Style def = styles.getStyle(StyleContext.DEFAULT_STYLE);
+
+        Style heading = styles.addStyle("heading", def);
+        //StyleConstants.setFontFamily(heading, "SansSerif");
+        StyleConstants.setBold(heading, true);
+        StyleConstants.setAlignment(heading, StyleConstants.ALIGN_CENTER);
+        StyleConstants.setSpaceAbove(heading, 10);
+        StyleConstants.setSpaceBelow(heading, 10);
+        StyleConstants.setFontSize(heading, 18);
+
+        // Title
+        Style sty = styles.addStyle("title", heading);
+        StyleConstants.setFontSize(sty, 32);
+
+        // edition
+        sty = styles.addStyle("edition", heading);
+        StyleConstants.setFontSize(sty, 16);
+
+        // author
+        sty = styles.addStyle("author", heading);
+        StyleConstants.setItalic(sty, true);
+        StyleConstants.setSpaceBelow(sty, 25);
+
+        // subtitle
+        sty = styles.addStyle("subtitle", heading);
+        StyleConstants.setSpaceBelow(sty, 35);
+
+        // normal
+        sty = styles.addStyle("normal", def);
+        StyleConstants.setLeftIndent(sty, 10);
+        StyleConstants.setRightIndent(sty, 10);
+        //StyleConstants.setFontFamily(sty, "SansSerif");
+        StyleConstants.setFontSize(sty, 14);
+        StyleConstants.setSpaceAbove(sty, 4);
+        StyleConstants.setSpaceBelow(sty, 4);
+    }
+    DefaultStyledDocument doc;
+    StyleContext styles;
+    HashMap<String, Style> runAttr;
+
+
+    static class Paragraph {
+
+        Paragraph(String logical, Run[] data) {
+            this.logical = logical;
+            this.data = data;
+        }
+        String logical;
+        Run[] data;
+    }
+
+
+    static class Run {
+
+        Run(String attr, String content) {
+            this.attr = attr;
+            this.content = content;
+        }
+        String attr;
+        String content;
+    }
+    Paragraph[] data = new Paragraph[] {
+        new Paragraph("title", new Run[] {
+            new Run("none", "Hello from Cupertino")
+        }),
+        new Paragraph("title", new Run[] {
+            new Run("none", "\u53F0\u5317\u554F\u5019\u60A8\u0021")
+        }),
+        new Paragraph("title", new Run[] {
+            new Run("none", "\u0391\u03B8\u03B7\u03BD\u03B1\u03B9\u0020" // Greek
+            + "\u03B1\u03C3\u03C0\u03B1\u03B6\u03BF\u03BD"
+            + "\u03C4\u03B1\u03B9\u0020\u03C5\u03BC\u03B1"
+            + "\u03C2\u0021")
+        }),
+        new Paragraph("title", new Run[] {
+            new Run("none", "\u6771\u4eac\u304b\u3089\u4eca\u65e5\u306f")
+        }),
+        new Paragraph("title", new Run[] {
+            new Run("none", "\u05e9\u05dc\u05d5\u05dd \u05de\u05d9\u05e8\u05d5"
+            + "\u05e9\u05dc\u05d9\u05dd")
+        }),
+        new Paragraph("title", new Run[] {
+            new Run("none", "\u0633\u0644\u0627\u0645")
+        }), };
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/demo/share/jfc/Stylepad/README.txt	Fri Jun 22 12:16:14 2018 -0700
@@ -0,0 +1,11 @@
+
+To run the Stylepad demo:
+
+  java -jar Stylepad.jar
+
+These instructions assume that this installation's version of the java
+command is in your path.  If it isn't, then you should either
+specify the complete path to the java command or update your
+PATH environment variable as described in the installation
+instructions for the Java(TM) SE Development Kit.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/demo/share/jfc/Stylepad/Stylepad.java	Fri Jun 22 12:16:14 2018 -0700
@@ -0,0 +1,409 @@
+/*
+ *
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. 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 Oracle 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.
+ */
+
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.FileDialog;
+import java.awt.Frame;
+import java.awt.Graphics;
+import java.awt.GraphicsEnvironment;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutput;
+import java.io.ObjectOutputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.Icon;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JFrame;
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import javax.swing.JTextPane;
+import javax.swing.SwingUtilities;
+import javax.swing.text.DefaultStyledDocument;
+import javax.swing.text.Document;
+import javax.swing.text.JTextComponent;
+import javax.swing.text.StyleContext;
+import javax.swing.text.StyledEditorKit;
+import javax.swing.text.TextAction;
+
+
+/**
+ * Sample application using JTextPane.
+ *
+ * @author Timothy Prinzing
+ */
+@SuppressWarnings("serial")
+public class Stylepad extends Notepad {
+
+    private static ResourceBundle resources;
+    private FileDialog fileDialog;
+
+    private static final String[] MENUBAR_KEYS = {"file", "edit", "color",
+        "font", "debug"};
+    private static final String[] FONT_KEYS = {"family1", "family2", "family3",
+        "family4", "-", "size1", "size2", "size3", "size4", "size5", "-",
+        "bold", "italic", "underline"};
+    private static final String[] TOOLBAR_KEYS = {"new", "open", "save", "-",
+        "cut", "copy", "paste", "-", "bold", "italic", "underline", "-",
+        "left", "center", "right"};
+
+
+    static {
+        try {
+            properties.load(Stylepad.class.getResourceAsStream(
+                    "resources/StylepadSystem.properties"));
+            resources = ResourceBundle.getBundle("resources.Stylepad");
+        } catch (MissingResourceException | IOException  mre) {
+            System.err.println("Stylepad.properties or StylepadSystem.properties not found");
+            System.exit(0);
+        }
+    }
+
+    public Stylepad() {
+        super();
+    }
+
+    public static void main(String[] args) {
+        try {
+            SwingUtilities.invokeAndWait(new Runnable() {
+
+                public void run() {
+                    JFrame frame = new JFrame();
+                    frame.setTitle(resources.getString("Title"));
+                    frame.setBackground(Color.lightGray);
+                    frame.getContentPane().
+                            setLayout(new BorderLayout());
+                    Stylepad stylepad = new Stylepad();
+                    frame.getContentPane().add("Center", stylepad);
+                    frame.setJMenuBar(stylepad.createMenubar());
+                    frame.addWindowListener(new AppCloser());
+                    frame.pack();
+                    frame.setSize(600, 480);
+                    frame.setVisible(true);
+                }
+            });
+        } catch (InterruptedException ex) {
+            Logger.getLogger(Stylepad.class.getName()).log(Level.SEVERE, null,
+                    ex);
+        } catch (InvocationTargetException ex) {
+            Logger.getLogger(Stylepad.class.getName()).log(Level.SEVERE, null,
+                    ex);
+        }
+    }
+
+    /**
+     * Fetch the list of actions supported by this
+     * editor.  It is implemented to return the list
+     * of actions supported by the superclass
+     * augmented with the actions defined locally.
+     */
+    @Override
+    public Action[] getActions() {
+        Action[] defaultActions = {
+            new NewAction(),
+            new OpenAction(),
+            new SaveAction(),
+            new StyledEditorKit.FontFamilyAction("font-family-SansSerif",
+            "SansSerif"), };
+        Action[] a = TextAction.augmentList(super.getActions(), defaultActions);
+        return a;
+    }
+
+    /**
+     * Try and resolve the resource name in the local
+     * resource file, and if not found fall back to
+     * the superclass resource file.
+     */
+    @Override
+    protected String getResourceString(String nm) {
+        String str;
+        try {
+            str = Stylepad.resources.getString(nm);
+        } catch (MissingResourceException mre) {
+            str = super.getResourceString(nm);
+        }
+        return str;
+    }
+
+    /**
+     * Create an editor to represent the given document.
+     */
+    @Override
+    protected JTextComponent createEditor() {
+        StyleContext sc = new StyleContext();
+        DefaultStyledDocument doc = new DefaultStyledDocument(sc);
+        initDocument(doc, sc);
+        JTextPane p = new JTextPane(doc);
+        p.setDragEnabled(true);
+
+        //p.getCaret().setBlinkRate(0);
+
+        return p;
+    }
+
+    /**
+     * Create a menu for the app.  This is redefined to trap
+     * a couple of special entries for now.
+     */
+    @Override
+    protected JMenu createMenu(String key) {
+        if (key.equals("color")) {
+            return createColorMenu();
+        }
+        return super.createMenu(key);
+    }
+
+    @Override
+    protected String[] getItemKeys(String key) {
+        switch (key) {
+            case "font":
+                return FONT_KEYS;
+            default:
+                return super.getItemKeys(key);
+        }
+    }
+
+    @Override
+    protected String[] getMenuBarKeys() {
+        return MENUBAR_KEYS;
+    }
+
+    @Override
+    protected String[] getToolBarKeys() {
+        return TOOLBAR_KEYS;
+    }
+
+    // this will soon be replaced
+    JMenu createColorMenu() {
+        ActionListener a;
+        JMenuItem mi;
+        JMenu menu = new JMenu(getResourceString("color" + labelSuffix));
+        mi = new JMenuItem(resources.getString("Red"));
+        mi.setHorizontalTextPosition(JButton.RIGHT);
+        mi.setIcon(new ColoredSquare(Color.red));
+        a =
+                new StyledEditorKit.ForegroundAction("set-foreground-red",
+                Color.red);
+        //a = new ColorAction(se, Color.red);
+        mi.addActionListener(a);
+        menu.add(mi);
+        mi = new JMenuItem(resources.getString("Green"));
+        mi.setHorizontalTextPosition(JButton.RIGHT);
+        mi.setIcon(new ColoredSquare(Color.green));
+        a = new StyledEditorKit.ForegroundAction("set-foreground-green",
+                Color.green);
+        //a = new ColorAction(se, Color.green);
+        mi.addActionListener(a);
+        menu.add(mi);
+        mi = new JMenuItem(resources.getString("Blue"));
+        mi.setHorizontalTextPosition(JButton.RIGHT);
+        mi.setIcon(new ColoredSquare(Color.blue));
+        a = new StyledEditorKit.ForegroundAction("set-foreground-blue",
+                Color.blue);
+        //a = new ColorAction(se, Color.blue);
+        mi.addActionListener(a);
+        menu.add(mi);
+
+        return menu;
+    }
+
+    void initDocument(DefaultStyledDocument doc, StyleContext sc) {
+        Wonderland w = new Wonderland(doc, sc);
+        w.loadDocument();
+    }
+
+    JComboBox createFamilyChoices() {
+        JComboBox b = new JComboBox();
+        String[] fontNames = GraphicsEnvironment.getLocalGraphicsEnvironment().
+                getAvailableFontFamilyNames();
+        for (String fontName : fontNames) {
+            b.addItem(fontName);
+        }
+        return b;
+    }
+
+
+    /**
+     * Trys to read a file which is assumed to be a
+     * serialization of a document.
+     */
+    class OpenAction extends AbstractAction {
+
+        OpenAction() {
+            super(openAction);
+        }
+
+        @Override
+        public void actionPerformed(ActionEvent e) {
+            Frame frame = getFrame();
+            if (fileDialog == null) {
+                fileDialog = new FileDialog(frame);
+            }
+            fileDialog.setMode(FileDialog.LOAD);
+            fileDialog.setVisible(true);
+
+            String file = fileDialog.getFile();
+            if (file == null) {
+                return;
+            }
+            String directory = fileDialog.getDirectory();
+            File f = new File(directory, file);
+            if (f.exists()) {
+                try {
+                    FileInputStream fin = new FileInputStream(f);
+                    ObjectInputStream istrm = new ObjectInputStream(fin);
+                    Document doc = (Document) istrm.readObject();
+                    if (getEditor().getDocument() != null) {
+                        getEditor().getDocument().removeUndoableEditListener(
+                                undoHandler);
+                    }
+                    getEditor().setDocument(doc);
+                    doc.addUndoableEditListener(undoHandler);
+                    resetUndoManager();
+                    frame.setTitle(file);
+                    validate();
+                } catch (IOException io) {
+                    // should put in status panel
+                    System.err.println("IOException: " + io.getMessage());
+                } catch (ClassNotFoundException cnf) {
+                    // should put in status panel
+                    System.err.println("Class not found: " + cnf.getMessage());
+                }
+            } else {
+                // should put in status panel
+                System.err.println("No such file: " + f);
+            }
+        }
+    }
+
+
+    /**
+     * Trys to write the document as a serialization.
+     */
+    class SaveAction extends AbstractAction {
+
+        SaveAction() {
+            super(saveAction);
+        }
+
+        @Override
+        public void actionPerformed(ActionEvent e) {
+            Frame frame = getFrame();
+            if (fileDialog == null) {
+                fileDialog = new FileDialog(frame);
+            }
+            fileDialog.setMode(FileDialog.SAVE);
+            fileDialog.setVisible(true);
+            String file = fileDialog.getFile();
+            if (file == null) {
+                return;
+            }
+            String directory = fileDialog.getDirectory();
+            File f = new File(directory, file);
+            try {
+                FileOutputStream fstrm = new FileOutputStream(f);
+                ObjectOutput ostrm = new ObjectOutputStream(fstrm);
+                ostrm.writeObject(getEditor().getDocument());
+                ostrm.flush();
+                frame.setTitle(f.getName());
+            } catch (IOException io) {
+                // should put in status panel
+                System.err.println("IOException: " + io.getMessage());
+            }
+        }
+    }
+
+
+    /**
+     * Creates an empty document.
+     */
+    class NewAction extends AbstractAction {
+
+        NewAction() {
+            super(newAction);
+        }
+
+        @Override
+        public void actionPerformed(ActionEvent e) {
+            if (getEditor().getDocument() != null) {
+                getEditor().getDocument().removeUndoableEditListener(undoHandler);
+            }
+            getEditor().setDocument(new DefaultStyledDocument());
+            getEditor().getDocument().addUndoableEditListener(undoHandler);
+            resetUndoManager();
+            getFrame().setTitle(resources.getString("Title"));
+            validate();
+        }
+    }
+
+
+    class ColoredSquare implements Icon {
+
+        Color color;
+
+        public ColoredSquare(Color c) {
+            this.color = c;
+        }
+
+        @Override
+        public void paintIcon(Component c, Graphics g, int x, int y) {
+            Color oldColor = g.getColor();
+            g.setColor(color);
+            g.fill3DRect(x, y, getIconWidth(), getIconHeight(), true);
+            g.setColor(oldColor);
+        }
+
+        @Override
+        public int getIconWidth() {
+            return 12;
+        }
+
+        @Override
+        public int getIconHeight() {
+            return 12;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/demo/share/jfc/Stylepad/Wonderland.java	Fri Jun 22 12:16:14 2018 -0700
@@ -0,0 +1,299 @@
+/*
+ *
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. 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 Oracle 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.
+ */
+
+
+import java.awt.Color;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.DefaultStyledDocument;
+import javax.swing.text.Style;
+import javax.swing.text.StyleConstants;
+import javax.swing.text.StyleContext;
+
+
+/**
+ * hack to load attributed content
+ */
+public class Wonderland {
+
+    Wonderland(DefaultStyledDocument doc, StyleContext styles) {
+        this.doc = doc;
+        this.styles = styles;
+        runAttr = new HashMap<String, Style>();
+    }
+
+    void loadDocument() {
+        createStyles();
+        for (int i = 0; i < data.length; i++) {
+            Paragraph p = data[i];
+            addParagraph(p);
+        }
+    }
+
+    void addParagraph(Paragraph p) {
+        try {
+            Style s = null;
+            for (int i = 0; i < p.data.length; i++) {
+                Run run = p.data[i];
+                s = runAttr.get(run.attr);
+                doc.insertString(doc.getLength(), run.content, s);
+            }
+
+            // set logical style
+            Style ls = styles.getStyle(p.logical);
+            doc.setLogicalStyle(doc.getLength() - 1, ls);
+            doc.insertString(doc.getLength(), "\n", null);
+        } catch (BadLocationException e) {
+            System.err.println("Internal error: " + e);
+        }
+    }
+
+    void createStyles() {
+        // no attributes defined
+        Style s = styles.addStyle(null, null);
+        runAttr.put("none", s);
+        s = styles.addStyle(null, null);
+        StyleConstants.setItalic(s, true);
+        StyleConstants.setForeground(s, new Color(153, 153, 102));
+        runAttr.put("cquote", s); // catepillar quote
+
+        s = styles.addStyle(null, null);
+        StyleConstants.setItalic(s, true);
+        StyleConstants.setForeground(s, new Color(51, 102, 153));
+        runAttr.put("aquote", s); // alice quote
+
+        try {
+            ResourceBundle resources = ResourceBundle.getBundle(
+                    "resources.Stylepad",
+                    Locale.getDefault());
+            s = styles.addStyle(null, null);
+            Icon alice =
+                    new ImageIcon(getClass().
+                    getResource(resources.getString("aliceGif")));
+            StyleConstants.setIcon(s, alice);
+            runAttr.put("alice", s); // alice
+
+            s = styles.addStyle(null, null);
+            Icon caterpillar =
+                    new ImageIcon(getClass().
+                    getResource(resources.getString("caterpillarGif")));
+            StyleConstants.setIcon(s, caterpillar);
+            runAttr.put("caterpillar", s); // caterpillar
+
+            s = styles.addStyle(null, null);
+            Icon hatter =
+                    new ImageIcon(getClass().
+                    getResource(resources.getString("hatterGif")));
+            StyleConstants.setIcon(s, hatter);
+            runAttr.put("hatter", s); // hatter
+
+
+        } catch (MissingResourceException mre) {
+            // can't display image
+        }
+
+        Style def = styles.getStyle(StyleContext.DEFAULT_STYLE);
+
+        Style heading = styles.addStyle("heading", def);
+        StyleConstants.setFontFamily(heading, "SansSerif");
+        StyleConstants.setBold(heading, true);
+        StyleConstants.setAlignment(heading, StyleConstants.ALIGN_CENTER);
+        StyleConstants.setSpaceAbove(heading, 10);
+        StyleConstants.setSpaceBelow(heading, 10);
+        StyleConstants.setFontSize(heading, 18);
+
+        // Title
+        Style sty = styles.addStyle("title", heading);
+        StyleConstants.setFontSize(sty, 32);
+
+        // edition
+        sty = styles.addStyle("edition", heading);
+        StyleConstants.setFontSize(sty, 16);
+
+        // author
+        sty = styles.addStyle("author", heading);
+        StyleConstants.setItalic(sty, true);
+        StyleConstants.setSpaceBelow(sty, 25);
+
+        // subtitle
+        sty = styles.addStyle("subtitle", heading);
+        StyleConstants.setSpaceBelow(sty, 35);
+
+        // normal
+        sty = styles.addStyle("normal", def);
+        StyleConstants.setLeftIndent(sty, 10);
+        StyleConstants.setRightIndent(sty, 10);
+        StyleConstants.setFontFamily(sty, "SansSerif");
+        StyleConstants.setFontSize(sty, 14);
+        StyleConstants.setSpaceAbove(sty, 4);
+        StyleConstants.setSpaceBelow(sty, 4);
+    }
+    DefaultStyledDocument doc;
+    StyleContext styles;
+    HashMap<String, Style> runAttr;
+
+
+    static class Paragraph {
+
+        Paragraph(String logical, Run[] data) {
+            this.logical = logical;
+            this.data = data;
+        }
+        String logical;
+        Run[] data;
+    }
+
+
+    static class Run {
+
+        Run(String attr, String content) {
+            this.attr = attr;
+            this.content = content;
+        }
+        String attr;
+        String content;
+    }
+    Paragraph[] data = new Paragraph[] {
+        new Paragraph("title", new Run[] {
+            new Run("none", "ALICE'S ADVENTURES IN WONDERLAND")
+        }),
+        new Paragraph("author", new Run[] {
+            new Run("none", "Lewis Carroll")
+        }),
+        new Paragraph("heading", new Run[] {
+            new Run("alice", " ")
+        }),
+        new Paragraph("edition", new Run[] {
+            new Run("none", "THE MILLENNIUM FULCRUM EDITION 3.0")
+        }),
+        new Paragraph("heading", new Run[] {
+            new Run("none", "CHAPTER V")
+        }),
+        new Paragraph("subtitle", new Run[] {
+            new Run("none", "Advice from a Caterpillar")
+        }),
+        new Paragraph("normal", new Run[] {
+            new Run("none", " "), }),
+        new Paragraph("normal", new Run[] {
+            new Run("none",
+            "The Caterpillar and Alice looked at each other for some time in "
+                    + "silence:  at last the Caterpillar took the hookah out "
+                    + "of its mouth, and addressed her in a languid, sleepy "
+                    + "voice.")
+        }),
+        new Paragraph("normal", new Run[] {
+            new Run("cquote", "Who are YOU?  "),
+            new Run("none", "said the Caterpillar.")
+        }),
+        new Paragraph("normal",
+        new Run[] {
+            new Run("none",
+            "This was not an encouraging opening for a conversation.  Alice "
+                    + "replied, rather shyly, "),
+            new Run("aquote",
+            "I--I hardly know, sir, just at present--at least I know who I WAS "
+                    + "when I got up this morning, but I think I must have "
+                    + "been changed several times since then. "), }),
+        new Paragraph("heading", new Run[] {
+            new Run("caterpillar", " ")
+        }),
+        new Paragraph("normal", new Run[] {
+            new Run("cquote", "What do you mean by that? "),
+            new Run("none", " said the Caterpillar sternly.  "),
+            new Run("cquote", "Explain yourself!"), }),
+        new Paragraph("normal", new Run[] {
+            new Run("aquote", "I can't explain MYSELF, I'm afraid, sir"),
+            new Run("none", " said Alice, "),
+            new Run("aquote", "because I'm not myself, you see."), }),
+        new Paragraph("normal", new Run[] {
+            new Run("cquote", "I don't see,"),
+            new Run("none", " said the Caterpillar."), }),
+        new Paragraph("normal",
+        new Run[] {
+            new Run("aquote", "I'm afraid I can't put it more clearly,  "),
+            new Run("none", "Alice replied very politely, "),
+            new Run("aquote",
+            "for I can't understand it myself to begin with; and being so many "
+                    + "different sizes in a day is very confusing."), }),
+        new Paragraph("normal", new Run[] {
+            new Run("cquote", "It isn't,  "),
+            new Run("none", "said the Caterpillar.")
+        }),
+        new Paragraph("normal", new Run[] {
+            new Run("aquote", "Well, perhaps you haven't found it so yet,"),
+            new Run("none", " said Alice; "),
+            new Run("aquote",
+            "but when you have to turn into a chrysalis--you will some day, "
+                    + "you know--and then after that into a butterfly, I "
+                    + "should think you'll feel it a little queer, won't you?")
+        }),
+        new Paragraph("normal", new Run[] {
+            new Run("cquote", "Not a bit, "),
+            new Run("none", "said the Caterpillar.")
+        }),
+        new Paragraph("normal",
+        new Run[] {
+            new Run("aquote", "Well, perhaps your feelings may be different,"),
+            new Run("none", " said Alice; "),
+            new Run("aquote", "all I know is, it would feel very queer to ME."),
+        }),
+        new Paragraph("normal", new Run[] {
+            new Run("cquote", "You!"),
+            new Run("none", " said the Caterpillar contemptuously.  "),
+            new Run("cquote", "Who are YOU?"), }),
+        new Paragraph("normal", new Run[] {
+            new Run("normal",
+            "Which brought them back again to the beginning of the "
+                    + "conversation.  Alice felt a little irritated at the "
+                    + "Caterpillar's making such VERY short remarks, and she "
+                    + "drew herself up and said, very gravely, "),
+            new Run("aquote",
+            "I think, you ought to tell me who YOU are, first."), }),
+        new Paragraph("normal", new Run[] {
+            new Run("cquote", "Why?  "),
+            new Run("none", "said the Caterpillar."), }),
+        new Paragraph("heading", new Run[] {
+            new Run("hatter", " ")
+        }),
+        new Paragraph("normal", new Run[] {
+            new Run("none", " "), }),
+        new Paragraph("normal", new Run[] {
+            new Run("none", " "), }),
+        new Paragraph("normal", new Run[] {
+            new Run("none", " "), })
+    };
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/demo/share/jfc/Stylepad/resources/Stylepad.properties	Fri Jun 22 12:16:14 2018 -0700
@@ -0,0 +1,58 @@
+#
+# Resource strings for Stylepad example
+
+Title=Stylepad
+
+# Menu labels
+colorLabel=Color
+Red=Red
+Green=Green
+Blue=Blue
+
+boldLabel=Bold
+italicLabel=Italic
+
+# font menu
+
+fontLabel=Font
+family1Label=SansSerif
+family2Label=Monospaced
+family3Label=Serif
+family4Label=Lucida Sans
+size1Label=10
+size2Label=12
+size3Label=18
+size4Label=24
+size5Label=48
+boldLabel=Bold
+italicLabel=Italic
+underlineLabel=Underline
+
+#
+# debug Menu definition
+#
+debugLabel=Debug
+dumpLabel=Dump model to System.err
+showElementTreeLabel=Show Elements
+
+
+# toolbar definition
+boldImage=resources/bold.gif
+boldTooltip=Bold
+italicImage=resources/italic.gif
+italicTooltip=Italic
+underlineImage=resources/underline.gif
+underlineTooltip=Underline
+foregroundImage=resources/fg.gif
+leftImage=resources/left.gif
+leftTooltip=Left Justify
+centerImage=resources/center.gif
+centerTooltip=Center Justify
+rightImage=resources/right.gif
+rightTooltip=Right Justify
+bulletsImage=resources/bullets.gif
+
+# wonderland example images
+aliceGif=resources/alice.gif
+caterpillarGif=resources/caterpillar.gif
+hatterGif=resources/hatter.gif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/demo/share/jfc/Stylepad/resources/StylepadSystem.properties	Fri Jun 22 12:16:14 2018 -0700
@@ -0,0 +1,23 @@
+#
+# Non-translatable properties for Stylepad example
+
+ViewportBackingStore=true
+
+family1Action=font-family-SansSerif
+family2Action=font-family-Monospaced
+family3Action=font-family-Serif
+family4Action=font-family-LucidaSans
+size1Action=font-size-10
+size2Action=font-size-12
+size3Action=font-size-18
+size4Action=font-size-24
+size5Action=font-size-48
+boldAction=font-bold
+italicAction=font-italic
+underlineAction=font-underline
+
+dumpAction=dump-model
+
+leftAction=left-justify
+centerAction=center-justify
+rightAction=right-justify
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/demo/share/jfc/Stylepad/resources/Stylepad_ja.properties	Fri Jun 22 12:16:14 2018 -0700
@@ -0,0 +1,58 @@
+#
+# Resource strings for Stylepad example
+
+Title=\u30B9\u30BF\u30A4\u30EB\u30D1\u30C3\u30C9
+
+# Menu labels
+colorLabel=\u30AB\u30E9\u30FC
+Red=\u8D64
+Green=\u7DD1
+Blue=\u9752
+
+boldLabel=\u592A\u5B57
+italicLabel=\u30A4\u30BF\u30EA\u30C3\u30AF
+
+# font menu
+
+fontLabel=\u30D5\u30A9\u30F3\u30C8
+family1Label=SansSerif
+family2Label=\u30E2\u30CE\u30B9\u30DA\u30FC\u30B9
+family3Label=Serif
+family4Label=Lucida Sans
+size1Label=10
+size2Label=12
+size3Label=18
+size4Label=24
+size5Label=48
+boldLabel=\u592A\u5B57
+italicLabel=\u30A4\u30BF\u30EA\u30C3\u30AF
+underlineLabel=\u4E0B\u7DDA
+
+#
+# debug Menu definition
+#
+debugLabel=\u30C7\u30D0\u30C3\u30B0
+dumpLabel=\u30E2\u30C7\u30EB\u3092System.err\u306B\u30C0\u30F3\u30D7
+showElementTreeLabel=\u8981\u7D20\u306E\u8868\u793A
+
+
+# toolbar definition
+boldImage=resources/bold.gif
+boldTooltip=\u592A\u5B57
+italicImage=resources/italic.gif
+italicTooltip=\u30A4\u30BF\u30EA\u30C3\u30AF
+underlineImage=resources/underline.gif
+underlineTooltip=\u4E0B\u7DDA
+foregroundImage=resources/fg.gif
+leftImage=resources/left.gif
+leftTooltip=\u5DE6\u63C3\u3048
+centerImage=resources/center.gif
+centerTooltip=\u4E2D\u592E\u63C3\u3048
+rightImage=resources/right.gif
+rightTooltip=\u53F3\u63C3\u3048
+bulletsImage=resources/bullets.gif
+
+# wonderland example images
+aliceGif=resources/alice.gif
+caterpillarGif=resources/caterpillar.gif
+hatterGif=resources/hatter.gif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/demo/share/jfc/Stylepad/resources/Stylepad_zh_CN.properties	Fri Jun 22 12:16:14 2018 -0700
@@ -0,0 +1,58 @@
+#
+# Resource strings for Stylepad example
+
+Title=StylePad
+
+# Menu labels
+colorLabel=\u989C\u8272
+Red=\u7EA2\u8272
+Green=\u7EFF\u8272
+Blue=\u84DD\u8272
+
+boldLabel=\u7C97\u4F53
+italicLabel=\u659C\u4F53
+
+# font menu
+
+fontLabel=\u5B57\u4F53
+family1Label=SansSerif
+family2Label=Monospaced
+family3Label=Serif
+family4Label=Lucida Sans
+size1Label=10
+size2Label=12
+size3Label=18
+size4Label=24
+size5Label=48
+boldLabel=\u7C97\u4F53
+italicLabel=\u659C\u4F53
+underlineLabel=\u4E0B\u5212\u7EBF
+
+#
+# debug Menu definition
+#
+debugLabel=\u8C03\u8BD5
+dumpLabel=\u5C06\u6A21\u578B\u8F6C\u50A8\u5230 System.err
+showElementTreeLabel=\u663E\u793A\u5143\u7D20
+
+
+# toolbar definition
+boldImage=resources/bold.gif
+boldTooltip=\u7C97\u4F53
+italicImage=resources/italic.gif
+italicTooltip=\u659C\u4F53
+underlineImage=resources/underline.gif
+underlineTooltip=\u4E0B\u5212\u7EBF
+foregroundImage=resources/fg.gif
+leftImage=resources/left.gif
+leftTooltip=\u5DE6\u5BF9\u9F50
+centerImage=resources/center.gif
+centerTooltip=\u4E2D\u95F4\u5BF9\u9F50
+rightImage=resources/right.gif
+rightTooltip=\u53F3\u5BF9\u9F50
+bulletsImage=resources/bullets.gif
+
+# wonderland example images
+aliceGif=resources/alice.gif
+caterpillarGif=resources/caterpillar.gif
+hatterGif=resources/hatter.gif
Binary file src/demo/share/jfc/Stylepad/resources/alice.gif has changed
Binary file src/demo/share/jfc/Stylepad/resources/bold.gif has changed
Binary file src/demo/share/jfc/Stylepad/resources/bullets.gif has changed
Binary file src/demo/share/jfc/Stylepad/resources/caterpillar.gif has changed
Binary file src/demo/share/jfc/Stylepad/resources/center.gif has changed
Binary file src/demo/share/jfc/Stylepad/resources/fg.gif has changed
Binary file src/demo/share/jfc/Stylepad/resources/hatter.gif has changed
Binary file src/demo/share/jfc/Stylepad/resources/italic.gif has changed
Binary file src/demo/share/jfc/Stylepad/resources/left.gif has changed
Binary file src/demo/share/jfc/Stylepad/resources/rabbit.gif has changed
Binary file src/demo/share/jfc/Stylepad/resources/rabbit2.gif has changed
Binary file src/demo/share/jfc/Stylepad/resources/right.gif has changed
Binary file src/demo/share/jfc/Stylepad/resources/underline.gif has changed