home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / JBuilder8.iso / Solaris / resource / jre / demo / jfc / SwingSet2 / src / SwingSet2.java < prev    next >
Encoding:
Java Source  |  2002-09-06  |  38.9 KB  |  1,248 lines

  1. /*
  2.  * Copyright (c) 2002 Sun Microsystems, Inc. All  Rights Reserved.
  3.  * 
  4.  * Redistribution and use in source and binary forms, with or without
  5.  * modification, are permitted provided that the following conditions
  6.  * are met:
  7.  * 
  8.  * -Redistributions of source code must retain the above copyright
  9.  *  notice, this list of conditions and the following disclaimer.
  10.  * 
  11.  * -Redistribution in binary form must reproduct the above copyright
  12.  *  notice, this list of conditions and the following disclaimer in
  13.  *  the documentation and/or other materials provided with the distribution.
  14.  * 
  15.  * Neither the name of Sun Microsystems, Inc. or the names of contributors
  16.  * may be used to endorse or promote products derived from this software
  17.  * without specific prior written permission.
  18.  * 
  19.  * This software is provided "AS IS," without a warranty of any kind. ALL
  20.  * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
  21.  * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
  22.  * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT
  23.  * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT
  24.  * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS
  25.  * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
  26.  * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
  27.  * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
  28.  * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN
  29.  * IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
  30.  * 
  31.  * You acknowledge that Software is not designed, licensed or intended for
  32.  * use in the design, construction, operation or maintenance of any nuclear
  33.  * facility.
  34.  */
  35.  
  36. /*
  37.  * @(#)SwingSet2.java    1.32 02/06/13
  38.  */
  39.  
  40. import javax.swing.*;
  41. import javax.swing.event.*;
  42. import javax.swing.text.*;
  43. import javax.swing.border.*;
  44. import javax.swing.colorchooser.*;
  45. import javax.swing.filechooser.*;
  46. import javax.accessibility.*;
  47.  
  48. import javax.swing.plaf.metal.DefaultMetalTheme;
  49. import javax.swing.plaf.metal.MetalLookAndFeel;
  50.  
  51. import java.lang.reflect.*;
  52. import java.awt.*;
  53. import java.awt.event.*;
  54. import java.beans.*;
  55. import java.util.*;
  56. import java.io.*;
  57. import java.applet.*;
  58. import java.net.*;
  59.  
  60. /**
  61.  * A demo that shows all of the Swing components.
  62.  *
  63.  * @version 1.32 06/13/02
  64.  * @author Jeff Dinkins
  65.  */
  66. public class SwingSet2 extends JPanel {
  67.  
  68.     String[] demos = {
  69.       "ButtonDemo",
  70.       "ColorChooserDemo",
  71.       "ComboBoxDemo",
  72.       "FileChooserDemo",
  73.       "HtmlDemo",
  74.       "ListDemo",
  75.       "OptionPaneDemo",
  76.       "ProgressBarDemo",
  77.       "ScrollPaneDemo",
  78.       "SliderDemo",
  79.       "SplitPaneDemo",
  80.       "TabbedPaneDemo",
  81.       "TableDemo",
  82.       "ToolTipDemo",
  83.       "TreeDemo"
  84.     };
  85.  
  86.     void loadDemos() {
  87.     for(int i = 0; i < demos.length;) {
  88.             if(isApplet() && demos[i].equals("FileChooserDemo")) {
  89.            // don't load the file chooser demo if we are
  90.                // an applet
  91.         } else {
  92.            loadDemo(demos[i]);
  93.             }
  94.         i++;
  95.     }
  96.     }
  97.  
  98.     // Possible Look & Feels
  99.     private static final String mac      =
  100.             "com.sun.java.swing.plaf.mac.MacLookAndFeel";
  101.     private static final String metal    =
  102.             "javax.swing.plaf.metal.MetalLookAndFeel";
  103.     private static final String motif    =
  104.             "com.sun.java.swing.plaf.motif.MotifLookAndFeel";
  105.     private static final String windows  =
  106.             "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
  107.  
  108.     // The current Look & Feel
  109.     private static String currentLookAndFeel = metal;
  110.  
  111.     // List of demos
  112.     private Vector demosVector = new Vector();
  113.  
  114.     // The preferred size of the demo
  115.     private static final int PREFERRED_WIDTH = 720;
  116.     private static final int PREFERRED_HEIGHT = 640;
  117.     
  118.     // Box spacers
  119.     private Dimension HGAP = new Dimension(1,5);
  120.     private Dimension VGAP = new Dimension(5,1);
  121.  
  122.     // Resource bundle for internationalized and accessible text
  123.     private ResourceBundle bundle = null;
  124.  
  125.     // A place to hold on to the visible demo
  126.     private DemoModule currentDemo = null;
  127.     private JPanel demoPanel = null;
  128.  
  129.     // About Box
  130.     private JDialog aboutBox = null;
  131.  
  132.     // Status Bar
  133.     private JTextField statusField = null;
  134.  
  135.     // Tool Bar
  136.     private ToggleButtonToolBar toolbar = null;
  137.     private ButtonGroup toolbarGroup = new ButtonGroup();
  138.  
  139.     // Menus
  140.     private JMenuBar menuBar = null;
  141.     private JMenu lafMenu = null;
  142.     private JMenu themesMenu = null;
  143.     private JMenu audioMenu = null;
  144.     private JMenu toolTipMenu = null;
  145.     private ButtonGroup lafMenuGroup = new ButtonGroup();
  146.     private ButtonGroup themesMenuGroup = new ButtonGroup();
  147.     private ButtonGroup audioMenuGroup = new ButtonGroup();
  148.     private ButtonGroup toolTipMenuGroup = new ButtonGroup();
  149.  
  150.     // Used only if swingset is an application 
  151.     private JFrame frame = null;
  152.     private JWindow splashScreen = null;
  153.  
  154.     // Used only if swingset is an applet 
  155.     private SwingSet2Applet applet = null;
  156.  
  157.     // To debug or not to debug, that is the question
  158.     private boolean DEBUG = true;
  159.     private int debugCounter = 0;
  160.  
  161.     // The tab pane that holds the demo
  162.     private JTabbedPane tabbedPane = null;
  163.  
  164.     private JEditorPane demoSrcPane = null;
  165.  
  166.     private JLabel splashLabel = null;
  167.  
  168.     // contentPane cache, saved from the applet or application frame
  169.     Container contentPane = null;
  170.  
  171.  
  172.     // number of swingsets - for multiscreen
  173.     // keep track of the number of SwingSets created - we only want to exit
  174.     // the program when the last one has been closed.
  175.     private static int numSSs = 0;
  176.     private static Vector swingSets = new Vector();
  177.  
  178.     public SwingSet2(SwingSet2Applet applet) {
  179.         this(applet, null);
  180.     }
  181.  
  182.     /**
  183.      * SwingSet2 Constructor
  184.      */
  185.     public SwingSet2(SwingSet2Applet applet, GraphicsConfiguration gc) {
  186.  
  187.     // Note that the applet may null if this is started as an application
  188.     this.applet = applet;
  189.  
  190.     // Create Frame here for app-mode so the splash screen can get the
  191.     // GraphicsConfiguration from it in createSplashScreen()
  192.     if (!isApplet()) {
  193.         frame = createFrame(gc);
  194.     }
  195.  
  196.     // setLayout(new BorderLayout());
  197.     setLayout(new BorderLayout());
  198.  
  199.     // set the preferred size of the demo
  200.     setPreferredSize(new Dimension(PREFERRED_WIDTH,PREFERRED_HEIGHT));
  201.  
  202.     // Create and throw the splash screen up. Since this will
  203.     // physically throw bits on the screen, we need to do this
  204.     // on the GUI thread using invokeLater.
  205.     createSplashScreen();
  206.  
  207.     // do the following on the gui thread
  208.     SwingUtilities.invokeLater(new Runnable() {
  209.         public void run() {
  210.         showSplashScreen();
  211.         }
  212.     });
  213.         
  214.     initializeDemo();
  215.     preloadFirstDemo();
  216.  
  217.     // Show the demo and take down the splash screen. Note that
  218.     // we again must do this on the GUI thread using invokeLater.
  219.     SwingUtilities.invokeLater(new Runnable() {
  220.         public void run() {
  221.         showSwingSet2();
  222.         hideSplash();
  223.         }
  224.     });
  225.  
  226.     // Start loading the rest of the demo in the background
  227.     DemoLoadThread demoLoader = new DemoLoadThread(this);
  228.     demoLoader.start();
  229.     }
  230.  
  231.  
  232.     /**
  233.      * SwingSet2 Main. Called only if we're an application, not an applet.
  234.      */
  235.     public static void main(String[] args) {
  236.     // Create SwingSet on the default monitor
  237.     SwingSet2 swingset = new SwingSet2(null, GraphicsEnvironment.
  238.                                              getLocalGraphicsEnvironment().
  239.                                              getDefaultScreenDevice().
  240.                                              getDefaultConfiguration());
  241.     }
  242.  
  243.     // *******************************************************
  244.     // *************** Demo Loading Methods ******************
  245.     // *******************************************************
  246.     
  247.     
  248.     
  249.     public void initializeDemo() {
  250.     JPanel top = new JPanel();
  251.     top.setLayout(new BorderLayout());
  252.     add(top, BorderLayout.NORTH);
  253.  
  254.     menuBar = createMenus();
  255.     top.add(menuBar, BorderLayout.NORTH);
  256.  
  257.     ToolBarPanel toolbarPanel = new ToolBarPanel();
  258.     toolbarPanel.setLayout(new BorderLayout());
  259.     toolbar = new ToggleButtonToolBar();
  260.     toolbarPanel.add(toolbar, BorderLayout.CENTER);
  261.     top.add(toolbarPanel, BorderLayout.SOUTH);
  262.     toolbarPanel.addContainerListener(toolbarPanel);
  263.  
  264.     tabbedPane = new JTabbedPane();
  265.     add(tabbedPane, BorderLayout.CENTER);
  266.     tabbedPane.getModel().addChangeListener(new TabListener());
  267.  
  268.     statusField = new JTextField("");
  269.     statusField.setEditable(false);
  270.     add(statusField, BorderLayout.SOUTH);
  271.     
  272.     demoPanel = new JPanel();
  273.     demoPanel.setLayout(new BorderLayout());
  274.     demoPanel.setBorder(new EtchedBorder());
  275.     tabbedPane.addTab("Hi There!", demoPanel);
  276.     
  277.     // Add html src code viewer 
  278.     demoSrcPane = new JEditorPane("text/html", getString("SourceCode.loading"));
  279.     demoSrcPane.setEditable(false);
  280.     
  281.     JScrollPane scroller = new JScrollPane();
  282.     scroller.getViewport().add(demoSrcPane);
  283.     
  284.     tabbedPane.addTab(
  285.         getString("TabbedPane.src_label"),
  286.         null,
  287.         scroller,
  288.         getString("TabbedPane.src_tooltip")
  289.     );
  290.     }
  291.  
  292.     DemoModule currentTabDemo = null;
  293.     class TabListener implements ChangeListener {
  294.     public void stateChanged(ChangeEvent e) {
  295.         SingleSelectionModel model = (SingleSelectionModel) e.getSource();
  296.         boolean srcSelected = model.getSelectedIndex() == 1;
  297.         if(currentTabDemo != currentDemo && demoSrcPane != null && srcSelected) {
  298.         demoSrcPane.setText(getString("SourceCode.loading"));
  299.         repaint();
  300.         }
  301.         if(currentTabDemo != currentDemo && srcSelected) {
  302.         currentTabDemo = currentDemo;
  303.         setSourceCode(currentDemo);
  304.         } 
  305.     }
  306.     }
  307.  
  308.  
  309.     /**
  310.      * Create menus
  311.      */
  312.     public JMenuBar createMenus() {
  313.     JMenuItem mi;
  314.     // ***** create the menubar ****
  315.     JMenuBar menuBar = new JMenuBar();
  316.     menuBar.getAccessibleContext().setAccessibleName(
  317.         getString("MenuBar.accessible_description"));
  318.  
  319.     // ***** create File menu 
  320.     JMenu fileMenu = (JMenu) menuBar.add(new JMenu(getString("FileMenu.file_label")));
  321.         fileMenu.setMnemonic(getMnemonic("FileMenu.file_mnemonic"));
  322.     fileMenu.getAccessibleContext().setAccessibleDescription(getString("FileMenu.accessible_description"));
  323.  
  324.     createMenuItem(fileMenu, "FileMenu.about_label", "FileMenu.about_mnemonic",
  325.                "FileMenu.about_accessible_description", new AboutAction(this));
  326.  
  327.         fileMenu.addSeparator();
  328.  
  329.     createMenuItem(fileMenu, "FileMenu.open_label", "FileMenu.open_mnemonic",
  330.                "FileMenu.open_accessible_description", null);
  331.  
  332.     createMenuItem(fileMenu, "FileMenu.save_label", "FileMenu.save_mnemonic",
  333.                "FileMenu.save_accessible_description", null);
  334.  
  335.     createMenuItem(fileMenu, "FileMenu.save_as_label", "FileMenu.save_as_mnemonic",
  336.                "FileMenu.save_as_accessible_description", null);
  337.  
  338.  
  339.     if(!isApplet()) {
  340.         fileMenu.addSeparator();
  341.         
  342.         createMenuItem(fileMenu, "FileMenu.exit_label", "FileMenu.exit_mnemonic",
  343.                "FileMenu.exit_accessible_description", new ExitAction(this)
  344.         );
  345.     }
  346.  
  347.         // Create these menu items for the first SwingSet only.
  348.         if (numSSs == 0) {
  349.     // ***** create laf switcher menu 
  350.     lafMenu = (JMenu) menuBar.add(new JMenu(getString("LafMenu.laf_label")));
  351.         lafMenu.setMnemonic(getMnemonic("LafMenu.laf_mnemonic"));
  352.     lafMenu.getAccessibleContext().setAccessibleDescription(
  353.         getString("LafMenu.laf_accessible_description"));
  354.  
  355.     mi = createLafMenuItem(lafMenu, "LafMenu.java_label", "LafMenu.java_mnemonic",
  356.                "LafMenu.java_accessible_description", metal);
  357.     mi.setSelected(true); // this is the default l&f
  358.  
  359.     createLafMenuItem(lafMenu, "LafMenu.mac_label", "LafMenu.mac_mnemonic",
  360.                "LafMenu.mac_accessible_description", mac);
  361.  
  362.     createLafMenuItem(lafMenu, "LafMenu.motif_label", "LafMenu.motif_mnemonic",
  363.                "LafMenu.motif_accessible_description", motif);
  364.  
  365.     createLafMenuItem(lafMenu, "LafMenu.windows_label", "LafMenu.windows_mnemonic",
  366.                "LafMenu.windows_accessible_description", windows);
  367.  
  368.     // ***** create themes menu 
  369.     themesMenu = (JMenu) menuBar.add(new JMenu(getString("ThemesMenu.themes_label")));
  370.         themesMenu.setMnemonic(getMnemonic("ThemesMenu.themes_mnemonic"));
  371.     themesMenu.getAccessibleContext().setAccessibleDescription(
  372.         getString("ThemesMenu.themes_accessible_description"));
  373.  
  374.     // ***** create the audio submenu under the theme menu
  375.     audioMenu = (JMenu) themesMenu.add(new JMenu(getString("AudioMenu.audio_label")));
  376.         audioMenu.setMnemonic(getMnemonic("AudioMenu.audio_mnemonic"));
  377.     audioMenu.getAccessibleContext().setAccessibleDescription(
  378.         getString("AudioMenu.audio_accessible_description"));
  379.  
  380.     createAudioMenuItem(audioMenu, "AudioMenu.on_label",
  381.                 "AudioMenu.on_mnemonic", 
  382.                 "AudioMenu.on_accessible_description",
  383.                 new OnAudioAction(this));
  384.  
  385.     mi = createAudioMenuItem(audioMenu, "AudioMenu.default_label",
  386.                  "AudioMenu.default_mnemonic", 
  387.                  "AudioMenu.default_accessible_description",
  388.                  new DefaultAudioAction(this));
  389.     mi.setSelected(true); // This is the default feedback setting
  390.  
  391.     createAudioMenuItem(audioMenu, "AudioMenu.off_label",
  392.                 "AudioMenu.off_mnemonic", 
  393.                 "AudioMenu.off_accessible_description",
  394.                 new OffAudioAction(this));
  395.  
  396.     // *** now back to adding color/font themes to the theme menu
  397.     mi = createThemesMenuItem(themesMenu, "ThemesMenu.default_label", "ThemesMenu.default_mnemonic",
  398.                "ThemesMenu.default_accessible_description", new DefaultMetalTheme());
  399.     mi.setSelected(true); // This is the default theme
  400.     
  401.     createThemesMenuItem(themesMenu, "ThemesMenu.aqua_label", "ThemesMenu.aqua_mnemonic",
  402.                "ThemesMenu.aqua_accessible_description", new AquaTheme());
  403.  
  404.     createThemesMenuItem(themesMenu, "ThemesMenu.charcoal_label", "ThemesMenu.charcoal_mnemonic",
  405.                "ThemesMenu.charcoal_accessible_description", new CharcoalTheme());
  406.  
  407.     createThemesMenuItem(themesMenu, "ThemesMenu.contrast_label", "ThemesMenu.contrast_mnemonic",
  408.                "ThemesMenu.contrast_accessible_description", new ContrastTheme());
  409.  
  410.     createThemesMenuItem(themesMenu, "ThemesMenu.emerald_label", "ThemesMenu.emerald_mnemonic",
  411.                "ThemesMenu.emerald_accessible_description", new EmeraldTheme());
  412.  
  413.     createThemesMenuItem(themesMenu, "ThemesMenu.ruby_label", "ThemesMenu.ruby_mnemonic",
  414.                "ThemesMenu.ruby_accessible_description", new RubyTheme());
  415.  
  416.     // ***** create the tooltip menu.
  417.     toolTipMenu = (JMenu) menuBar.add(new JMenu(
  418.                 getString("ToolTipMenu.tooltip_label")));
  419.         toolTipMenu.setMnemonic(getMnemonic("ToolTipMenu.tooltip_mnemonic"));
  420.     toolTipMenu.getAccessibleContext().setAccessibleDescription(
  421.         getString("ToolTipMenu.tooltip_accessible_description"));
  422.  
  423.         // ***** create tool tip submenu items.
  424.         mi = createToolTipMenuItem(toolTipMenu, "ToolTipMenu.on_label",
  425.                 "ToolTipMenu.on_mnemonic",
  426.                 "ToolTipMenu.on_accessible_description",
  427.                 new ToolTipAction(this, true));
  428.         mi.setSelected(true);
  429.  
  430.         createToolTipMenuItem(toolTipMenu, "ToolTipMenu.off_label",
  431.                 "ToolTipMenu.off_mnemonic",
  432.                 "ToolTipMenu.off_accessible_description",
  433.                 new ToolTipAction(this, false));
  434.         }
  435.  
  436.  
  437.     // ***** create the multiscreen menu, if we have multiple screens
  438.     if (!isApplet()) {
  439.         GraphicsDevice[] screens = GraphicsEnvironment.
  440.                                     getLocalGraphicsEnvironment().
  441.                                     getScreenDevices();
  442.         if (screens.length > 1) {
  443.  
  444.             JMenu multiScreenMenu = (JMenu) menuBar.add(new JMenu(
  445.                                      getString("MultiMenu.multi_label")));
  446.  
  447.             multiScreenMenu.setMnemonic(getMnemonic("MultiMenu.multi_mnemonic"));    
  448.             multiScreenMenu.getAccessibleContext().setAccessibleDescription(
  449.              getString("MultiMenu.multi_accessible_description"));
  450.  
  451.             createMultiscreenMenuItem(multiScreenMenu, MultiScreenAction.ALL_SCREENS);
  452.             for (int i = 0; i < screens.length; i++) {
  453.                 createMultiscreenMenuItem(multiScreenMenu, i);
  454.             }
  455.         }
  456.     }
  457.  
  458.     return menuBar;
  459.     }
  460.  
  461.     /**
  462.      * Create the tool tip submenu
  463.      */
  464.     public JMenuItem createToolTipMenuItem(JMenu menu, String label,
  465.                                            String mnemonic,
  466.                                            String accessibleDescription,
  467.                                            Action action) {
  468.         JRadioButtonMenuItem mi = (JRadioButtonMenuItem)menu.add(
  469.                 new JRadioButtonMenuItem(getString(label)));
  470.         toolTipMenuGroup.add(mi);
  471.         mi.setMnemonic(getMnemonic(mnemonic));
  472.         mi.getAccessibleContext().setAccessibleDescription(getString(
  473.                 accessibleDescription));
  474.         mi.addActionListener(action);
  475.  
  476.         return mi;
  477.     }
  478.  
  479.     /**
  480.      * Create the theme's audio submenu
  481.      */
  482.     public JMenuItem createAudioMenuItem(JMenu menu, String label,
  483.                      String mnemonic,
  484.                      String accessibleDescription,
  485.                      Action action) {
  486.         JRadioButtonMenuItem mi = (JRadioButtonMenuItem) menu.add(new JRadioButtonMenuItem(getString(label)));
  487.     audioMenuGroup.add(mi);
  488.     mi.setMnemonic(getMnemonic(mnemonic));
  489.     mi.getAccessibleContext().setAccessibleDescription(getString(accessibleDescription));
  490.     mi.addActionListener(action);
  491.  
  492.     return mi;
  493.     }
  494.  
  495.     /**
  496.      * Creates a generic menu item
  497.      */
  498.     public JMenuItem createMenuItem(JMenu menu, String label, String mnemonic,
  499.                    String accessibleDescription, Action action) {
  500.         JMenuItem mi = (JMenuItem) menu.add(new JMenuItem(getString(label)));
  501.     mi.setMnemonic(getMnemonic(mnemonic));
  502.     mi.getAccessibleContext().setAccessibleDescription(getString(accessibleDescription));
  503.     mi.addActionListener(action);
  504.     if(action == null) {
  505.         mi.setEnabled(false);
  506.     }
  507.     return mi;
  508.     }
  509.  
  510.     /**
  511.      * Creates a JRadioButtonMenuItem for the Themes menu
  512.      */
  513.     public JMenuItem createThemesMenuItem(JMenu menu, String label, String mnemonic,
  514.                    String accessibleDescription, DefaultMetalTheme theme) {
  515.         JRadioButtonMenuItem mi = (JRadioButtonMenuItem) menu.add(new JRadioButtonMenuItem(getString(label)));
  516.     themesMenuGroup.add(mi);
  517.     mi.setMnemonic(getMnemonic(mnemonic));
  518.     mi.getAccessibleContext().setAccessibleDescription(getString(accessibleDescription));
  519.     mi.addActionListener(new ChangeThemeAction(this, theme));
  520.  
  521.     return mi;
  522.     }
  523.  
  524.     /**
  525.      * Creates a JRadioButtonMenuItem for the Look and Feel menu
  526.      */
  527.     public JMenuItem createLafMenuItem(JMenu menu, String label, String mnemonic,
  528.                    String accessibleDescription, String laf) {
  529.         JMenuItem mi = (JRadioButtonMenuItem) menu.add(new JRadioButtonMenuItem(getString(label)));
  530.     lafMenuGroup.add(mi);
  531.     mi.setMnemonic(getMnemonic(mnemonic));
  532.     mi.getAccessibleContext().setAccessibleDescription(getString(accessibleDescription));
  533.     mi.addActionListener(new ChangeLookAndFeelAction(this, laf));
  534.  
  535.     mi.setEnabled(isAvailableLookAndFeel(laf));
  536.  
  537.     return mi;
  538.     }
  539.  
  540.     /**
  541.      * Creates a multi-screen menu item
  542.      */
  543.     public JMenuItem createMultiscreenMenuItem(JMenu menu, int screen) {
  544.         JMenuItem mi = null;
  545.         if (screen == MultiScreenAction.ALL_SCREENS) {
  546.             mi = (JMenuItem) menu.add(new JMenuItem(getString("MultiMenu.all_label")));
  547.             mi.setMnemonic(getMnemonic("MultiMenu.all_mnemonic"));
  548.             mi.getAccessibleContext().setAccessibleDescription(getString(
  549.                                                                  "MultiMenu.all_accessible_description"));
  550.         }
  551.         else {
  552.             mi = (JMenuItem) menu.add(new JMenuItem(getString("MultiMenu.single_label") + " " +
  553.                                                                                                  screen));
  554.             mi.setMnemonic(KeyEvent.VK_0 + screen);
  555.             mi.getAccessibleContext().setAccessibleDescription(getString(
  556.                                                "MultiMenu.single_accessible_description") + " " + screen);
  557.                                                                                             
  558.         }
  559.         mi.addActionListener(new MultiScreenAction(this, screen));
  560.         return mi;
  561.     }
  562.  
  563.     /**
  564.      * Load the first demo. This is done separately from the remaining demos
  565.      * so that we can get SwingSet2 up and available to the user quickly.
  566.      */
  567.     public void preloadFirstDemo() {
  568.     DemoModule demo = addDemo(new InternalFrameDemo(this));
  569.     setDemo(demo);
  570.     }
  571.  
  572.  
  573.     /**
  574.      * Add a demo to the toolbar
  575.      */
  576.     public DemoModule addDemo(DemoModule demo) {
  577.     demosVector.addElement(demo);
  578.     // do the following on the gui thread
  579.     SwingUtilities.invokeLater(new SwingSetRunnable(this, demo) {
  580.         public void run() {
  581.         SwitchToDemoAction action = new SwitchToDemoAction(swingset, (DemoModule) obj);
  582.         JToggleButton tb = swingset.getToolBar().addToggleButton(action);
  583.         swingset.getToolBarGroup().add(tb);
  584.         if(swingset.getToolBarGroup().getSelection() == null) {
  585.             tb.setSelected(true);
  586.         }
  587.         tb.setText(null);
  588.         tb.setToolTipText(((DemoModule)obj).getToolTip());
  589.  
  590.         if(demos[demos.length-1].equals(obj.getClass().getName())) {
  591.             setStatus("");
  592.         } 
  593.           
  594.         }
  595.     });
  596.     return demo;
  597.     }
  598.  
  599.  
  600.     /**
  601.      * Sets the current demo
  602.      */
  603.     public void setDemo(DemoModule demo) {
  604.     currentDemo = demo;
  605.  
  606.     // Ensure panel's UI is current before making visible
  607.     JComponent currentDemoPanel = demo.getDemoPanel();
  608.     SwingUtilities.updateComponentTreeUI(currentDemoPanel);
  609.  
  610.     demoPanel.removeAll();
  611.     demoPanel.add(currentDemoPanel, BorderLayout.CENTER);
  612.  
  613.     tabbedPane.setSelectedIndex(0);
  614.     tabbedPane.setTitleAt(0, demo.getName());
  615.     tabbedPane.setToolTipTextAt(0, demo.getToolTip());
  616.     }
  617.  
  618.  
  619.     /**
  620.      * Bring up the SwingSet2 demo by showing the frame (only
  621.      * applicable if coming up as an application, not an applet);
  622.      */
  623.     public void showSwingSet2() {
  624.     if(!isApplet() && getFrame() != null) {
  625.         // put swingset in a frame and show it
  626.         JFrame f = getFrame();
  627.         f.setTitle(getString("Frame.title"));
  628.         f.getContentPane().add(this, BorderLayout.CENTER);
  629.         f.pack();
  630.  
  631.         Rectangle screenRect = f.getGraphicsConfiguration().getBounds();
  632.             Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets(
  633.                     f.getGraphicsConfiguration());
  634.  
  635.             // Make sure we don't place the demo off the screen.
  636.             int centerWidth = screenRect.width < f.getSize().width ?
  637.                     screenRect.x :
  638.                     screenRect.x + screenRect.width/2 - f.getSize().width/2;
  639.             int centerHeight = screenRect.height < f.getSize().height ?
  640.                     screenRect.y :
  641.                     screenRect.y + screenRect.height/2 - f.getSize().height/2;
  642.  
  643.             centerHeight = centerHeight < screenInsets.top ?
  644.                     screenInsets.top : centerHeight;
  645.  
  646.             f.setLocation(centerWidth, centerHeight);
  647.         f.show();
  648.             numSSs++;
  649.             swingSets.add(this);
  650.     } 
  651.     }
  652.  
  653.     /**
  654.      * Show the spash screen while the rest of the demo loads
  655.      */
  656.     public void createSplashScreen() {
  657.     splashLabel = new JLabel(createImageIcon("Splash.jpg", "Splash.accessible_description"));
  658.     
  659.     if(!isApplet()) {
  660.         splashScreen = new JWindow(getFrame());
  661.         splashScreen.getContentPane().add(splashLabel);
  662.         splashScreen.pack();
  663.         Rectangle screenRect = getFrame().getGraphicsConfiguration().getBounds();
  664.         splashScreen.setLocation(
  665.          screenRect.x + screenRect.width/2 - splashScreen.getSize().width/2,
  666.          screenRect.y + screenRect.height/2 - splashScreen.getSize().height/2);
  667.     } 
  668.     }
  669.  
  670.     public void showSplashScreen() {
  671.     if(!isApplet()) {
  672.         splashScreen.show();
  673.     } else {
  674.         add(splashLabel, BorderLayout.CENTER);
  675.         validate();
  676.         repaint();
  677.     }
  678.     }
  679.  
  680.     /**
  681.      * pop down the spash screen
  682.      */
  683.     public void hideSplash() {
  684.     if(!isApplet()) {
  685.         splashScreen.setVisible(false);
  686.         splashScreen = null;
  687.         splashLabel = null;
  688.     }
  689.     }
  690.  
  691.     // *******************************************************
  692.     // ****************** Utility Methods ********************
  693.     // *******************************************************
  694.  
  695.     /**
  696.      * Loads a demo from a classname
  697.      */
  698.     void loadDemo(String classname) {
  699.     setStatus(getString("Status.loading") + getString(classname + ".name"));
  700.     DemoModule demo = null;
  701.     try {
  702.         Class demoClass = Class.forName(classname);
  703.         Constructor demoConstructor = demoClass.getConstructor(new Class[]{SwingSet2.class});
  704.         demo = (DemoModule) demoConstructor.newInstance(new Object[]{this});
  705.         addDemo(demo);
  706.     } catch (Exception e) {
  707.         System.out.println("Error occurred loading demo: " + classname);
  708.     }
  709.     }
  710.     
  711.     /**
  712.      * A utility function that layers on top of the LookAndFeel's
  713.      * isSupportedLookAndFeel() method. Returns true if the LookAndFeel
  714.      * is supported. Returns false if the LookAndFeel is not supported
  715.      * and/or if there is any kind of error checking if the LookAndFeel
  716.      * is supported.
  717.      *
  718.      * The L&F menu will use this method to detemine whether the various
  719.      * L&F options should be active or inactive.
  720.      *
  721.      */
  722.      protected boolean isAvailableLookAndFeel(String laf) {
  723.          try { 
  724.              Class lnfClass = Class.forName(laf);
  725.              LookAndFeel newLAF = (LookAndFeel)(lnfClass.newInstance());
  726.              return newLAF.isSupportedLookAndFeel();
  727.          } catch(Exception e) { // If ANYTHING weird happens, return false
  728.              return false;
  729.          }
  730.      }
  731.  
  732.  
  733.     /**
  734.      * Determines if this is an applet or application
  735.      */
  736.     public boolean isApplet() {
  737.     return (applet != null);
  738.     }
  739.  
  740.     /**
  741.      * Returns the applet instance
  742.      */
  743.     public SwingSet2Applet getApplet() {
  744.     return applet;
  745.     }
  746.  
  747.  
  748.     /**
  749.      * Returns the frame instance
  750.      */
  751.     public JFrame getFrame() {
  752.     return frame;
  753.     }
  754.  
  755.     /**
  756.      * Returns the menubar
  757.      */
  758.     public JMenuBar getMenuBar() {
  759.     return menuBar;
  760.     }
  761.  
  762.     /**
  763.      * Returns the toolbar
  764.      */
  765.     public ToggleButtonToolBar getToolBar() {
  766.     return toolbar;
  767.     }
  768.  
  769.     /**
  770.      * Returns the toolbar button group
  771.      */
  772.     public ButtonGroup getToolBarGroup() {
  773.     return toolbarGroup;
  774.     }
  775.  
  776.     /**
  777.      * Returns the content pane wether we're in an applet
  778.      * or application
  779.      */
  780.     public Container getContentPane() {
  781.     if(contentPane == null) {
  782.         if(getFrame() != null) {
  783.         contentPane = getFrame().getContentPane();
  784.         } else if (getApplet() != null) {
  785.         contentPane = getApplet().getContentPane();
  786.         }
  787.     }
  788.     return contentPane;
  789.     }
  790.  
  791.     /**
  792.      * Create a frame for SwingSet2 to reside in if brought up
  793.      * as an application.
  794.      */
  795.     public static JFrame createFrame(GraphicsConfiguration gc) {
  796.     JFrame frame = new JFrame(gc);
  797.         if (numSSs == 0) {
  798.             frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  799.         } else {
  800.         WindowListener l = new WindowAdapter() {
  801.             public void windowClosing(WindowEvent e) {
  802.                     numSSs--;
  803.                     swingSets.remove(this);
  804.             }
  805.         };
  806.         frame.addWindowListener(l);
  807.         }
  808.     return frame;
  809.     }
  810.  
  811.  
  812.     /**
  813.      * Set the status 
  814.      */
  815.     public void setStatus(String s) {
  816.     // do the following on the gui thread
  817.     SwingUtilities.invokeLater(new SwingSetRunnable(this, s) {
  818.         public void run() {
  819.         swingset.statusField.setText((String) obj);
  820.         }
  821.     });
  822.     }
  823.  
  824.  
  825.     /**
  826.      * This method returns a string from the demo's resource bundle.
  827.      */
  828.     public String getString(String key) {
  829.     String value = null;
  830.     try {
  831.         value = getResourceBundle().getString(key);
  832.     } catch (MissingResourceException e) {
  833.         System.out.println("java.util.MissingResourceException: Couldn't find value for: " + key);
  834.     }
  835.     if(value == null) {
  836.         value = "Could not find resource: " + key + "  ";
  837.     }
  838.     return value;
  839.     }
  840.  
  841.     /**
  842.      * Returns the resource bundle associated with this demo. Used
  843.      * to get accessable and internationalized strings.
  844.      */
  845.     public ResourceBundle getResourceBundle() {
  846.     if(bundle == null) {
  847.         bundle = ResourceBundle.getBundle("resources.swingset");
  848.     }
  849.     return bundle;
  850.     }
  851.  
  852.     /**
  853.      * Returns a mnemonic from the resource bundle. Typically used as
  854.      * keyboard shortcuts in menu items.
  855.      */
  856.     public char getMnemonic(String key) {
  857.     return (getString(key)).charAt(0);
  858.     }
  859.  
  860.     /**
  861.      * Creates an icon from an image contained in the "images" directory.
  862.      */
  863.     public ImageIcon createImageIcon(String filename, String description) {
  864.     String path = "/resources/images/" + filename;
  865.     return new ImageIcon(getClass().getResource(path)); 
  866.     }
  867.  
  868.     /**
  869.      * If DEBUG is defined, prints debug information out to std ouput.
  870.      */
  871.     public void debug(String s) {
  872.     if(DEBUG) {
  873.         System.out.println((debugCounter++) + ": " + s);
  874.     }
  875.     }
  876.  
  877.     /**
  878.      * Stores the current L&F, and calls updateLookAndFeel, below
  879.      */
  880.     public void setLookAndFeel(String laf) {
  881.     if(currentLookAndFeel != laf) {
  882.         currentLookAndFeel = laf;
  883.         themesMenu.setEnabled(laf == metal);
  884.         updateLookAndFeel();
  885.     }
  886.     }
  887.  
  888.     /**
  889.      * Sets the current L&F on each demo module
  890.      */
  891.     public void updateLookAndFeel() {
  892.     try {
  893.         UIManager.setLookAndFeel(currentLookAndFeel);
  894.             for (Iterator itr = swingSets.iterator(); itr.hasNext(); ) {
  895.                 SwingSet2 ss = (SwingSet2)itr.next();
  896.             SwingUtilities.updateComponentTreeUI(ss);
  897.             }
  898.             // update LAF for the toplevel frame, too
  899.             if (!isApplet()) {
  900.                 SwingUtilities.updateComponentTreeUI(getFrame());
  901.             } else {
  902.                 SwingUtilities.updateComponentTreeUI(getApplet());
  903.             }
  904.  
  905.     } catch (Exception ex) {
  906.         System.out.println("Failed loading L&F: " + currentLookAndFeel);
  907.         System.out.println(ex);
  908.     }
  909.  
  910.     // lazily update update the UI's for the remaining demos
  911.     for (int i = 0; i < demosVector.size(); i++) {
  912.         DemoModule demo = (DemoModule) demosVector.elementAt(i);
  913.         if(currentDemo != demo) {
  914.         // do the following on the gui thread
  915.         SwingUtilities.invokeLater(new SwingSetRunnable(this, demo) {
  916.             public void run() {
  917.             SwingUtilities.updateComponentTreeUI(((DemoModule)obj).getDemoPanel());
  918.             }
  919.         });
  920.         }
  921.     }
  922.  
  923.     }
  924.  
  925.     /**
  926.      * Loads and puts the source code text into JEditorPane in the "Source Code" tab
  927.      */
  928.     public void setSourceCode(DemoModule demo) {
  929.     // do the following on the gui thread
  930.     SwingUtilities.invokeLater(new SwingSetRunnable(this, demo) {
  931.         public void run() {
  932.         swingset.demoSrcPane.setText(((DemoModule)obj).getSourceCode());
  933.         swingset.demoSrcPane.setCaretPosition(0);
  934.  
  935.         }
  936.     });
  937.     }
  938.  
  939.     // *******************************************************
  940.     // **************   ToggleButtonToolbar  *****************
  941.     // *******************************************************
  942.     static Insets zeroInsets = new Insets(1,1,1,1);
  943.     protected class ToggleButtonToolBar extends JToolBar {
  944.     public ToggleButtonToolBar() {
  945.         super();
  946.     }
  947.  
  948.     JToggleButton addToggleButton(Action a) {
  949.         JToggleButton tb = new JToggleButton(
  950.         (String)a.getValue(Action.NAME),
  951.         (Icon)a.getValue(Action.SMALL_ICON)
  952.         );
  953.         tb.setMargin(zeroInsets);
  954.         tb.setText(null);
  955.         tb.setEnabled(a.isEnabled());
  956.         tb.setToolTipText((String)a.getValue(Action.SHORT_DESCRIPTION));
  957.         tb.setAction(a);
  958.         add(tb);
  959.         return tb;
  960.     }
  961.     }
  962.  
  963.     // *******************************************************
  964.     // *********  ToolBar Panel / Docking Listener ***********
  965.     // *******************************************************
  966.     class ToolBarPanel extends JPanel implements ContainerListener {
  967.  
  968.     public boolean contains(int x, int y) {
  969.         Component c = getParent();
  970.         if (c != null) {
  971.         Rectangle r = c.getBounds();
  972.         return (x >= 0) && (x < r.width) && (y >= 0) && (y < r.height);
  973.         }
  974.         else {
  975.         return super.contains(x,y);
  976.         }
  977.     }
  978.  
  979.     public void componentAdded(ContainerEvent e) {
  980.         Container c = e.getContainer().getParent();
  981.         if (c != null) {
  982.         c.getParent().validate();
  983.         c.getParent().repaint();        
  984.         }
  985.     }
  986.  
  987.     public void componentRemoved(ContainerEvent e) {
  988.         Container c = e.getContainer().getParent();
  989.         if (c != null) {
  990.         c.getParent().validate();
  991.         c.getParent().repaint();
  992.         }
  993.     }
  994.     }
  995.  
  996.     // *******************************************************
  997.     // ******************   Runnables  ***********************
  998.     // *******************************************************
  999.  
  1000.     /**
  1001.      * Generic SwingSet2 runnable. This is intended to run on the
  1002.      * AWT gui event thread so as not to muck things up by doing
  1003.      * gui work off the gui thread. Accepts a SwingSet2 and an Object
  1004.      * as arguments, which gives subtypes of this class the two
  1005.      * "must haves" needed in most runnables for this demo.
  1006.      */
  1007.     class SwingSetRunnable implements Runnable {
  1008.     protected SwingSet2 swingset;
  1009.     protected Object obj;
  1010.     
  1011.     public SwingSetRunnable(SwingSet2 swingset, Object obj) {
  1012.         this.swingset = swingset;
  1013.         this.obj = obj;
  1014.     }
  1015.  
  1016.     public void run() {
  1017.     }
  1018.     }
  1019.     
  1020.     
  1021.     // *******************************************************
  1022.     // ********************   Actions  ***********************
  1023.     // *******************************************************
  1024.     
  1025.     public class SwitchToDemoAction extends AbstractAction {
  1026.     SwingSet2 swingset;
  1027.     DemoModule demo;
  1028.     
  1029.     public SwitchToDemoAction(SwingSet2 swingset, DemoModule demo) {
  1030.         super(demo.getName(), demo.getIcon());
  1031.         this.swingset = swingset;
  1032.         this.demo = demo;
  1033.     }
  1034.  
  1035.     public void actionPerformed(ActionEvent e) {
  1036.         swingset.setDemo(demo);
  1037.     }
  1038.     }
  1039.  
  1040.     class OkAction extends AbstractAction {
  1041.     JDialog aboutBox;
  1042.  
  1043.         protected OkAction(JDialog aboutBox) {
  1044.             super("OkAction");
  1045.         this.aboutBox = aboutBox;
  1046.         }
  1047.  
  1048.         public void actionPerformed(ActionEvent e) {
  1049.         aboutBox.setVisible(false);
  1050.     }
  1051.     }
  1052.  
  1053.     class ChangeLookAndFeelAction extends AbstractAction {
  1054.     SwingSet2 swingset;
  1055.     String laf;
  1056.         protected ChangeLookAndFeelAction(SwingSet2 swingset, String laf) {
  1057.             super("ChangeTheme");
  1058.         this.swingset = swingset;
  1059.         this.laf = laf;
  1060.         }
  1061.  
  1062.         public void actionPerformed(ActionEvent e) {
  1063.         swingset.setLookAndFeel(laf);
  1064.     }
  1065.     }
  1066.  
  1067.     // Turns on all possible auditory feedback
  1068.     class OnAudioAction extends AbstractAction {
  1069.     SwingSet2 swingset;
  1070.         protected OnAudioAction(SwingSet2 swingset) {
  1071.             super("Audio On");
  1072.         this.swingset = swingset;
  1073.         }
  1074.         public void actionPerformed(ActionEvent e) {
  1075.         UIManager.put("AuditoryCues.playList",
  1076.               UIManager.get("AuditoryCues.allAuditoryCues"));
  1077.         swingset.updateLookAndFeel();
  1078.     }
  1079.     }
  1080.  
  1081.     // Turns on the default amount of auditory feedback
  1082.     class DefaultAudioAction extends AbstractAction {
  1083.     SwingSet2 swingset;
  1084.         protected DefaultAudioAction(SwingSet2 swingset) {
  1085.             super("Audio Default");
  1086.         this.swingset = swingset;
  1087.         }
  1088.         public void actionPerformed(ActionEvent e) {
  1089.         UIManager.put("AuditoryCues.playList",
  1090.               UIManager.get("AuditoryCues.defaultCueList"));
  1091.         swingset.updateLookAndFeel();
  1092.     }
  1093.     }
  1094.  
  1095.     // Turns off all possible auditory feedback
  1096.     class OffAudioAction extends AbstractAction {
  1097.     SwingSet2 swingset;
  1098.         protected OffAudioAction(SwingSet2 swingset) {
  1099.             super("Audio Off");
  1100.         this.swingset = swingset;
  1101.         }
  1102.         public void actionPerformed(ActionEvent e) {
  1103.         UIManager.put("AuditoryCues.playList",
  1104.               UIManager.get("AuditoryCues.noAuditoryCues"));
  1105.         swingset.updateLookAndFeel();
  1106.     }
  1107.     }
  1108.  
  1109.     // Turns on or off the tool tips for the demo.
  1110.     class ToolTipAction extends AbstractAction {
  1111.         SwingSet2 swingset;
  1112.         boolean status;
  1113.         protected ToolTipAction(SwingSet2 swingset, boolean status) {
  1114.             super("ToolTip Control");
  1115.             this.swingset = swingset;
  1116.             this.status = status;
  1117.         }
  1118.  
  1119.         public void actionPerformed(ActionEvent e) {
  1120.             ToolTipManager.sharedInstance().setEnabled(status);
  1121.         }
  1122.     }
  1123.  
  1124.     class ChangeThemeAction extends AbstractAction {
  1125.     SwingSet2 swingset;
  1126.     DefaultMetalTheme theme;
  1127.         protected ChangeThemeAction(SwingSet2 swingset, DefaultMetalTheme theme) {
  1128.             super("ChangeTheme");
  1129.         this.swingset = swingset;
  1130.         this.theme = theme;
  1131.         }
  1132.  
  1133.         public void actionPerformed(ActionEvent e) {
  1134.         MetalLookAndFeel.setCurrentTheme(theme);
  1135.         swingset.updateLookAndFeel();
  1136.     }
  1137.     }
  1138.  
  1139.     class ExitAction extends AbstractAction {
  1140.     SwingSet2 swingset;
  1141.         protected ExitAction(SwingSet2 swingset) {
  1142.             super("ExitAction");
  1143.         this.swingset = swingset;
  1144.         }
  1145.  
  1146.         public void actionPerformed(ActionEvent e) {
  1147.         System.exit(0);
  1148.         }
  1149.     }
  1150.  
  1151.     class AboutAction extends AbstractAction {
  1152.     SwingSet2 swingset;
  1153.         protected AboutAction(SwingSet2 swingset) {
  1154.             super("AboutAction");
  1155.         this.swingset = swingset;
  1156.         }
  1157.     
  1158.         public void actionPerformed(ActionEvent e) {
  1159.         if(aboutBox == null) {
  1160.         // JPanel panel = new JPanel(new BorderLayout());
  1161.         JPanel panel = new AboutPanel(swingset);
  1162.         panel.setLayout(new BorderLayout());
  1163.  
  1164.         aboutBox = new JDialog(swingset.getFrame(), getString("AboutBox.title"), false);
  1165.         aboutBox.getContentPane().add(panel, BorderLayout.CENTER);
  1166.  
  1167.         // JButton button = new JButton(getString("AboutBox.ok_button_text"));
  1168.         JPanel buttonpanel = new JPanel();
  1169.         buttonpanel.setOpaque(false);
  1170.         JButton button = (JButton) buttonpanel.add(
  1171.             new JButton(getString("AboutBox.ok_button_text"))
  1172.         );
  1173.         panel.add(buttonpanel, BorderLayout.SOUTH);
  1174.  
  1175.         button.addActionListener(new OkAction(aboutBox));
  1176.         }
  1177.         aboutBox.pack();
  1178.         Point p = swingset.getLocationOnScreen();
  1179.         aboutBox.setLocation(p.x + 10, p.y +10);
  1180.         aboutBox.show();
  1181.     }
  1182.     }
  1183.  
  1184.     class MultiScreenAction extends AbstractAction {
  1185.         static final int ALL_SCREENS = -1;
  1186.         int screen;
  1187.         protected MultiScreenAction(SwingSet2 swingset, int screen) {
  1188.             super("MultiScreenAction");
  1189.             this.screen = screen;
  1190.         }
  1191.  
  1192.         public void actionPerformed(ActionEvent e) {
  1193.             GraphicsDevice[] gds = GraphicsEnvironment.
  1194.                                    getLocalGraphicsEnvironment().
  1195.                                    getScreenDevices();
  1196.             if (screen == ALL_SCREENS) {
  1197.                 for (int i = 0; i < gds.length; i++) {
  1198.                     SwingSet2 swingset = new SwingSet2(null,
  1199.                                   gds[i].getDefaultConfiguration());
  1200.                 }
  1201.             }
  1202.             else {
  1203.                 SwingSet2 swingset = new SwingSet2(null,
  1204.                              gds[screen].getDefaultConfiguration());
  1205.             }
  1206.         }
  1207.     }
  1208.  
  1209.     // *******************************************************
  1210.     // **********************  Misc  *************************
  1211.     // *******************************************************
  1212.  
  1213.     class DemoLoadThread extends Thread {
  1214.     SwingSet2 swingset;
  1215.     
  1216.     public DemoLoadThread(SwingSet2 swingset) {
  1217.         this.swingset = swingset;
  1218.     }
  1219.  
  1220.     public void run() {
  1221.         swingset.loadDemos();
  1222.     }
  1223.     }
  1224.  
  1225.     class AboutPanel extends JPanel {
  1226.     ImageIcon aboutimage = null;
  1227.     SwingSet2 swingset = null;
  1228.  
  1229.     public AboutPanel(SwingSet2 swingset) {
  1230.         this.swingset = swingset;
  1231.         aboutimage = swingset.createImageIcon("About.jpg", "AboutBox.accessible_description");
  1232.         setOpaque(false);
  1233.     }
  1234.  
  1235.     public void paint(Graphics g) {
  1236.         aboutimage.paintIcon(this, g, 0, 0);
  1237.         super.paint(g);
  1238.     }
  1239.  
  1240.     public Dimension getPreferredSize() {
  1241.         return new Dimension(aboutimage.getIconWidth(),
  1242.                  aboutimage.getIconHeight());
  1243.     }
  1244.     }
  1245.  
  1246. }
  1247.  
  1248.