changeset 50688:6e7126d9e99f

8197948: Create test for SwingSet2 main window Reviewed-by: prr Contributed-by: abdul.kolarkunnu@oracle.com
author psadhukhan
date Wed, 09 May 2018 16:03:49 +0530
parents df06fe86f536
children 1a0960ba9735
files test/jdk/sanity/client/SwingSet/src/SwingSet2DemoTest.java test/jdk/sanity/client/lib/SwingSet2/README test/jdk/sanity/client/lib/SwingSet2/src/AquaTheme.java test/jdk/sanity/client/lib/SwingSet2/src/CharcoalTheme.java test/jdk/sanity/client/lib/SwingSet2/src/ContrastTheme.java test/jdk/sanity/client/lib/SwingSet2/src/DemoModule.java test/jdk/sanity/client/lib/SwingSet2/src/EmeraldTheme.java test/jdk/sanity/client/lib/SwingSet2/src/OptionPaneDemo.java test/jdk/sanity/client/lib/SwingSet2/src/RubyTheme.java test/jdk/sanity/client/lib/SwingSet2/src/SwingSet2.java test/jdk/sanity/client/lib/SwingSet2/src/TextAndMnemonicUtils.java test/jdk/sanity/client/lib/SwingSet2/src/resources/images/toolbar/JOptionPane.gif test/jdk/sanity/client/lib/SwingSet2/src/resources/swingset.properties
diffstat 13 files changed, 2574 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sanity/client/SwingSet/src/SwingSet2DemoTest.java	Wed May 09 16:03:49 2018 +0530
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import static org.jemmy2ext.JemmyExt.EXACT_STRING_COMPARATOR;
+import static org.testng.Assert.assertTrue;
+
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JRadioButtonMenuItem;
+import javax.swing.ToolTipManager;
+import javax.swing.plaf.metal.MetalLookAndFeel;
+
+import org.jtregext.GuiTestListener;
+import org.netbeans.jemmy.ClassReference;
+import org.netbeans.jemmy.ComponentChooser;
+import org.netbeans.jemmy.TimeoutExpiredException;
+import org.netbeans.jemmy.operators.ComponentOperator;
+import org.netbeans.jemmy.operators.JButtonOperator;
+import org.netbeans.jemmy.operators.JCheckBoxMenuItemOperator;
+import org.netbeans.jemmy.operators.JFrameOperator;
+import org.netbeans.jemmy.operators.JMenuOperator;
+import org.netbeans.jemmy.operators.JRadioButtonMenuItemOperator;
+import org.netbeans.jemmy.operators.JToggleButtonOperator;
+import org.netbeans.jemmy.util.NameComponentChooser;
+import org.testng.annotations.Listeners;
+import org.testng.annotations.Test;
+
+/*
+ * @test
+ * @key headful
+ * @summary Verifies check box menu item, radio button menu item, nested menus
+ * and themes using SwingSet2 main window. Testing of other swing components
+ * are covered in SwingSet3 demo tests.
+ *
+ * @library /sanity/client/lib/jemmy/src
+ * @library /sanity/client/lib/Extensions/src
+ * @library /sanity/client/lib/SwingSet2/src
+ * @modules java.desktop
+ *          java.logging
+ * @build org.jemmy2ext.JemmyExt
+ * @build SwingSet2
+ * @run testng SwingSet2DemoTest
+ */
+@Listeners(GuiTestListener.class)
+public class SwingSet2DemoTest {
+
+    private static final String OCEAN_THEME_NAME = "Ocean";
+    private static final String STEEL_THEME_NAME = "Steel";
+    private static final int TOOLTIP_DISMISS_DELAY = 60000;
+
+    /**
+     * Testing check box menu item, radio button menu item, nested menus and
+     * themes. Testing of all other main swing components are covered in
+     * SwingSet3 demo tests.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void test() throws Exception {
+
+        new ClassReference(SwingSet2.class.getCanonicalName()).startApplication();
+        JFrameOperator frameOperator = new JFrameOperator(SwingSet2.FRAME_TITLE);
+        frameOperator.setComparator(EXACT_STRING_COMPARATOR);
+
+        checkCheckBoxMenuItem(frameOperator);
+        JMenuOperator themesMenu = new JMenuOperator(frameOperator, SwingSet2.THEMES_MENU_TEXT);
+        // Themes menu will be enabled only on MetalLookAndFeel
+        if(themesMenu.isEnabled()) {
+            checkMenuOnMenuAndRadioButtonMenuItem(frameOperator, themesMenu);
+            checkThemes(frameOperator, themesMenu);
+        }
+    }
+
+    /**
+     * Verifies the properties of nested menu and radio button menu item
+     * @param frameOperator
+     * @param themesMenu
+     */
+    private void checkMenuOnMenuAndRadioButtonMenuItem(
+            JFrameOperator frameOperator, JMenuOperator themesMenu) {
+
+        themesMenu.push();
+        themesMenu.waitSelected(true);
+        // Font menu is a nested menu, selecting that and verifying its
+        // sub menu items are launched
+        JMenuOperator fontMenu = new JMenuOperator(frameOperator, SwingSet2.FONT_MENU_TEXT);
+        JRadioButtonMenuItemOperator fontPlainMenuItem = new JRadioButtonMenuItemOperator(
+                (JRadioButtonMenuItem)fontMenu.showMenuItem(
+                        SwingSet2.FONT_PLAIN_MENU_TEXT, "/").getSource());
+        JRadioButtonMenuItemOperator fontBoldMenuItem = new JRadioButtonMenuItemOperator(
+                (JRadioButtonMenuItem)fontMenu.showMenuItem(
+                        SwingSet2.FONT_BOLD_MENU_TEXT, "/").getSource());
+        JButtonOperator testComp =
+                new JButtonOperator(frameOperator, OptionPaneDemo.INPUT_BUTTON);
+        checkRadioButtonMenuItem(fontBoldMenuItem, fontPlainMenuItem, testComp,
+                component -> component.getFont().isBold());
+        checkRadioButtonMenuItem(fontPlainMenuItem, fontBoldMenuItem, testComp,
+                component -> component.getFont().isPlain());
+    }
+
+    /**
+     * Verifies the properties of radio button menu item
+     * @param pressMenuItem
+     * @param unPressMenuItem
+     * @param testComp
+     * @param validator
+     */
+    private void checkRadioButtonMenuItem(JRadioButtonMenuItemOperator pressMenuItem,
+            JRadioButtonMenuItemOperator unPressMenuItem,
+            ComponentOperator testComp, ComponentChooser validator){
+
+        // Selecting a radio button menu item and verifying the pressed menu
+        // item is selected, other one is unselected and corresponding ui
+        // changes also happened
+        pressMenuItem.push();
+        pressMenuItem.waitSelected(true);
+        unPressMenuItem.waitSelected(false);
+        testComp.waitStateOnQueue(validator);
+    }
+
+    /**
+     * Verifies the properties of check box menu item
+     * @param frameOperator
+     */
+    private void checkCheckBoxMenuItem(JFrameOperator frameOperator) {
+
+        ToolTipManager.sharedInstance().setDismissDelay(TOOLTIP_DISMISS_DELAY);
+        JToggleButtonOperator testComp = new JToggleButtonOperator(
+                frameOperator, new NameComponentChooser(SwingSet2.getString(
+                        OptionPaneDemo.DEMO_NAME + SwingSet2.NAME_PROP_SUFFIX)));
+        JMenuOperator optionsMenu = new JMenuOperator(frameOperator, SwingSet2.OPTIONS_MENU_TEXT);
+        JCheckBoxMenuItemOperator toolTipMenuItem = new JCheckBoxMenuItemOperator(
+                (JCheckBoxMenuItem)optionsMenu.showMenuItem(
+                        SwingSet2.TOOLTIP_MENU_TEXT, "/").getSource());
+        // Selecting and deselecting tooltip checkbox menu item and verifying
+        // tooltip is showing for demo toggle button
+        toolTipMenuItem.push();
+        toolTipMenuItem.waitSelected(false);
+        boolean isToolTipTimeout = false;
+        try {
+            testComp.showToolTip();
+        } catch (TimeoutExpiredException e) {
+            isToolTipTimeout = true;
+        }
+        assertTrue(isToolTipTimeout, "Tooltip is showing even after unchecking the checkbox menu"
+                + " item 'Enable Tool Tips'");
+        toolTipMenuItem.push();
+        toolTipMenuItem.waitSelected(true);
+        testComp.showToolTip();
+    }
+
+    /**
+     * Verifies the different themes by applying different themes
+     * @param frameOperator
+     * @param themesMenu
+     */
+    private void checkThemes(JFrameOperator frameOperator, JMenuOperator themesMenu) {
+        String themeMenuNames [] = {SwingSet2.OCEAN_MENU_TEXT, SwingSet2.AQUA_MENU_TEXT,
+                SwingSet2.STEEL_MENU_TEXT, SwingSet2.CHARCOAL_MENU_TEXT,
+                SwingSet2.CONTRAST_MENU_TEXT, SwingSet2.EMERALD_MENU_TEXT, SwingSet2.RUBY_MENU_TEXT};
+        String themeNames [] = {OCEAN_THEME_NAME, AquaTheme.NAME, STEEL_THEME_NAME,
+                CharcoalTheme.NAME, ContrastTheme.NAME, EmeraldTheme.NAME, RubyTheme.NAME};
+
+        for (int i = 0; i < themeMenuNames.length; i++) {
+            int themeIndex = i;
+            JRadioButtonMenuItemOperator menuItem = new JRadioButtonMenuItemOperator(
+                    (JRadioButtonMenuItem)themesMenu.showMenuItem(
+                            themeMenuNames[themeIndex], "/").getSource());
+            menuItem.push();
+            menuItem.waitSelected(true);
+            menuItem.waitStateOnQueue(comp -> themeNames[themeIndex].
+                    equals(MetalLookAndFeel.getCurrentTheme().getName()));
+        }
+    }
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sanity/client/lib/SwingSet2/README	Wed May 09 16:03:49 2018 +0530
@@ -0,0 +1,4 @@
+The content of this src folder was originally taken from openjdk SwingSet2 demo: http://hg.openjdk.java.net/jdk/jdk/file/2d5d75263e77/src/demo/share/jfc/SwingSet2.
+Then it was modified to increase testability and removed extra content and extra dependencies.
+
+This is NOT the official location of the SwingSet2 demo.
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sanity/client/lib/SwingSet2/src/AquaTheme.java	Wed May 09 16:03:49 2018 +0530
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.swing.plaf.ColorUIResource;
+import javax.swing.plaf.metal.DefaultMetalTheme;
+
+/**
+ * This class describes a theme using "blue-green" colors.
+ *
+ * @author Steve Wilson
+ */
+public class AquaTheme extends DefaultMetalTheme {
+
+    public static String NAME = "Aqua";
+
+    public String getName() { return NAME; }
+
+    private final ColorUIResource primary1 = new ColorUIResource(102, 153, 153);
+    private final ColorUIResource primary2 = new ColorUIResource(128, 192, 192);
+    private final ColorUIResource primary3 = new ColorUIResource(159, 235, 235);
+
+    protected ColorUIResource getPrimary1() { return primary1; }
+    protected ColorUIResource getPrimary2() { return primary2; }
+    protected ColorUIResource getPrimary3() { return primary3; }
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sanity/client/lib/SwingSet2/src/CharcoalTheme.java	Wed May 09 16:03:49 2018 +0530
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.swing.plaf.ColorUIResource;
+import javax.swing.plaf.metal.DefaultMetalTheme;
+
+/**
+ * This class describes a theme using gray colors.
+ *
+ * @author Steve Wilson
+ */
+public class CharcoalTheme extends DefaultMetalTheme {
+
+    public static String NAME = "Charcoal";
+
+    public String getName() { return NAME; }
+
+    private final ColorUIResource primary1 = new ColorUIResource(66, 33, 66);
+    private final ColorUIResource primary2 = new ColorUIResource(90, 86, 99);
+    private final ColorUIResource primary3 = new ColorUIResource(99, 99, 99);
+
+    private final ColorUIResource secondary1 = new ColorUIResource(0, 0, 0);
+    private final ColorUIResource secondary2 = new ColorUIResource(51, 51, 51);
+    private final ColorUIResource secondary3 = new ColorUIResource(102, 102, 102);
+
+    private final ColorUIResource black = new ColorUIResource(222, 222, 222);
+    private final ColorUIResource white = new ColorUIResource(0, 0, 0);
+
+    protected ColorUIResource getPrimary1() { return primary1; }
+    protected ColorUIResource getPrimary2() { return primary2; }
+    protected ColorUIResource getPrimary3() { return primary3; }
+
+    protected ColorUIResource getSecondary1() { return secondary1; }
+    protected ColorUIResource getSecondary2() { return secondary2; }
+    protected ColorUIResource getSecondary3() { return secondary3; }
+
+    protected ColorUIResource getBlack() { return black; }
+    protected ColorUIResource getWhite() { return white; }
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sanity/client/lib/SwingSet2/src/ContrastTheme.java	Wed May 09 16:03:49 2018 +0530
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.swing.UIDefaults;
+import javax.swing.border.Border;
+import javax.swing.border.CompoundBorder;
+import javax.swing.border.LineBorder;
+import javax.swing.plaf.BorderUIResource;
+import javax.swing.plaf.ColorUIResource;
+import javax.swing.plaf.basic.BasicBorders;
+import javax.swing.plaf.metal.DefaultMetalTheme;
+
+/**
+ * This class describes a higher-contrast Metal Theme.
+ *
+ * @author Michael C. Albers
+ */
+
+public class ContrastTheme extends DefaultMetalTheme {
+
+    public static String NAME = "Contrast";
+
+    public String getName() { return NAME; }
+
+    private final ColorUIResource primary1 = new ColorUIResource(0, 0, 0);
+    private final ColorUIResource primary2 = new ColorUIResource(204, 204, 204);
+    private final ColorUIResource primary3 = new ColorUIResource(255, 255, 255);
+    private final ColorUIResource primaryHighlight = new ColorUIResource(102,102,102);
+
+    private final ColorUIResource secondary2 = new ColorUIResource(204, 204, 204);
+    private final ColorUIResource secondary3 = new ColorUIResource(255, 255, 255);
+
+    protected ColorUIResource getPrimary1() { return primary1; }
+    protected ColorUIResource getPrimary2() { return primary2; }
+    protected ColorUIResource getPrimary3() { return primary3; }
+    public ColorUIResource getPrimaryControlHighlight() { return primaryHighlight;}
+
+    protected ColorUIResource getSecondary2() { return secondary2; }
+    protected ColorUIResource getSecondary3() { return secondary3; }
+    public ColorUIResource getControlHighlight() { return super.getSecondary3(); }
+
+    public ColorUIResource getFocusColor() { return getBlack(); }
+
+    public ColorUIResource getTextHighlightColor() { return getBlack(); }
+    public ColorUIResource getHighlightedTextColor() { return getWhite(); }
+
+    public ColorUIResource getMenuSelectedBackground() { return getBlack(); }
+    public ColorUIResource getMenuSelectedForeground() { return getWhite(); }
+    public ColorUIResource getAcceleratorForeground() { return getBlack(); }
+    public ColorUIResource getAcceleratorSelectedForeground() { return getWhite(); }
+
+
+    public void addCustomEntriesToTable(UIDefaults table) {
+
+        Border blackLineBorder = new BorderUIResource(new LineBorder( getBlack() ));
+
+        Object textBorder = new BorderUIResource( new CompoundBorder(
+                                                       blackLineBorder,
+                                                       new BasicBorders.MarginBorder()));
+
+        table.put( "ToolTip.border", blackLineBorder);
+        table.put( "TitledBorder.border", blackLineBorder);
+
+        table.put( "TextField.border", textBorder);
+        table.put( "PasswordField.border", textBorder);
+        table.put( "TextArea.border", textBorder);
+        table.put( "TextPane.border", textBorder);
+        table.put( "EditorPane.border", textBorder);
+
+
+    }
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sanity/client/lib/SwingSet2/src/DemoModule.java	Wed May 09 16:03:49 2018 +0530
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+
+import javax.swing.BoxLayout;
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import javax.swing.JApplet;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.UIManager;
+import javax.swing.border.Border;
+import javax.swing.border.CompoundBorder;
+import javax.swing.border.EmptyBorder;
+import javax.swing.border.SoftBevelBorder;
+
+/**
+ * A generic SwingSet2 demo module
+ *
+ * @author Jeff Dinkins
+ */
+public class DemoModule extends JApplet {
+
+    // The preferred size of the demo
+    private int PREFERRED_WIDTH = 680;
+    private int PREFERRED_HEIGHT = 600;
+
+    Border loweredBorder = new CompoundBorder(new SoftBevelBorder(SoftBevelBorder.LOWERED),
+                                              new EmptyBorder(5,5,5,5));
+
+    // Premade convenience dimensions, for use wherever you need 'em.
+    public static Dimension HGAP2 = new Dimension(2,1);
+    public static Dimension VGAP2 = new Dimension(1,2);
+
+    public static Dimension HGAP5 = new Dimension(5,1);
+    public static Dimension VGAP5 = new Dimension(1,5);
+
+    public static Dimension HGAP10 = new Dimension(10,1);
+    public static Dimension VGAP10 = new Dimension(1,10);
+
+    public static Dimension HGAP15 = new Dimension(15,1);
+    public static Dimension VGAP15 = new Dimension(1,15);
+
+    public static Dimension HGAP20 = new Dimension(20,1);
+    public static Dimension VGAP20 = new Dimension(1,20);
+
+    public static Dimension HGAP25 = new Dimension(25,1);
+    public static Dimension VGAP25 = new Dimension(1,25);
+
+    public static Dimension HGAP30 = new Dimension(30,1);
+    public static Dimension VGAP30 = new Dimension(1,30);
+
+    private SwingSet2 swingset = null;
+    private JPanel panel = null;
+    private String resourceName = null;
+    private String iconPath = null;
+    private String sourceCode = null;
+
+    public DemoModule(SwingSet2 swingset) {
+        this(swingset, null, null);
+    }
+
+    public DemoModule(SwingSet2 swingset, String resourceName, String iconPath) {
+        UIManager.put("swing.boldMetal", Boolean.FALSE);
+        panel = new JPanel();
+        panel.setLayout(new BorderLayout());
+
+        this.resourceName = resourceName;
+        this.iconPath = iconPath;
+        this.swingset = swingset;
+
+        loadSourceCode();
+    }
+
+    public String getResourceName() {
+        return resourceName;
+    }
+
+    public JPanel getDemoPanel() {
+        return panel;
+    }
+
+    public SwingSet2 getSwingSet2() {
+        return swingset;
+    }
+
+
+    public String getString(String key) {
+
+        if (getSwingSet2() != null) {
+            return getSwingSet2().getString(key);
+        }else{
+            return "nada";
+        }
+    }
+
+    public char getMnemonic(String key) {
+        return (getString(key)).charAt(0);
+    }
+
+    public ImageIcon createImageIcon(String filename, String description) {
+        if(getSwingSet2() != null) {
+            return getSwingSet2().createImageIcon(filename, description);
+        } else {
+            String path = "/resources/images/" + filename;
+            return new ImageIcon(getClass().getResource(path), description);
+        }
+    }
+
+
+    public String getSourceCode() {
+        return sourceCode;
+    }
+
+    public void loadSourceCode() {
+        if(getResourceName() != null) {
+            String filename = getResourceName() + ".java";
+            sourceCode = new String("<html><body bgcolor=\"#ffffff\"><pre>");
+            InputStream is;
+            InputStreamReader isr;
+            URL url;
+
+            try {
+                url = getClass().getResource(filename);
+                is = url.openStream();
+                isr = new InputStreamReader(is, "UTF-8");
+                BufferedReader reader = new BufferedReader(isr);
+
+                // Read one line at a time, htmlize using super-spiffy
+                // html java code formating utility from www.CoolServlets.com
+                String line = reader.readLine();
+                while(line != null) {
+                    sourceCode += line + " \n ";
+                    line = reader.readLine();
+                }
+                sourceCode += new String("</pre></body></html>");
+            } catch (Exception ex) {
+                sourceCode = "Could not load file: " + filename;
+            }
+        }
+    }
+
+    public String getName() {
+        return getString(getResourceName() + ".name");
+    };
+
+    public Icon getIcon() {
+        return createImageIcon(iconPath, getResourceName() + ".name");
+    };
+
+    public String getToolTip() {
+        return getString(getResourceName() + ".tooltip");
+    };
+
+    public void mainImpl() {
+        JFrame frame = new JFrame(getName());
+        frame.getContentPane().setLayout(new BorderLayout());
+        frame.getContentPane().add(getDemoPanel(), BorderLayout.CENTER);
+        getDemoPanel().setPreferredSize(new Dimension(PREFERRED_WIDTH, PREFERRED_HEIGHT));
+        frame.pack();
+        frame.show();
+    }
+
+    public JPanel createHorizontalPanel(boolean threeD) {
+        JPanel p = new JPanel();
+        p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));
+        p.setAlignmentY(TOP_ALIGNMENT);
+        p.setAlignmentX(LEFT_ALIGNMENT);
+        if(threeD) {
+            p.setBorder(loweredBorder);
+        }
+        return p;
+    }
+
+    public JPanel createVerticalPanel(boolean threeD) {
+        JPanel p = new JPanel();
+        p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
+        p.setAlignmentY(TOP_ALIGNMENT);
+        p.setAlignmentX(LEFT_ALIGNMENT);
+        if(threeD) {
+            p.setBorder(loweredBorder);
+        }
+        return p;
+    }
+
+    public static void main(String[] args) {
+        DemoModule demo = new DemoModule(null);
+        demo.mainImpl();
+    }
+
+    public void init() {
+        getContentPane().setLayout(new BorderLayout());
+        getContentPane().add(getDemoPanel(), BorderLayout.CENTER);
+    }
+
+    void updateDragEnabled(boolean dragEnabled) {}
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sanity/client/lib/SwingSet2/src/EmeraldTheme.java	Wed May 09 16:03:49 2018 +0530
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.swing.plaf.ColorUIResource;
+import javax.swing.plaf.metal.DefaultMetalTheme;
+
+/**
+ * This class describes a theme using glowing green colors.
+ *
+ * @author Jeff Dinkins
+ */
+public class EmeraldTheme extends DefaultMetalTheme {
+
+    public static String NAME = "Emerald";
+
+    public String getName() { return NAME; }
+
+    private final ColorUIResource primary1 = new ColorUIResource(51, 142, 71);
+    private final ColorUIResource primary2 = new ColorUIResource(102, 193, 122);
+    private final ColorUIResource primary3 = new ColorUIResource(153, 244, 173);
+
+    protected ColorUIResource getPrimary1() { return primary1; }
+    protected ColorUIResource getPrimary2() { return primary2; }
+    protected ColorUIResource getPrimary3() { return primary3; }
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sanity/client/lib/SwingSet2/src/OptionPaneDemo.java	Wed May 09 16:03:49 2018 +0530
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.Dimension;
+import java.awt.event.ActionEvent;
+import java.net.URL;
+
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.Box;
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+
+/**
+ * JOptionPaneDemo
+ *
+ * @author Jeff Dinkins
+ */
+public class OptionPaneDemo extends DemoModule {
+
+    public static final String DEMO_NAME = "OptionPaneDemo";
+    public static final String INPUT_BUTTON = "Show Input Dialog";
+
+    /**
+     * main method allows us to run as a standalone demo.
+     */
+    public static void main(String[] args) {
+        OptionPaneDemo demo = new OptionPaneDemo(null);
+        demo.mainImpl();
+    }
+
+    /**
+     * OptionPaneDemo Constructor
+     */
+    public OptionPaneDemo(SwingSet2 swingset) {
+        // Set the title for this demo, and an icon used to represent this
+        // demo inside the SwingSet2 app.
+        super(swingset, DEMO_NAME, "toolbar/JOptionPane.gif");
+
+        JPanel demo = getDemoPanel();
+
+        demo.setLayout(new BoxLayout(demo, BoxLayout.X_AXIS));
+
+        JPanel bp = new JPanel() {
+            public Dimension getMaximumSize() {
+                return new Dimension(getPreferredSize().width, super.getMaximumSize().height);
+            }
+        };
+        bp.setLayout(new BoxLayout(bp, BoxLayout.Y_AXIS));
+
+        bp.add(Box.createRigidArea(VGAP30));
+        bp.add(Box.createRigidArea(VGAP30));
+
+        bp.add(createInputDialogButton());      bp.add(Box.createRigidArea(VGAP15));
+        bp.add(createWarningDialogButton());    bp.add(Box.createRigidArea(VGAP15));
+        bp.add(createMessageDialogButton());    bp.add(Box.createRigidArea(VGAP15));
+        bp.add(createComponentDialogButton());  bp.add(Box.createRigidArea(VGAP15));
+        bp.add(createConfirmDialogButton());    bp.add(Box.createVerticalGlue());
+
+        demo.add(Box.createHorizontalGlue());
+        demo.add(bp);
+        demo.add(Box.createHorizontalGlue());
+    }
+
+    public JButton createWarningDialogButton() {
+        Action a = new AbstractAction(getString("OptionPaneDemo.warningbutton")) {
+            public void actionPerformed(ActionEvent e) {
+                JOptionPane.showMessageDialog(
+                    getDemoPanel(),
+                    getString("OptionPaneDemo.warningtext"),
+                    getString("OptionPaneDemo.warningtitle"),
+                    JOptionPane.WARNING_MESSAGE
+                );
+            }
+        };
+        return createButton(a);
+    }
+
+    public JButton createMessageDialogButton() {
+        Action a = new AbstractAction(getString("OptionPaneDemo.messagebutton")) {
+            URL img = getClass().getResource("/resources/images/optionpane/bottle.gif");
+            String imagesrc = "<img src=\"" + img + "\" width=\"284\" height=\"100\">";
+            String message = getString("OptionPaneDemo.messagetext");
+            public void actionPerformed(ActionEvent e) {
+                JOptionPane.showMessageDialog(
+                    getDemoPanel(),
+                    "<html>" + imagesrc + "<br><center>" + message + "</center><br></html>"
+                );
+            }
+        };
+        return createButton(a);
+    }
+
+    public JButton createConfirmDialogButton() {
+        Action a = new AbstractAction(getString("OptionPaneDemo.confirmbutton")) {
+            public void actionPerformed(ActionEvent e) {
+                int result = JOptionPane.showConfirmDialog(getDemoPanel(), getString("OptionPaneDemo.confirmquestion"));
+                if(result == JOptionPane.YES_OPTION) {
+                    JOptionPane.showMessageDialog(getDemoPanel(), getString("OptionPaneDemo.confirmyes"));
+                } else if(result == JOptionPane.NO_OPTION) {
+                    JOptionPane.showMessageDialog(getDemoPanel(), getString("OptionPaneDemo.confirmno"));
+                }
+            }
+        };
+        return createButton(a);
+    }
+
+    public JButton createInputDialogButton() {
+        Action a = new AbstractAction(getString("OptionPaneDemo.inputbutton")) {
+            public void actionPerformed(ActionEvent e) {
+                String result = JOptionPane.showInputDialog(getDemoPanel(), getString("OptionPaneDemo.inputquestion"));
+                if ((result != null) && (result.length() > 0)) {
+                    JOptionPane.showMessageDialog(getDemoPanel(),
+                                    result + ": " +
+                                    getString("OptionPaneDemo.inputresponse"));
+                }
+            }
+        };
+        return createButton(a);
+    }
+
+    public JButton createComponentDialogButton() {
+        Action a = new AbstractAction(getString("OptionPaneDemo.componentbutton")) {
+            public void actionPerformed(ActionEvent e) {
+                // In a ComponentDialog, you can show as many message components and
+                // as many options as you want:
+
+                // Messages
+                Object[]      message = new Object[4];
+                message[0] = getString("OptionPaneDemo.componentmessage");
+                message[1] = new JTextField(getString("OptionPaneDemo.componenttextfield"));
+
+                JComboBox cb = new JComboBox();
+                cb.addItem(getString("OptionPaneDemo.component_cb1"));
+                cb.addItem(getString("OptionPaneDemo.component_cb2"));
+                cb.addItem(getString("OptionPaneDemo.component_cb3"));
+                message[2] = cb;
+
+                message[3] = getString("OptionPaneDemo.componentmessage2");
+
+                // Options
+                String[] options = {
+                    getString("OptionPaneDemo.component_op1"),
+                    getString("OptionPaneDemo.component_op2"),
+                    getString("OptionPaneDemo.component_op3"),
+                    getString("OptionPaneDemo.component_op4"),
+                    getString("OptionPaneDemo.component_op5")
+                };
+                int result = JOptionPane.showOptionDialog(
+                    getDemoPanel(),                             // the parent that the dialog blocks
+                    message,                                    // the dialog message array
+                    getString("OptionPaneDemo.componenttitle"), // the title of the dialog window
+                    JOptionPane.DEFAULT_OPTION,                 // option type
+                    JOptionPane.INFORMATION_MESSAGE,            // message type
+                    null,                                       // optional icon, use null to use the default icon
+                    options,                                    // options string array, will be made into buttons
+                    options[3]                                  // option that should be made into a default button
+                );
+                switch(result) {
+                   case 0: // yes
+                     JOptionPane.showMessageDialog(getDemoPanel(), getString("OptionPaneDemo.component_r1"));
+                     break;
+                   case 1: // no
+                     JOptionPane.showMessageDialog(getDemoPanel(), getString("OptionPaneDemo.component_r2"));
+                     break;
+                   case 2: // maybe
+                     JOptionPane.showMessageDialog(getDemoPanel(), getString("OptionPaneDemo.component_r3"));
+                     break;
+                   case 3: // probably
+                     JOptionPane.showMessageDialog(getDemoPanel(), getString("OptionPaneDemo.component_r4"));
+                     break;
+                   default:
+                     break;
+                }
+
+            }
+        };
+        return createButton(a);
+    }
+
+    public JButton createButton(Action a) {
+        JButton b = new JButton() {
+            public Dimension getMaximumSize() {
+                int width = Short.MAX_VALUE;
+                int height = super.getMaximumSize().height;
+                return new Dimension(width, height);
+            }
+        };
+        // setting the following client property informs the button to show
+        // the action text as it's name. The default is to not show the
+        // action text.
+        b.putClientProperty("displayActionText", Boolean.TRUE);
+        b.setAction(a);
+        // b.setAlignmentX(JButton.CENTER_ALIGNMENT);
+        return b;
+    }
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sanity/client/lib/SwingSet2/src/RubyTheme.java	Wed May 09 16:03:49 2018 +0530
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.swing.plaf.ColorUIResource;
+import javax.swing.plaf.metal.DefaultMetalTheme;
+
+/**
+ * This class describes a theme using red colors.
+ *
+ * @author Jeff Dinkins
+ */
+public class RubyTheme extends DefaultMetalTheme {
+
+    public static String NAME = "Ruby";
+
+    public String getName() { return NAME; }
+
+    private final ColorUIResource primary1 = new ColorUIResource(80, 10, 22);
+    private final ColorUIResource primary2 = new ColorUIResource(193, 10, 44);
+    private final ColorUIResource primary3 = new ColorUIResource(244, 10, 66);
+
+    protected ColorUIResource getPrimary1() { return primary1; }
+    protected ColorUIResource getPrimary2() { return primary2; }
+    protected ColorUIResource getPrimary3() { return primary3; }
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sanity/client/lib/SwingSet2/src/SwingSet2.java	Wed May 09 16:03:49 2018 +0530
@@ -0,0 +1,1261 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.Insets;
+import java.awt.Rectangle;
+import java.awt.Toolkit;
+import java.awt.event.ActionEvent;
+import java.awt.event.ContainerEvent;
+import java.awt.event.ContainerListener;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.MissingResourceException;
+import java.util.Vector;
+
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.ButtonGroup;
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import javax.swing.InputMap;
+import javax.swing.JButton;
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JComponent;
+import javax.swing.JDialog;
+import javax.swing.JEditorPane;
+import javax.swing.JFrame;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
+import javax.swing.JRadioButtonMenuItem;
+import javax.swing.JScrollPane;
+import javax.swing.JTabbedPane;
+import javax.swing.JTextField;
+import javax.swing.JToggleButton;
+import javax.swing.JToolBar;
+import javax.swing.KeyStroke;
+import javax.swing.SingleSelectionModel;
+import javax.swing.SwingUtilities;
+import javax.swing.ToolTipManager;
+import javax.swing.UIManager;
+import javax.swing.border.EtchedBorder;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.plaf.metal.DefaultMetalTheme;
+import javax.swing.plaf.metal.MetalLookAndFeel;
+import javax.swing.plaf.metal.MetalTheme;
+import javax.swing.plaf.metal.OceanTheme;
+
+/**
+ * A demo that shows all of the Swing components.
+ *
+ * @author Jeff Dinkins
+ */
+public class SwingSet2 extends JPanel {
+
+    String[] demos = {
+      "ButtonDemo",
+      "ColorChooserDemo",
+      "ComboBoxDemo",
+      "FileChooserDemo",
+      "HtmlDemo",
+      "ListDemo",
+      "OptionPaneDemo",
+      "ProgressBarDemo",
+      "ScrollPaneDemo",
+      "SliderDemo",
+      "SplitPaneDemo",
+      "TabbedPaneDemo",
+      "TableDemo",
+      "ToolTipDemo",
+      "TreeDemo"
+    };
+
+     // The current Look & Feel
+    private static LookAndFeelData currentLookAndFeel;
+    private static LookAndFeelData[] lookAndFeelData;
+    // List of demos
+    private ArrayList<DemoModule> demosList = new ArrayList<DemoModule>();
+
+    public static final String FRAME_TITLE = getString("Frame.title");
+    public static final String THEMES_MENU_TEXT = getString("ThemesMenu.themes_label");
+    public static final String OPTIONS_MENU_TEXT = getString("OptionsMenu.options_label");
+    public static final String FONT_MENU_TEXT = getString("FontMenu.fonts_label");
+    public static final String FONT_PLAIN_MENU_TEXT = getString("FontMenu.plain_label");
+    public static final String FONT_BOLD_MENU_TEXT = getString("FontMenu.bold_label");
+    public static final String TOOLTIP_MENU_TEXT = getString("OptionsMenu.tooltip_label");
+    public static final String OCEAN_MENU_TEXT = getString("ThemesMenu.ocean_label");
+    public static final String AQUA_MENU_TEXT = getString("ThemesMenu.aqua_label");
+    public static final String STEEL_MENU_TEXT = getString("ThemesMenu.steel_label");
+    public static final String CONTRAST_MENU_TEXT = getString("ThemesMenu.contrast_label");
+    public static final String CHARCOAL_MENU_TEXT = getString("ThemesMenu.charcoal_label");
+    public static final String EMERALD_MENU_TEXT = getString("ThemesMenu.emerald_label");
+    public static final String RUBY_MENU_TEXT= getString("ThemesMenu.ruby_label");
+    public static final String NAME_PROP_SUFFIX = ".name";
+
+    // The preferred size of the demo
+    private static final int PREFERRED_WIDTH = 720;
+    private static final int PREFERRED_HEIGHT = 640;
+
+    // A place to hold on to the visible demo
+    private DemoModule currentDemo = null;
+    private JPanel demoPanel = null;
+
+    // About Box
+    private JDialog aboutBox = null;
+
+    // Status Bar
+    private JTextField statusField = null;
+
+    // Tool Bar
+    private ToggleButtonToolBar toolbar = null;
+    private ButtonGroup toolbarGroup = new ButtonGroup();
+
+    // Menus
+    private JMenuBar menuBar = null;
+    private JMenu lafMenu = null;
+    private JMenu themesMenu = null;
+    private JMenu audioMenu = null;
+    private JMenu optionsMenu = null;
+    private ButtonGroup lafMenuGroup = new ButtonGroup();
+    private ButtonGroup themesMenuGroup = new ButtonGroup();
+    private ButtonGroup audioMenuGroup = new ButtonGroup();
+
+    // Popup menu
+    private JPopupMenu popupMenu = null;
+    private ButtonGroup popupMenuGroup = new ButtonGroup();
+
+    // Used only if swingset is an application
+    private JFrame frame = null;
+
+    // The tab pane that holds the demo
+    private JTabbedPane tabbedPane = null;
+
+    private JEditorPane demoSrcPane = null;
+
+
+    // contentPane cache, saved from the application frame
+    Container contentPane = null;
+
+
+    // number of swingsets - for multiscreen
+    // keep track of the number of SwingSets created - we only want to exit
+    // the program when the last one has been closed.
+    private static int numSSs = 0;
+    private static Vector<SwingSet2> swingSets = new Vector<SwingSet2>();
+
+    private boolean dragEnabled = false;
+
+    /**
+     * SwingSet2 Constructor
+     */
+    public SwingSet2(GraphicsConfiguration gc) {
+
+        String lafClassName = UIManager.getLookAndFeel().getClass().getName();
+        lookAndFeelData = getInstalledLookAndFeelData();
+        currentLookAndFeel = Arrays.stream(lookAndFeelData)
+                .filter(laf -> lafClassName.equals(laf.className))
+                .findFirst().get();
+
+        frame = createFrame(gc);
+
+        // set the layout
+        setLayout(new BorderLayout());
+
+        // set the preferred size of the demo
+        setPreferredSize(new Dimension(PREFERRED_WIDTH,PREFERRED_HEIGHT));
+
+        initializeDemo();
+        preloadFirstDemo();
+
+        showSwingSet2();
+    }
+
+    /**
+     * SwingSet2 Main.
+     */
+    public static void main(final String[] args) {
+        // must run in EDT when constructing the GUI components
+        SwingUtilities.invokeLater(() -> {
+            // Create SwingSet on the default monitor
+            UIManager.put("swing.boldMetal", Boolean.FALSE);
+            SwingSet2 swingset = new SwingSet2(GraphicsEnvironment.
+                                         getLocalGraphicsEnvironment().
+                                         getDefaultScreenDevice().
+                                         getDefaultConfiguration());
+        });
+    }
+
+    // *******************************************************
+    // *************** Demo Loading Methods ******************
+    // *******************************************************
+
+
+    public void initializeDemo() {
+        JPanel top = new JPanel();
+        top.setLayout(new BorderLayout());
+        add(top, BorderLayout.NORTH);
+
+        menuBar = createMenus();
+        frame.setJMenuBar(menuBar);
+
+        // creates popup menu accessible via keyboard
+        popupMenu = createPopupMenu();
+
+        ToolBarPanel toolbarPanel = new ToolBarPanel();
+        toolbarPanel.setLayout(new BorderLayout());
+        toolbar = new ToggleButtonToolBar();
+        toolbarPanel.add(toolbar, BorderLayout.CENTER);
+        top.add(toolbarPanel, BorderLayout.SOUTH);
+        toolbarPanel.addContainerListener(toolbarPanel);
+
+        tabbedPane = new JTabbedPane();
+        add(tabbedPane, BorderLayout.CENTER);
+        tabbedPane.getModel().addChangeListener(new TabListener());
+
+        statusField = new JTextField("");
+        statusField.setEditable(false);
+        add(statusField, BorderLayout.SOUTH);
+
+        demoPanel = new JPanel();
+        demoPanel.setLayout(new BorderLayout());
+        demoPanel.setBorder(new EtchedBorder());
+        tabbedPane.addTab("Hi There!", demoPanel);
+
+        // Add html src code viewer
+        demoSrcPane = new JEditorPane("text/html", getString("SourceCode.loading"));
+        demoSrcPane.setEditable(false);
+
+        JScrollPane scroller = new JScrollPane();
+        scroller.getViewport().add(demoSrcPane);
+
+        tabbedPane.addTab(
+            getString("TabbedPane.src_label"),
+            null,
+            scroller,
+            getString("TabbedPane.src_tooltip")
+        );
+    }
+
+    DemoModule currentTabDemo = null;
+    class TabListener implements ChangeListener {
+        public void stateChanged(ChangeEvent e) {
+            SingleSelectionModel model = (SingleSelectionModel) e.getSource();
+            boolean srcSelected = model.getSelectedIndex() == 1;
+            if(currentTabDemo != currentDemo && demoSrcPane != null && srcSelected) {
+                demoSrcPane.setText(getString("SourceCode.loading"));
+                repaint();
+            }
+            if(currentTabDemo != currentDemo && srcSelected) {
+                currentTabDemo = currentDemo;
+                setSourceCode(currentDemo);
+            }
+        }
+    }
+
+    /**
+     * Create menus
+     */
+    public JMenuBar createMenus() {
+        JMenuItem mi;
+        // ***** create the menubar ****
+        JMenuBar menuBar = new JMenuBar();
+        menuBar.getAccessibleContext().setAccessibleName(
+            getString("MenuBar.accessible_description"));
+
+        // ***** create File menu
+        JMenu fileMenu = (JMenu) menuBar.add(new JMenu(getString("FileMenu.file_label")));
+        fileMenu.setMnemonic(getMnemonic("FileMenu.file_mnemonic"));
+        fileMenu.getAccessibleContext().setAccessibleDescription(getString("FileMenu.accessible_description"));
+
+        createMenuItem(fileMenu, "FileMenu.about_label", "FileMenu.about_mnemonic",
+                       "FileMenu.about_accessible_description", new AboutAction(this));
+
+        fileMenu.addSeparator();
+
+        createMenuItem(fileMenu, "FileMenu.open_label", "FileMenu.open_mnemonic",
+                       "FileMenu.open_accessible_description", null);
+
+        createMenuItem(fileMenu, "FileMenu.save_label", "FileMenu.save_mnemonic",
+                       "FileMenu.save_accessible_description", null);
+
+        createMenuItem(fileMenu, "FileMenu.save_as_label", "FileMenu.save_as_mnemonic",
+                       "FileMenu.save_as_accessible_description", null);
+
+        fileMenu.addSeparator();
+
+        createMenuItem(fileMenu, "FileMenu.exit_label", "FileMenu.exit_mnemonic",
+                       "FileMenu.exit_accessible_description", new ExitAction(this)
+        );
+
+        // Create these menu items for the first SwingSet only.
+        if (numSSs == 0) {
+        // ***** create laf switcher menu
+        lafMenu = (JMenu) menuBar.add(new JMenu(getString("LafMenu.laf_label")));
+        lafMenu.setMnemonic(getMnemonic("LafMenu.laf_mnemonic"));
+        lafMenu.getAccessibleContext().setAccessibleDescription(
+            getString("LafMenu.laf_accessible_description"));
+
+        for (LookAndFeelData lafData : lookAndFeelData) {
+            mi = createLafMenuItem(lafMenu, lafData);
+            mi.setSelected(lafData.equals(currentLookAndFeel));
+        }
+
+        // ***** create themes menu
+        themesMenu = (JMenu) menuBar.add(new JMenu(THEMES_MENU_TEXT));
+        themesMenu.setMnemonic(getMnemonic("ThemesMenu.themes_mnemonic"));
+        themesMenu.getAccessibleContext().setAccessibleDescription(
+            getString("ThemesMenu.themes_accessible_description"));
+
+        // ***** create the audio submenu under the theme menu
+        audioMenu = (JMenu) themesMenu.add(new JMenu(getString("AudioMenu.audio_label")));
+        audioMenu.setMnemonic(getMnemonic("AudioMenu.audio_mnemonic"));
+        audioMenu.getAccessibleContext().setAccessibleDescription(
+            getString("AudioMenu.audio_accessible_description"));
+
+        createAudioMenuItem(audioMenu, "AudioMenu.on_label",
+                            "AudioMenu.on_mnemonic",
+                            "AudioMenu.on_accessible_description",
+                            new OnAudioAction(this));
+
+        mi = createAudioMenuItem(audioMenu, "AudioMenu.default_label",
+                                 "AudioMenu.default_mnemonic",
+                                 "AudioMenu.default_accessible_description",
+                                 new DefaultAudioAction(this));
+        mi.setSelected(true); // This is the default feedback setting
+
+        createAudioMenuItem(audioMenu, "AudioMenu.off_label",
+                            "AudioMenu.off_mnemonic",
+                            "AudioMenu.off_accessible_description",
+                            new OffAudioAction(this));
+
+
+        // ***** create the font submenu under the theme menu
+        JMenu fontMenu = (JMenu) themesMenu.add(new JMenu(FONT_MENU_TEXT));
+        fontMenu.setMnemonic(getMnemonic("FontMenu.fonts_mnemonic"));
+        fontMenu.getAccessibleContext().setAccessibleDescription(
+            getString("FontMenu.fonts_accessible_description"));
+        ButtonGroup fontButtonGroup = new ButtonGroup();
+        mi = createButtonGroupMenuItem(fontMenu, FONT_PLAIN_MENU_TEXT,
+                "FontMenu.plain_mnemonic",
+                "FontMenu.plain_accessible_description",
+                new ChangeFontAction(this, true), fontButtonGroup);
+        mi.setSelected(true);
+        mi = createButtonGroupMenuItem(fontMenu, FONT_BOLD_MENU_TEXT,
+                "FontMenu.bold_mnemonic",
+                "FontMenu.bold_accessible_description",
+                new ChangeFontAction(this, false), fontButtonGroup);
+
+
+
+        // *** now back to adding color/font themes to the theme menu
+        mi = createThemesMenuItem(themesMenu, OCEAN_MENU_TEXT,
+                                              "ThemesMenu.ocean_mnemonic",
+                                              "ThemesMenu.ocean_accessible_description",
+                                              new OceanTheme());
+        mi.setSelected(true); // This is the default theme
+
+        createThemesMenuItem(themesMenu, STEEL_MENU_TEXT,
+                             "ThemesMenu.steel_mnemonic",
+                             "ThemesMenu.steel_accessible_description",
+                             new DefaultMetalTheme());
+
+        createThemesMenuItem(themesMenu, AQUA_MENU_TEXT, "ThemesMenu.aqua_mnemonic",
+                       "ThemesMenu.aqua_accessible_description", new AquaTheme());
+
+        createThemesMenuItem(themesMenu, CHARCOAL_MENU_TEXT, "ThemesMenu.charcoal_mnemonic",
+                       "ThemesMenu.charcoal_accessible_description", new CharcoalTheme());
+
+        createThemesMenuItem(themesMenu, CONTRAST_MENU_TEXT, "ThemesMenu.contrast_mnemonic",
+                       "ThemesMenu.contrast_accessible_description", new ContrastTheme());
+
+        createThemesMenuItem(themesMenu, EMERALD_MENU_TEXT, "ThemesMenu.emerald_mnemonic",
+                       "ThemesMenu.emerald_accessible_description", new EmeraldTheme());
+
+        createThemesMenuItem(themesMenu, RUBY_MENU_TEXT, "ThemesMenu.ruby_mnemonic",
+                       "ThemesMenu.ruby_accessible_description", new RubyTheme());
+
+        // Enable theme menu based on L&F
+        themesMenu.setEnabled("Metal".equals(currentLookAndFeel.name));
+
+        // ***** create the options menu
+        optionsMenu = (JMenu)menuBar.add(
+            new JMenu(OPTIONS_MENU_TEXT));
+        optionsMenu.setMnemonic(getMnemonic("OptionsMenu.options_mnemonic"));
+        optionsMenu.getAccessibleContext().setAccessibleDescription(
+            getString("OptionsMenu.options_accessible_description"));
+
+        // ***** create tool tip submenu item.
+        mi = createCheckBoxMenuItem(optionsMenu, TOOLTIP_MENU_TEXT,
+                "OptionsMenu.tooltip_mnemonic",
+                "OptionsMenu.tooltip_accessible_description",
+                new ToolTipAction());
+        mi.setSelected(true);
+
+        // ***** create drag support submenu item.
+        createCheckBoxMenuItem(optionsMenu, getString("OptionsMenu.dragEnabled_label"),
+                "OptionsMenu.dragEnabled_mnemonic",
+                "OptionsMenu.dragEnabled_accessible_description",
+                new DragSupportAction());
+        }
+
+        // ***** create the multiscreen menu, if we have multiple screens
+        GraphicsDevice[] screens = GraphicsEnvironment.
+                getLocalGraphicsEnvironment().
+                getScreenDevices();
+        if (screens.length > 1) {
+            JMenu multiScreenMenu = (JMenu) menuBar.add(new JMenu(
+                 getString("MultiMenu.multi_label")));
+            multiScreenMenu.setMnemonic(getMnemonic("MultiMenu.multi_mnemonic"));
+            multiScreenMenu.getAccessibleContext().setAccessibleDescription(
+                    getString("MultiMenu.multi_accessible_description"));
+
+            createMultiscreenMenuItem(multiScreenMenu, MultiScreenAction.ALL_SCREENS);
+            for (int i = 0; i < screens.length; i++) {
+                createMultiscreenMenuItem(multiScreenMenu, i);
+            }
+        }
+        return menuBar;
+    }
+
+    /**
+     * Create a checkbox menu menu item
+     */
+    private JMenuItem createCheckBoxMenuItem(JMenu menu, String label,
+                                             String mnemonic,
+                                             String accessibleDescription,
+                                             Action action) {
+        JCheckBoxMenuItem mi = (JCheckBoxMenuItem)menu.add(
+                new JCheckBoxMenuItem(label));
+        mi.setMnemonic(getMnemonic(mnemonic));
+        mi.getAccessibleContext().setAccessibleDescription(getString(
+                accessibleDescription));
+        mi.addActionListener(action);
+        return mi;
+    }
+
+    /**
+     * Create a radio button menu menu item for items that are part of a
+     * button group.
+     */
+    private JMenuItem createButtonGroupMenuItem(JMenu menu, String label,
+                                                String mnemonic,
+                                                String accessibleDescription,
+                                                Action action,
+                                                ButtonGroup buttonGroup) {
+        JRadioButtonMenuItem mi = (JRadioButtonMenuItem)menu.add(
+                new JRadioButtonMenuItem(label));
+        buttonGroup.add(mi);
+        mi.setMnemonic(getMnemonic(mnemonic));
+        mi.getAccessibleContext().setAccessibleDescription(getString(
+                accessibleDescription));
+        mi.addActionListener(action);
+        return mi;
+    }
+
+    /**
+     * Create the theme's audio submenu
+     */
+    public JMenuItem createAudioMenuItem(JMenu menu, String label,
+                                         String mnemonic,
+                                         String accessibleDescription,
+                                         Action action) {
+        JRadioButtonMenuItem mi = (JRadioButtonMenuItem) menu.add(new JRadioButtonMenuItem(getString(label)));
+        audioMenuGroup.add(mi);
+        mi.setMnemonic(getMnemonic(mnemonic));
+        mi.getAccessibleContext().setAccessibleDescription(getString(accessibleDescription));
+        mi.addActionListener(action);
+        return mi;
+    }
+
+    /**
+     * Creates a generic menu item
+     */
+    public JMenuItem createMenuItem(JMenu menu, String label, String mnemonic,
+                               String accessibleDescription, Action action) {
+        JMenuItem mi = (JMenuItem) menu.add(new JMenuItem(getString(label)));
+        mi.setMnemonic(getMnemonic(mnemonic));
+        mi.getAccessibleContext().setAccessibleDescription(getString(accessibleDescription));
+        mi.addActionListener(action);
+        if(action == null) {
+            mi.setEnabled(false);
+        }
+        return mi;
+    }
+
+    /**
+     * Creates a JRadioButtonMenuItem for the Themes menu
+     */
+    public JMenuItem createThemesMenuItem(JMenu menu, String label, String mnemonic,
+                               String accessibleDescription, MetalTheme theme) {
+        JRadioButtonMenuItem mi = (JRadioButtonMenuItem) menu.add(new JRadioButtonMenuItem(label));
+        themesMenuGroup.add(mi);
+        mi.setMnemonic(getMnemonic(mnemonic));
+        mi.getAccessibleContext().setAccessibleDescription(getString(accessibleDescription));
+        mi.addActionListener(new ChangeThemeAction(this, theme));
+        return mi;
+    }
+
+    /**
+     * Creates a JRadioButtonMenuItem for the Look and Feel menu
+     */
+    public JMenuItem createLafMenuItem(JMenu menu, LookAndFeelData lafData) {
+        JMenuItem mi = menu.add(new JRadioButtonMenuItem(lafData.label));
+        lafMenuGroup.add(mi);
+        mi.setMnemonic(lafData.mnemonic);
+        mi.getAccessibleContext().setAccessibleDescription(lafData.accDescription);
+        mi.addActionListener(new ChangeLookAndFeelAction(this, lafData));
+        return mi;
+    }
+
+    /**
+     * Creates a multi-screen menu item
+     */
+    public JMenuItem createMultiscreenMenuItem(JMenu menu, int screen) {
+        JMenuItem mi = null;
+        if (screen == MultiScreenAction.ALL_SCREENS) {
+            mi = (JMenuItem) menu.add(new JMenuItem(getString("MultiMenu.all_label")));
+            mi.setMnemonic(getMnemonic("MultiMenu.all_mnemonic"));
+            mi.getAccessibleContext().setAccessibleDescription(getString(
+                                                                 "MultiMenu.all_accessible_description"));
+        }
+        else {
+            mi = (JMenuItem) menu.add(new JMenuItem(getString("MultiMenu.single_label") + " " +
+                                                                                                 screen));
+            mi.setMnemonic(KeyEvent.VK_0 + screen);
+            mi.getAccessibleContext().setAccessibleDescription(getString(
+                                               "MultiMenu.single_accessible_description") + " " + screen);
+
+        }
+        mi.addActionListener(new MultiScreenAction(this, screen));
+        return mi;
+    }
+
+    public JPopupMenu createPopupMenu() {
+        JPopupMenu popup = new JPopupMenu("JPopupMenu demo");
+
+        for (LookAndFeelData lafData : lookAndFeelData) {
+            createPopupMenuItem(popup, lafData);
+        }
+
+        // register key binding to activate popup menu
+        InputMap map = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
+        map.put(KeyStroke.getKeyStroke(KeyEvent.VK_F10, InputEvent.SHIFT_MASK),
+                "postMenuAction");
+        map.put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTEXT_MENU, 0), "postMenuAction");
+        getActionMap().put("postMenuAction", new ActivatePopupMenuAction(this, popup));
+
+        return popup;
+    }
+
+    /**
+     * Creates a JMenuItem for the Look and Feel popup menu
+     */
+    public JMenuItem createPopupMenuItem(JPopupMenu menu, LookAndFeelData lafData) {
+        JMenuItem mi = menu.add(new JMenuItem(lafData.label));
+        popupMenuGroup.add(mi);
+        mi.setMnemonic(lafData.mnemonic);
+        mi.getAccessibleContext().setAccessibleDescription(lafData.accDescription);
+        mi.addActionListener(new ChangeLookAndFeelAction(this, lafData));
+        return mi;
+    }
+
+    /**
+     * Load the first demo. This is done separately from the remaining demos
+     * so that we can get SwingSet2 up and available to the user quickly.
+     */
+    public void preloadFirstDemo() {
+        DemoModule demo = addDemo(new OptionPaneDemo(this));
+        setDemo(demo);
+    }
+
+    /**
+     * Add a demo to the toolbar
+     */
+    public DemoModule addDemo(DemoModule demo) {
+        demosList.add(demo);
+        if (dragEnabled) {
+            demo.updateDragEnabled(true);
+        }
+        // do the following on the gui thread
+        SwingUtilities.invokeLater(new SwingSetRunnable(this, demo) {
+            public void run() {
+                SwitchToDemoAction action = new SwitchToDemoAction(swingset, (DemoModule) obj);
+                JToggleButton tb = swingset.getToolBar().addToggleButton(action);
+                swingset.getToolBarGroup().add(tb);
+                if(swingset.getToolBarGroup().getSelection() == null) {
+                    tb.setSelected(true);
+                }
+                tb.setText(null);
+                tb.setToolTipText(((DemoModule)obj).getToolTip());
+
+                if(demos[demos.length-1].equals(obj.getClass().getName())) {
+                    setStatus(getString("Status.popupMenuAccessible"));
+                }
+            }
+        });
+        return demo;
+    }
+
+    /**
+     * Sets the current demo
+     */
+    public void setDemo(DemoModule demo) {
+        currentDemo = demo;
+
+        // Ensure panel's UI is current before making visible
+        JComponent currentDemoPanel = demo.getDemoPanel();
+        SwingUtilities.updateComponentTreeUI(currentDemoPanel);
+
+        demoPanel.removeAll();
+        demoPanel.add(currentDemoPanel, BorderLayout.CENTER);
+
+        tabbedPane.setSelectedIndex(0);
+        tabbedPane.setTitleAt(0, demo.getName());
+        tabbedPane.setToolTipTextAt(0, demo.getToolTip());
+    }
+
+    /**
+     * Bring up the SwingSet2 demo by showing the frame
+     */
+    public void showSwingSet2() {
+        if(getFrame() != null) {
+            // put swingset in a frame and show it
+            JFrame f = getFrame();
+            f.setTitle(FRAME_TITLE);
+            f.getContentPane().add(this, BorderLayout.CENTER);
+            f.pack();
+
+            Rectangle screenRect = f.getGraphicsConfiguration().getBounds();
+            Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets(
+                    f.getGraphicsConfiguration());
+
+            // Make sure we don't place the demo off the screen.
+            int centerWidth = screenRect.width < f.getSize().width ?
+                    screenRect.x :
+                    screenRect.x + screenRect.width/2 - f.getSize().width/2;
+            int centerHeight = screenRect.height < f.getSize().height ?
+                    screenRect.y :
+                    screenRect.y + screenRect.height/2 - f.getSize().height/2;
+
+            centerHeight = centerHeight < screenInsets.top ?
+                    screenInsets.top : centerHeight;
+
+            f.setLocation(centerWidth, centerHeight);
+            f.show();
+            numSSs++;
+            swingSets.add(this);
+        }
+    }
+
+    // *******************************************************
+    // ****************** Utility Methods ********************
+    // *******************************************************
+
+    /**
+     * Returns the frame instance
+     */
+    public JFrame getFrame() {
+        return frame;
+    }
+
+    /**
+     * Returns the toolbar
+     */
+    public ToggleButtonToolBar getToolBar() {
+        return toolbar;
+    }
+
+    /**
+     * Returns the toolbar button group
+     */
+    public ButtonGroup getToolBarGroup() {
+        return toolbarGroup;
+    }
+
+    /**
+     * Create a frame for SwingSet2 to reside in if brought up
+     * as an application.
+     */
+    public static JFrame createFrame(GraphicsConfiguration gc) {
+        JFrame frame = new JFrame(gc);
+        if (numSSs == 0) {
+            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+        } else {
+            WindowListener l = new WindowAdapter() {
+                public void windowClosing(WindowEvent e) {
+                    numSSs--;
+                    swingSets.remove(this);
+                }
+            };
+            frame.addWindowListener(l);
+        }
+        return frame;
+    }
+
+    /**
+     * Set the status
+     */
+    public void setStatus(String s) {
+        // do the following on the gui thread
+        SwingUtilities.invokeLater(new SwingSetRunnable(this, s) {
+            public void run() {
+                swingset.statusField.setText((String) obj);
+            }
+        });
+    }
+
+    /**
+     * This method returns a string from the demo's resource bundle.
+     */
+    public static String getString(String key) {
+        String value = null;
+        try {
+            value = TextAndMnemonicUtils.getTextAndMnemonicString(key);
+        } catch (MissingResourceException e) {
+            System.out.println("java.util.MissingResourceException: Couldn't find value for: " + key);
+        }
+        if(value == null) {
+            value = "Could not find resource: " + key + "  ";
+        }
+        return value;
+    }
+
+    void setDragEnabled(boolean dragEnabled) {
+        if (dragEnabled == this.dragEnabled) {
+            return;
+        }
+
+        this.dragEnabled = dragEnabled;
+
+        for (DemoModule dm : demosList) {
+            dm.updateDragEnabled(dragEnabled);
+        }
+
+        demoSrcPane.setDragEnabled(dragEnabled);
+    }
+
+    /**
+     * Returns a mnemonic from the resource bundle. Typically used as
+     * keyboard shortcuts in menu items.
+     */
+    public char getMnemonic(String key) {
+        return (getString(key)).charAt(0);
+    }
+
+    /**
+     * Creates an icon from an image contained in the "images" directory.
+     */
+    public ImageIcon createImageIcon(String filename, String description) {
+        String path = "/resources/images/" + filename;
+        return new ImageIcon(getClass().getResource(path));
+    }
+
+    /**
+     * Stores the current L&F, and calls updateLookAndFeel, below
+     */
+    public void setLookAndFeel(LookAndFeelData laf) {
+        if(!currentLookAndFeel.equals(laf)) {
+            currentLookAndFeel = laf;
+            /* The recommended way of synchronizing state between multiple
+             * controls that represent the same command is to use Actions.
+             * The code below is a workaround and will be replaced in future
+             * version of SwingSet2 demo.
+             */
+            String lafName = laf.label;
+            themesMenu.setEnabled(laf.name.equals("Metal"));
+            updateLookAndFeel();
+            for(int i=0;i<lafMenu.getItemCount();i++) {
+                JMenuItem item = lafMenu.getItem(i);
+                item.setSelected(item.getText().equals(lafName));
+            }
+        }
+    }
+
+    private void updateThisSwingSet() {
+        JFrame frame = getFrame();
+        if (frame == null) {
+            SwingUtilities.updateComponentTreeUI(this);
+        } else {
+            SwingUtilities.updateComponentTreeUI(frame);
+        }
+
+        SwingUtilities.updateComponentTreeUI(popupMenu);
+        if (aboutBox != null) {
+            SwingUtilities.updateComponentTreeUI(aboutBox);
+        }
+    }
+
+    /**
+     * Sets the current L&F on each demo module
+     */
+    public void updateLookAndFeel() {
+        try {
+            UIManager.setLookAndFeel(currentLookAndFeel.className);
+            for (SwingSet2 ss : swingSets) {
+                ss.updateThisSwingSet();
+            }
+        } catch (Exception ex) {
+            System.out.println("Failed loading L&F: " + currentLookAndFeel);
+            System.out.println(ex);
+        }
+    }
+
+    /**
+     * Loads and puts the source code text into JEditorPane in the "Source Code" tab
+     */
+    public void setSourceCode(DemoModule demo) {
+        // do the following on the gui thread
+        SwingUtilities.invokeLater(new SwingSetRunnable(this, demo) {
+            public void run() {
+                swingset.demoSrcPane.setText(((DemoModule)obj).getSourceCode());
+                swingset.demoSrcPane.setCaretPosition(0);
+
+            }
+        });
+    }
+
+    // *******************************************************
+    // **************   ToggleButtonToolbar  *****************
+    // *******************************************************
+    static Insets zeroInsets = new Insets(1,1,1,1);
+    protected class ToggleButtonToolBar extends JToolBar {
+        public ToggleButtonToolBar() {
+            super();
+        }
+
+        JToggleButton addToggleButton(Action a) {
+            JToggleButton tb = new JToggleButton(
+                (String)a.getValue(Action.NAME),
+                (Icon)a.getValue(Action.SMALL_ICON)
+            );
+            tb.setName((String)a.getValue(Action.NAME));
+            tb.setMargin(zeroInsets);
+            tb.setText(null);
+            tb.setEnabled(a.isEnabled());
+            tb.setToolTipText((String)a.getValue(Action.SHORT_DESCRIPTION));
+            tb.setAction(a);
+            add(tb);
+            return tb;
+        }
+    }
+
+    // *******************************************************
+    // *********  ToolBar Panel / Docking Listener ***********
+    // *******************************************************
+    class ToolBarPanel extends JPanel implements ContainerListener {
+
+        public boolean contains(int x, int y) {
+            Component c = getParent();
+            if (c != null) {
+                Rectangle r = c.getBounds();
+                return (x >= 0) && (x < r.width) && (y >= 0) && (y < r.height);
+            }
+            else {
+                return super.contains(x,y);
+            }
+        }
+
+        public void componentAdded(ContainerEvent e) {
+            Container c = e.getContainer().getParent();
+            if (c != null) {
+                c.getParent().validate();
+                c.getParent().repaint();
+            }
+        }
+
+        public void componentRemoved(ContainerEvent e) {
+            Container c = e.getContainer().getParent();
+            if (c != null) {
+                c.getParent().validate();
+                c.getParent().repaint();
+            }
+        }
+    }
+
+    // *******************************************************
+    // ******************   Runnables  ***********************
+    // *******************************************************
+
+    /**
+     * Generic SwingSet2 runnable. This is intended to run on the
+     * AWT gui event thread so as not to muck things up by doing
+     * gui work off the gui thread. Accepts a SwingSet2 and an Object
+     * as arguments, which gives subtypes of this class the two
+     * "must haves" needed in most runnables for this demo.
+     */
+    class SwingSetRunnable implements Runnable {
+        protected SwingSet2 swingset;
+        protected Object obj;
+
+        public SwingSetRunnable(SwingSet2 swingset, Object obj) {
+            this.swingset = swingset;
+            this.obj = obj;
+        }
+
+        public void run() {
+        }
+    }
+
+
+    // *******************************************************
+    // ********************   Actions  ***********************
+    // *******************************************************
+
+    public class SwitchToDemoAction extends AbstractAction {
+        SwingSet2 swingset;
+        DemoModule demo;
+
+        public SwitchToDemoAction(SwingSet2 swingset, DemoModule demo) {
+            super(demo.getName(), demo.getIcon());
+            this.swingset = swingset;
+            this.demo = demo;
+        }
+
+        public void actionPerformed(ActionEvent e) {
+            swingset.setDemo(demo);
+        }
+    }
+
+    class OkAction extends AbstractAction {
+        JDialog aboutBox;
+
+        protected OkAction(JDialog aboutBox) {
+            super("OkAction");
+            this.aboutBox = aboutBox;
+        }
+
+        public void actionPerformed(ActionEvent e) {
+            aboutBox.setVisible(false);
+        }
+    }
+
+    class ChangeLookAndFeelAction extends AbstractAction {
+        SwingSet2 swingset;
+        LookAndFeelData lafData;
+        protected ChangeLookAndFeelAction(SwingSet2 swingset, LookAndFeelData lafData) {
+            super("ChangeTheme");
+            this.swingset = swingset;
+            this.lafData = lafData;
+        }
+
+        public void actionPerformed(ActionEvent e) {
+            swingset.setLookAndFeel(lafData);
+        }
+    }
+
+    class ActivatePopupMenuAction extends AbstractAction {
+        SwingSet2 swingset;
+        JPopupMenu popup;
+        protected ActivatePopupMenuAction(SwingSet2 swingset, JPopupMenu popup) {
+            super("ActivatePopupMenu");
+            this.swingset = swingset;
+            this.popup = popup;
+        }
+
+        public void actionPerformed(ActionEvent e) {
+            Dimension invokerSize = getSize();
+            Dimension popupSize = popup.getPreferredSize();
+            popup.show(swingset, (invokerSize.width - popupSize.width) / 2,
+                       (invokerSize.height - popupSize.height) / 2);
+        }
+    }
+
+    // Turns on all possible auditory feedback
+    class OnAudioAction extends AbstractAction {
+        SwingSet2 swingset;
+        protected OnAudioAction(SwingSet2 swingset) {
+            super("Audio On");
+            this.swingset = swingset;
+        }
+        public void actionPerformed(ActionEvent e) {
+            UIManager.put("AuditoryCues.playList",
+                          UIManager.get("AuditoryCues.allAuditoryCues"));
+            swingset.updateLookAndFeel();
+        }
+    }
+
+    // Turns on the default amount of auditory feedback
+    class DefaultAudioAction extends AbstractAction {
+        SwingSet2 swingset;
+        protected DefaultAudioAction(SwingSet2 swingset) {
+            super("Audio Default");
+            this.swingset = swingset;
+        }
+        public void actionPerformed(ActionEvent e) {
+            UIManager.put("AuditoryCues.playList",
+                          UIManager.get("AuditoryCues.defaultCueList"));
+            swingset.updateLookAndFeel();
+        }
+    }
+
+    // Turns off all possible auditory feedback
+    class OffAudioAction extends AbstractAction {
+        SwingSet2 swingset;
+        protected OffAudioAction(SwingSet2 swingset) {
+            super("Audio Off");
+            this.swingset = swingset;
+        }
+        public void actionPerformed(ActionEvent e) {
+            UIManager.put("AuditoryCues.playList",
+                          UIManager.get("AuditoryCues.noAuditoryCues"));
+            swingset.updateLookAndFeel();
+        }
+    }
+
+    // Turns on or off the tool tips for the demo.
+    class ToolTipAction extends AbstractAction {
+        protected ToolTipAction() {
+            super("ToolTip Control");
+        }
+
+        public void actionPerformed(ActionEvent e) {
+            boolean status = ((JCheckBoxMenuItem)e.getSource()).isSelected();
+            ToolTipManager.sharedInstance().setEnabled(status);
+        }
+    }
+
+    class DragSupportAction extends AbstractAction {
+        protected DragSupportAction() {
+            super("DragSupport Control");
+        }
+
+        public void actionPerformed(ActionEvent e) {
+            boolean dragEnabled = ((JCheckBoxMenuItem)e.getSource()).isSelected();
+            for (SwingSet2 ss : swingSets) {
+                ss.setDragEnabled(dragEnabled);
+            }
+        }
+    }
+
+    class ChangeThemeAction extends AbstractAction {
+        SwingSet2 swingset;
+        MetalTheme theme;
+        protected ChangeThemeAction(SwingSet2 swingset, MetalTheme theme) {
+            super("ChangeTheme");
+            this.swingset = swingset;
+            this.theme = theme;
+        }
+
+        public void actionPerformed(ActionEvent e) {
+            MetalLookAndFeel.setCurrentTheme(theme);
+            swingset.updateLookAndFeel();
+        }
+    }
+
+    class ExitAction extends AbstractAction {
+        SwingSet2 swingset;
+        protected ExitAction(SwingSet2 swingset) {
+            super("ExitAction");
+            this.swingset = swingset;
+        }
+
+        public void actionPerformed(ActionEvent e) {
+            System.exit(0);
+        }
+    }
+
+    class AboutAction extends AbstractAction {
+        SwingSet2 swingset;
+        protected AboutAction(SwingSet2 swingset) {
+            super("AboutAction");
+            this.swingset = swingset;
+        }
+
+        public void actionPerformed(ActionEvent e) {
+            if(aboutBox == null) {
+                // JPanel panel = new JPanel(new BorderLayout());
+                JPanel panel = new AboutPanel(swingset);
+                panel.setLayout(new BorderLayout());
+
+                aboutBox = new JDialog(swingset.getFrame(), getString("AboutBox.title"), false);
+                aboutBox.setResizable(false);
+                aboutBox.getContentPane().add(panel, BorderLayout.CENTER);
+
+                // JButton button = new JButton(getString("AboutBox.ok_button_text"));
+                JPanel buttonpanel = new JPanel();
+                buttonpanel.setBorder(new javax.swing.border.EmptyBorder(0, 0, 3, 0));
+                buttonpanel.setOpaque(false);
+                JButton button = (JButton) buttonpanel.add(
+                    new JButton(getString("AboutBox.ok_button_text"))
+                );
+                panel.add(buttonpanel, BorderLayout.SOUTH);
+
+                button.addActionListener(new OkAction(aboutBox));
+            }
+            aboutBox.pack();
+            aboutBox.setLocationRelativeTo(getFrame());
+            aboutBox.show();
+        }
+    }
+
+    class MultiScreenAction extends AbstractAction {
+        static final int ALL_SCREENS = -1;
+        int screen;
+        protected MultiScreenAction(SwingSet2 swingset, int screen) {
+            super("MultiScreenAction");
+            this.screen = screen;
+        }
+
+        public void actionPerformed(ActionEvent e) {
+            GraphicsDevice[] gds = GraphicsEnvironment.
+                                   getLocalGraphicsEnvironment().
+                                   getScreenDevices();
+            if (screen == ALL_SCREENS) {
+                for (int i = 0; i < gds.length; i++) {
+                    SwingSet2 swingset = new SwingSet2(
+                                  gds[i].getDefaultConfiguration());
+                    swingset.setDragEnabled(dragEnabled);
+                }
+            }
+            else {
+                SwingSet2 swingset = new SwingSet2(
+                             gds[screen].getDefaultConfiguration());
+                swingset.setDragEnabled(dragEnabled);
+            }
+        }
+    }
+
+    // *******************************************************
+    // **********************  Misc  *************************
+    // *******************************************************
+
+    class AboutPanel extends JPanel {
+        ImageIcon aboutimage = null;
+        SwingSet2 swingset = null;
+
+        public AboutPanel(SwingSet2 swingset) {
+            this.swingset = swingset;
+            aboutimage = swingset.createImageIcon("About.jpg", "AboutBox.accessible_description");
+            setOpaque(false);
+        }
+
+        public void paint(Graphics g) {
+            aboutimage.paintIcon(this, g, 0, 0);
+            super.paint(g);
+        }
+
+        public Dimension getPreferredSize() {
+            return new Dimension(aboutimage.getIconWidth(),
+                                 aboutimage.getIconHeight());
+        }
+    }
+
+    private class ChangeFontAction extends AbstractAction {
+        private SwingSet2 swingset;
+        private boolean plain;
+
+        ChangeFontAction(SwingSet2 swingset, boolean plain) {
+            super("FontMenu");
+            this.swingset = swingset;
+            this.plain = plain;
+        }
+
+        public void actionPerformed(ActionEvent e) {
+            if (plain) {
+                UIManager.put("swing.boldMetal", Boolean.FALSE);
+            }
+            else {
+                UIManager.put("swing.boldMetal", Boolean.TRUE);
+            }
+            // Change the look and feel to force the settings to take effect.
+            updateLookAndFeel();
+        }
+    }
+
+    private static LookAndFeelData[] getInstalledLookAndFeelData() {
+        return Arrays.stream(UIManager.getInstalledLookAndFeels())
+                .map(laf -> getLookAndFeelData(laf))
+                .toArray(LookAndFeelData[]::new);
+    }
+
+    private static LookAndFeelData getLookAndFeelData(
+            UIManager.LookAndFeelInfo info) {
+        switch (info.getName()) {
+            case "Metal":
+                return new LookAndFeelData(info, "java");
+            case "Nimbus":
+                return new LookAndFeelData(info, "nimbus");
+            case "Windows":
+                return new LookAndFeelData(info, "windows");
+            case "GTK+":
+                return new LookAndFeelData(info, "gtk");
+            case "CDE/Motif":
+                return new LookAndFeelData(info, "motif");
+            case "Mac OS X":
+                return new LookAndFeelData(info, "mac");
+            default:
+                return new LookAndFeelData(info);
+        }
+    }
+
+    private static class LookAndFeelData {
+        String name;
+        String className;
+        String label;
+        char mnemonic;
+        String accDescription;
+
+        public LookAndFeelData(UIManager.LookAndFeelInfo info) {
+            this(info.getName(), info.getClassName(), info.getName(),
+                 info.getName(), info.getName());
+        }
+
+        public LookAndFeelData(UIManager.LookAndFeelInfo info, String property) {
+            this(info.getName(), info.getClassName(),
+                    getString(String.format("LafMenu.%s_label", property)),
+                    getString(String.format("LafMenu.%s_mnemonic", property)),
+                    getString(String.format("LafMenu.%s_accessible_description",
+                                    property)));
+        }
+
+        public LookAndFeelData(String name, String className, String label,
+                               String mnemonic, String accDescription) {
+            this.name = name;
+            this.className = className;
+            this.label = label;
+            this.mnemonic = mnemonic.charAt(0);
+            this.accDescription = accDescription;
+        }
+
+        @Override
+        public String toString() {
+            return className;
+        }
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sanity/client/lib/SwingSet2/src/TextAndMnemonicUtils.java	Wed May 09 16:03:49 2018 +0530
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.IOException;
+import java.util.Properties;
+import java.util.ResourceBundle;
+
+/**
+ * <code>TextAndMnemonicUtils</code> allows to extract text and mnemonic values
+ * from the unified text & mnemonic strings. For example:
+ *   LafMenu.laf.labelAndMnemonic=&Look && Feel
+ * The extracted text is "Look & Feel" and the extracted mnemonic mnemonic is "L".
+ *
+ * There are several patterns for the text and mnemonic suffixes which are used
+ * in the resource file. The patterns format is:
+ * (resource key -> unified text & mnemonic resource key).
+ *
+ * Keys that have label suffixes:
+ * (xxx_label -> xxx.labelAndMnemonic)
+ *
+ * Keys that have mnemonic suffixes:
+ * (xxx_mnemonic -> xxx.labelAndMnemonic)
+ *
+ * Keys that do not have definite suffixes:
+ * (xxx -> xxx.labelAndMnemonic)
+ *
+ * @author Alexander Scherbatiy
+ */
+public class TextAndMnemonicUtils {
+
+    // Label suffix for the text & mnemonic resource
+    private static final String LABEL_SUFFIX = ".labelAndMnemonic";
+
+    // Resource bundle for internationalized and accessible text
+    private static ResourceBundle bundle = null;
+
+    // Resource properties for the mnemonic key defenition
+    private static Properties properties = null;
+
+    static {
+        bundle = ResourceBundle.getBundle("resources.swingset");
+        properties = new Properties();
+        try {
+            properties.load(TextAndMnemonicUtils.class.getResourceAsStream("resources/swingset.properties"));
+        } catch (IOException ex) {
+            System.out.println("java.io.IOException: Couldn't load properties from: resources/swingset.properties");
+        }
+    }
+
+    /**
+     * Returns accessible and internationalized strings or mnemonics from the
+     * resource bundle. The key is converted to the text & mnemonic key.
+     *
+     * The following patterns are checked:
+     * Keys that have label suffixes:
+     * (xxx_label -> xxx.labelAndMnemonic)
+     *
+     * Keys that have mnemonic suffixes:
+     * (xxx_mnemonic -> xxx.labelAndMnemonic)
+     *
+     * Keys that do not have definite suffixes:
+     * (xxx -> xxx.labelAndMnemonic)
+     *
+     * Properties class is used to check if a key created for mnemonic exists.
+     */
+    public static String getTextAndMnemonicString(String key) {
+
+        if (key.endsWith("_label")) {
+            String compositeKey = composeKey(key, 6, LABEL_SUFFIX);
+            String textAndMnemonic = bundle.getString(compositeKey);
+            return getTextFromTextAndMnemonic(textAndMnemonic);
+        }
+
+        if (key.endsWith("_mnemonic")) {
+
+            String compositeKey = composeKey(key, 9, LABEL_SUFFIX);
+            Object value = properties.getProperty(compositeKey);
+
+            if (value != null) {
+                String textAndMnemonic = bundle.getString(compositeKey);
+                return getMnemonicFromTextAndMnemonic(textAndMnemonic);
+            }
+
+        }
+
+        String compositeKey = composeKey(key, 0, LABEL_SUFFIX);
+        Object value = properties.getProperty(compositeKey);
+
+        if (value != null) {
+            String textAndMnemonic = bundle.getString(compositeKey);
+            return getTextFromTextAndMnemonic(textAndMnemonic);
+        }
+
+        String textAndMnemonic = bundle.getString(key);
+        return getTextFromTextAndMnemonic(textAndMnemonic);
+    }
+
+    /**
+     * Convert the text & mnemonic string to text string
+     *
+     * The '&' symbol is treated as the mnemonic pointer
+     * The double "&&" symbols are treated as the single '&'
+     *
+     * For example the string "&Look && Feel" is converted to "Look & Feel"
+     */
+    public static String getTextFromTextAndMnemonic(String text) {
+
+        StringBuilder sb = new StringBuilder();
+
+        int prevIndex = 0;
+        int nextIndex = text.indexOf('&');
+        int len = text.length();
+
+        while (nextIndex != -1) {
+
+            String s = text.substring(prevIndex, nextIndex);
+            sb.append(s);
+
+            nextIndex++;
+
+            if (nextIndex != len && text.charAt(nextIndex) == '&') {
+                sb.append('&');
+                nextIndex++;
+            }
+
+            prevIndex = nextIndex;
+            nextIndex = text.indexOf('&', nextIndex + 1);
+        }
+
+        sb.append(text.substring(prevIndex, text.length()));
+        return sb.toString();
+    }
+
+    /**
+     * Convert the text & mnemonic string to mnemonic
+     *
+     * The '&' symbol is treated the mnemonic pointer
+     * The double "&&" symbols are treated as the single '&'
+     *
+     * For example the string "&Look && Feel" is converted to "L"
+     */
+    public static String getMnemonicFromTextAndMnemonic(String text) {
+        int index = text.indexOf('&');
+
+        while (0 <= index && index < text.length() - 1) {
+            index++;
+            if (text.charAt(index) == '&') {
+                index = text.indexOf('&', index + 1);
+            } else {
+                char c = text.charAt(index);
+                return String.valueOf(Character.toUpperCase(c));
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Removes the last n characters and adds the suffix
+     */
+    private static String composeKey(String key, int reduce, String sufix) {
+        return key.substring(0, key.length() - reduce) + sufix;
+    }
+}
\ No newline at end of file
Binary file test/jdk/sanity/client/lib/SwingSet2/src/resources/images/toolbar/JOptionPane.gif has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sanity/client/lib/SwingSet2/src/resources/swingset.properties	Wed May 09 16:03:49 2018 +0530
@@ -0,0 +1,194 @@
+# This properties file is used to create a PropertyResourceBundle
+# It contains Locale specific strings used in the SwingSet demo.
+#
+# @author Jeff Dinkins
+
+#################################
+###  SwingSet Infrastructure  ###
+#################################
+
+### About Box ###
+
+AboutBox.title=About Swing!
+AboutBox.ok_button_text=OK
+AboutBox.accessible_description=SwingSet2 demo is Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+
+### Source Code ###
+SourceCode.loading=<html><body bgcolor=\"#ffffff\">Loading and formatting source code, please wait...</body></html>
+
+### Status ###
+
+Status.loading=Loading:
+Status.popupMenuAccessible=Press Shift-F10 to activate popup menu
+
+### Menu Bar ###
+
+MenuBar.accessible_description=Swing demo menu bar
+
+
+### Frame ###
+
+Frame.title=SwingSet2
+
+
+### Tabbed Pane ###
+
+TabbedPane.src.labelAndMnemonic=Source Code
+TabbedPane.src_tooltip=Look at the source code for this demo
+
+
+### Look & Feel Menu ###
+
+LafMenu.laf.labelAndMnemonic=&Look && Feel
+LafMenu.laf_accessible_description=Menu that allows Look && Feel switching
+
+LafMenu.java.labelAndMnemonic=&Java Look && Feel
+LafMenu.java_accessible_description=The Java Look && Feel
+
+LafMenu.nimbus.labelAndMnemonic=&Nimbus Look && Feel
+LafMenu.nimbus_accessible_description=The Nimbus Look && Feel
+
+LafMenu.mac.labelAndMnemonic=&Mac OS X Look && Feel
+LafMenu.mac_accessible_description=The Mac OS X Look && Feel
+
+LafMenu.motif.labelAndMnemonic=M&otif Look && Feel
+LafMenu.motif_accessible_description=The Motif Look && Feel
+
+LafMenu.windows.labelAndMnemonic=&Windows Style Look && Feel
+LafMenu.windows_accessible_description=Windows Style Look && Feel
+
+LafMenu.gtk.labelAndMnemonic=&GTK Style Look && Feel
+LafMenu.gtk_accessible_description=GTK Style Look && Feel
+
+### Themes Menu ###
+
+ThemesMenu.themes.labelAndMnemonic=&Themes
+ThemesMenu.themes_accessible_description=Menu to switch Metal color themes
+
+ThemesMenu.aqua.labelAndMnemonic=A&qua
+ThemesMenu.aqua_accessible_description=A Metal Theme that uses bluish-green colors
+
+ThemesMenu.charcoal.labelAndMnemonic=&Charcoal
+ThemesMenu.charcoal_accessible_description=A Metal Theme that uses dark grey colors
+
+ThemesMenu.contrast.labelAndMnemonic=&High Contrast
+ThemesMenu.contrast_accessible_description=A High Contrast Theme
+
+ThemesMenu.ocean.labelAndMnemonic=&Ocean
+ThemesMenu.ocean_accessible_description=The Ocean Metal Theme
+
+ThemesMenu.steel.labelAndMnemonic=&Steel
+ThemesMenu.steel_accessible_description=The blue/purple Metal Theme
+
+ThemesMenu.emerald.labelAndMnemonic=&Emerald
+ThemesMenu.emerald_accessible_description=A Metal Theme that uses green colors
+
+ThemesMenu.ruby.labelAndMnemonic=&Ruby
+ThemesMenu.ruby_accessible_description=A Metal Theme that uses red colors
+
+
+### Font SubMenu (under Themes) 
+FontMenu.fonts.labelAndMnemonic=&Fonts
+FontMenu.fonts_accessible_description=Menu to choose fonts for the Java look and feel
+
+FontMenu.bold.labelAndMnemonic=&Bold
+FontMenu.bold_accessible_description=Turns on bold fonts for the Java look and feel
+
+FontMenu.plain.labelAndMnemonic=&Plain
+FontMenu.plain_accessible_description=Turns on plain fonts for the Java look and feel
+
+
+### Audio SubMenu (under Themes) ###
+
+AudioMenu.audio.labelAndMnemonic=&Audio
+AudioMenu.audio_accessible_description=Menu to switch the amount of auditory feedback available within the Java look and feel
+
+AudioMenu.on.labelAndMnemonic=&On
+AudioMenu.on_accessible_description=Turn on all auditory feedback for the Java look and feel
+
+AudioMenu.default.labelAndMnemonic=&Default
+AudioMenu.default_accessible_description=Turn on the standard amount of auditory feedback for the Java look and feel
+
+AudioMenu.off.labelAndMnemonic=O&ff
+AudioMenu.off_accessible_description=Turn off all auditory feedback for the Java look and feel
+
+### Options Menu ###
+
+OptionsMenu.options.labelAndMnemonic=O&ptions
+OptionsMenu.options_accessible_description=Menu containing other options
+
+OptionsMenu.tooltip.labelAndMnemonic=Enable &Tool Tips
+OptionsMenu.tooltip_accessible_description=Enable or disable tool tips
+
+OptionsMenu.dragEnabled.labelAndMnemonic=Enable &Drag Support
+OptionsMenu.dragEnabled_accessible_description=Enable or disable drag support
+
+### File Menu ###
+
+FileMenu.file.labelAndMnemonic=&File
+FileMenu.accessible_description=File Menu
+FileMenu.about.labelAndMnemonic=A&bout
+FileMenu.about_accessible_description=Find out about the SwingSet2 application
+FileMenu.open.labelAndMnemonic=&Open
+FileMenu.open_accessible_description=Placeholder menu item for opening a file
+FileMenu.save.labelAndMnemonic=&Save
+FileMenu.save_accessible_description=Placeholder menu item for saving a file
+FileMenu.save_as.labelAndMnemonic=Save &As...
+FileMenu.save_as_accessible_description=Placeholder menu item for saving a file with a new name
+FileMenu.exit.labelAndMnemonic=E&xit
+FileMenu.exit_accessible_description=Exit the SwingSet2 application
+
+### Multi-Screen menu ###
+MultiMenu.multi.labelAndMnemonic=&Multiscreen
+MultiMenu.multi_accessible_description=Multiscreen Menu
+MultiMenu.all.labelAndMnemonic=Cre&ate SwingSet2 on all screens
+MultiMenu.all_accessible_description=Create a SwingSet2 window on every screen
+MultiMenu.single.labelAndMnemonic=Create SwingSet2 on screen
+MultiMenu.single_accessible_description=Create a SwingSet2 window on screen
+
+
+################################
+###          DEMOS           ###
+################################
+### OptionPane Demo ###
+
+OptionPaneDemo.accessible_description=The OptionPane Demo shows examples of using JOptionPane to generate different common option dialog boxes
+OptionPaneDemo.tooltip=JOptionPane Demo
+OptionPaneDemo.name=Option Pane Demo
+
+OptionPaneDemo.warningbutton=Show Warning Dialog
+OptionPaneDemo.componentbutton=Show Component Dialog
+OptionPaneDemo.inputbutton=Show Input Dialog
+OptionPaneDemo.confirmbutton=Show Confirmation Dialog
+OptionPaneDemo.messagebutton=Show Message Dialog
+
+OptionPaneDemo.warningtitle=Warning Dialog Example
+OptionPaneDemo.warningtext=<html><P><font color=black>This is a test of the <font color=red><b>Emergency Broadcast System</b></font>. <i><b>This is <br> only a test</b></i>.  The webmaster of your local intranet, in voluntary <br> cooperation with the <font color=blue><b>Federal</b></font> and <font color=blue><b>State</b></font> authorities, have <br> developed this system to keep you informed in the event of an <br> emergency. If this had been an actual emergency, the signal you <br> just heard would have been followed by official information, news <br> or instructions. This concludes this test of the <font color=red><b>Emergency <br> Broadcast System</b></font>.</font></P><P><br>Developer Note: This dialog demo used HTML for text formatting.</P></html>
+
+OptionPaneDemo.messagetext=Message in a Bottle (yeah)
+
+OptionPaneDemo.confirmquestion=Is the sun shining outside today?
+OptionPaneDemo.confirmyes=<html>Well what are you doing playing on the computer?<br> Get outside! Take a trip to the beach! Get a little sun!</html>
+OptionPaneDemo.confirmno=Well good thing you're inside protected from the elements!
+
+OptionPaneDemo.inputquestion=What is your favorite movie?
+OptionPaneDemo.inputresponse=That was a pretty good movie!
+
+OptionPaneDemo.componenttitle=Component Dialog Example
+OptionPaneDemo.componentmessage=<html>JOptionPane can contain as many components <br> as you want, such as a text field:</html>
+OptionPaneDemo.componenttextfield=or a combobox:
+OptionPaneDemo.component_cb1=item 1
+OptionPaneDemo.component_cb2=item 2
+OptionPaneDemo.component_cb3=item 3
+OptionPaneDemo.componentmessage2=<html>JOptionPane can also show as many options <br> as you want:</html>
+OptionPaneDemo.component_op1=Yes
+OptionPaneDemo.component_op2=No
+OptionPaneDemo.component_op3=Maybe
+OptionPaneDemo.component_op4=Probably
+OptionPaneDemo.component_op5=Cancel
+
+OptionPaneDemo.component_r1=Upbeat and positive! I like that! Good choice.
+OptionPaneDemo.component_r2=Definitely not, I wouldn't do it either.
+OptionPaneDemo.component_r3=<html><font color=black> Mmmm.. yes, the situation is unclear at this <br> time. Check back when you know for sure.</font></html>
+OptionPaneDemo.component_r4=<html><font color=black>You know you want to. I think you should <br> have gone for broke and pressed "Yes".</font></html>
+