home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / JBuilder8.iso / Solaris / resource / jre / demo / jfc / Stylepad / src / Notepad.java < prev    next >
Encoding:
Java Source  |  2002-09-06  |  19.9 KB  |  753 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.  * @(#)Notepad.java    1.20 02/06/13
  38.  */
  39.  
  40. import java.awt.*;
  41. import java.awt.event.*;
  42. import java.beans.*;
  43. import java.io.*;
  44. import java.net.URL;
  45. import java.util.*;
  46.  
  47. import javax.swing.text.*;
  48. import javax.swing.undo.*;
  49. import javax.swing.event.*;
  50. import javax.swing.*;
  51.  
  52. /**
  53.  * Sample application using the simple text editor component that
  54.  * supports only one font.
  55.  *
  56.  * @author  Timothy Prinzing
  57.  * @version 1.20 06/13/02
  58.  */
  59. class Notepad extends JPanel {
  60.  
  61.     private static ResourceBundle resources;
  62.  
  63.     static {
  64.         try {
  65.             resources = ResourceBundle.getBundle("resources.Notepad", 
  66.                                                  Locale.getDefault());
  67.         } catch (MissingResourceException mre) {
  68.             System.err.println("resources/Notepad.properties not found");
  69.             System.exit(1);
  70.         }
  71.     }
  72.  
  73.     Notepad() {
  74.     super(true);
  75.  
  76.     // Force SwingSet to come up in the Cross Platform L&F
  77.     try {
  78.         UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
  79.         // If you want the System L&F instead, comment out the above line and
  80.         // uncomment the following:
  81.         // UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
  82.     } catch (Exception exc) {
  83.         System.err.println("Error loading L&F: " + exc);
  84.     }
  85.  
  86.     setBorder(BorderFactory.createEtchedBorder());
  87.     setLayout(new BorderLayout());
  88.  
  89.     // create the embedded JTextComponent
  90.     editor = createEditor();
  91.     // Add this as a listener for undoable edits.
  92.     editor.getDocument().addUndoableEditListener(undoHandler);
  93.  
  94.     // install the command table
  95.     commands = new Hashtable();
  96.     Action[] actions = getActions();
  97.     for (int i = 0; i < actions.length; i++) {
  98.         Action a = actions[i];
  99.         //commands.put(a.getText(Action.NAME), a);
  100.         commands.put(a.getValue(Action.NAME), a);
  101.     }
  102.     
  103.     JScrollPane scroller = new JScrollPane();
  104.     JViewport port = scroller.getViewport();
  105.     port.add(editor);
  106.     try {
  107.         String vpFlag = resources.getString("ViewportBackingStore");
  108.         Boolean bs = new Boolean(vpFlag);
  109.         port.setBackingStoreEnabled(bs.booleanValue());
  110.     } catch (MissingResourceException mre) {
  111.         // just use the viewport default
  112.     }
  113.  
  114.     menuItems = new Hashtable();
  115.     menubar = createMenubar();
  116.     add("North", menubar);
  117.     JPanel panel = new JPanel();
  118.     panel.setLayout(new BorderLayout());    
  119.     panel.add("North",createToolbar());
  120.     panel.add("Center", scroller);
  121.     add("Center", panel);
  122.     add("South", createStatusbar());
  123.     }
  124.  
  125.     public static void main(String[] args) {
  126.         try {
  127.         String vers = System.getProperty("java.version");
  128.         if (vers.compareTo("1.1.2") < 0) {
  129.             System.out.println("!!!WARNING: Swing must be run with a " +
  130.                                "1.1.2 or higher version VM!!!");
  131.         }
  132.         JFrame frame = new JFrame();
  133.         frame.setTitle(resources.getString("Title"));
  134.     frame.setBackground(Color.lightGray);
  135.     frame.getContentPane().setLayout(new BorderLayout());
  136.     frame.getContentPane().add("Center", new Notepad());
  137.     frame.addWindowListener(new AppCloser());
  138.     frame.pack();
  139.     frame.setSize(500, 600);
  140.         frame.show();
  141.         } catch (Throwable t) {
  142.             System.out.println("uncaught exception: " + t);
  143.             t.printStackTrace();
  144.         }
  145.     }
  146.  
  147.     /**
  148.      * Fetch the list of actions supported by this
  149.      * editor.  It is implemented to return the list
  150.      * of actions supported by the embedded JTextComponent
  151.      * augmented with the actions defined locally.
  152.      */
  153.     public Action[] getActions() {
  154.     return TextAction.augmentList(editor.getActions(), defaultActions);
  155.     }
  156.  
  157.     /**
  158.      * Create an editor to represent the given document.  
  159.      */
  160.     protected JTextComponent createEditor() {
  161.     JTextComponent c = new JTextArea();
  162.     c.setDragEnabled(true);
  163.     c.setFont(new Font("monospaced", Font.PLAIN, 12));
  164.     return c;
  165.     }
  166.  
  167.     /** 
  168.      * Fetch the editor contained in this panel
  169.      */
  170.     protected JTextComponent getEditor() {
  171.     return editor;
  172.     }
  173.  
  174.     /**
  175.      * To shutdown when run as an application.  This is a
  176.      * fairly lame implementation.   A more self-respecting
  177.      * implementation would at least check to see if a save
  178.      * was needed.
  179.      */
  180.     protected static final class AppCloser extends WindowAdapter {
  181.         public void windowClosing(WindowEvent e) {
  182.         System.exit(0);
  183.     }
  184.     }
  185.  
  186.     /**
  187.      * Find the hosting frame, for the file-chooser dialog.
  188.      */
  189.     protected Frame getFrame() {
  190.     for (Container p = getParent(); p != null; p = p.getParent()) {
  191.         if (p instanceof Frame) {
  192.         return (Frame) p;
  193.         }
  194.     }
  195.     return null;
  196.     }
  197.  
  198.     /**
  199.      * This is the hook through which all menu items are
  200.      * created.  It registers the result with the menuitem
  201.      * hashtable so that it can be fetched with getMenuItem().
  202.      * @see #getMenuItem
  203.      */
  204.     protected JMenuItem createMenuItem(String cmd) {
  205.     JMenuItem mi = new JMenuItem(getResourceString(cmd + labelSuffix));
  206.         URL url = getResource(cmd + imageSuffix);
  207.     if (url != null) {
  208.         mi.setHorizontalTextPosition(JButton.RIGHT);
  209.         mi.setIcon(new ImageIcon(url));
  210.     }
  211.     String astr = getResourceString(cmd + actionSuffix);
  212.     if (astr == null) {
  213.         astr = cmd;
  214.     }
  215.     mi.setActionCommand(astr);
  216.     Action a = getAction(astr);
  217.     if (a != null) {
  218.         mi.addActionListener(a);
  219.         a.addPropertyChangeListener(createActionChangeListener(mi));
  220.         mi.setEnabled(a.isEnabled());
  221.     } else {
  222.         mi.setEnabled(false);
  223.     }
  224.     menuItems.put(cmd, mi);
  225.     return mi;
  226.     }
  227.  
  228.     /**
  229.      * Fetch the menu item that was created for the given
  230.      * command.
  231.      * @param cmd  Name of the action.
  232.      * @returns item created for the given command or null
  233.      *  if one wasn't created.
  234.      */
  235.     protected JMenuItem getMenuItem(String cmd) {
  236.     return (JMenuItem) menuItems.get(cmd);
  237.     }
  238.  
  239.     protected Action getAction(String cmd) {
  240.     return (Action) commands.get(cmd);
  241.     }
  242.  
  243.     protected String getResourceString(String nm) {
  244.     String str;
  245.     try {
  246.         str = resources.getString(nm);
  247.     } catch (MissingResourceException mre) {
  248.         str = null;
  249.     }
  250.     return str;
  251.     }
  252.  
  253.     protected URL getResource(String key) {
  254.     String name = getResourceString(key);
  255.     if (name != null) {
  256.         URL url = this.getClass().getResource(name);
  257.         return url;
  258.     }
  259.     return null;
  260.     }
  261.  
  262.     protected Container getToolbar() {
  263.     return toolbar;
  264.     }
  265.  
  266.     protected JMenuBar getMenubar() {
  267.     return menubar;
  268.     }
  269.  
  270.     /**
  271.      * Create a status bar
  272.      */
  273.     protected Component createStatusbar() {
  274.     // need to do something reasonable here
  275.     status = new StatusBar();
  276.     return status;
  277.     }
  278.  
  279.     /**
  280.      * Resets the undo manager.
  281.      */
  282.     protected void resetUndoManager() {
  283.     undo.discardAllEdits();
  284.     undoAction.update();
  285.     redoAction.update();
  286.     }
  287.  
  288.     /**
  289.      * Create the toolbar.  By default this reads the 
  290.      * resource file for the definition of the toolbar.
  291.      */
  292.     private Component createToolbar() {
  293.     toolbar = new JToolBar();
  294.     String[] toolKeys = tokenize(getResourceString("toolbar"));
  295.     for (int i = 0; i < toolKeys.length; i++) {
  296.         if (toolKeys[i].equals("-")) {
  297.         toolbar.add(Box.createHorizontalStrut(5));
  298.         } else {
  299.         toolbar.add(createTool(toolKeys[i]));
  300.         }
  301.     }
  302.     toolbar.add(Box.createHorizontalGlue());
  303.     return toolbar;
  304.     }
  305.  
  306.     /**
  307.      * Hook through which every toolbar item is created.
  308.      */
  309.     protected Component createTool(String key) {
  310.     return createToolbarButton(key);
  311.     }
  312.  
  313.     /**
  314.      * Create a button to go inside of the toolbar.  By default this
  315.      * will load an image resource.  The image filename is relative to
  316.      * the classpath (including the '.' directory if its a part of the
  317.      * classpath), and may either be in a JAR file or a separate file.
  318.      * 
  319.      * @param key The key in the resource file to serve as the basis
  320.      *  of lookups.
  321.      */
  322.     protected JButton createToolbarButton(String key) {
  323.     URL url = getResource(key + imageSuffix);
  324.         JButton b = new JButton(new ImageIcon(url)) {
  325.             public float getAlignmentY() { return 0.5f; }
  326.     };
  327.         b.setRequestFocusEnabled(false);
  328.         b.setMargin(new Insets(1,1,1,1));
  329.  
  330.     String astr = getResourceString(key + actionSuffix);
  331.     if (astr == null) {
  332.         astr = key;
  333.     }
  334.     Action a = getAction(astr);
  335.     if (a != null) {
  336.         b.setActionCommand(astr);
  337.         b.addActionListener(a);
  338.     } else {
  339.         b.setEnabled(false);
  340.     }
  341.  
  342.     String tip = getResourceString(key + tipSuffix);
  343.     if (tip != null) {
  344.         b.setToolTipText(tip);
  345.     }
  346.  
  347.         return b;
  348.     }
  349.  
  350.     /**
  351.      * Take the given string and chop it up into a series
  352.      * of strings on whitespace boundries.  This is useful
  353.      * for trying to get an array of strings out of the
  354.      * resource file.
  355.      */
  356.     protected String[] tokenize(String input) {
  357.     Vector v = new Vector();
  358.     StringTokenizer t = new StringTokenizer(input);
  359.     String cmd[];
  360.  
  361.     while (t.hasMoreTokens())
  362.         v.addElement(t.nextToken());
  363.     cmd = new String[v.size()];
  364.     for (int i = 0; i < cmd.length; i++)
  365.         cmd[i] = (String) v.elementAt(i);
  366.  
  367.     return cmd;
  368.     }
  369.  
  370.     /**
  371.      * Create the menubar for the app.  By default this pulls the
  372.      * definition of the menu from the associated resource file. 
  373.      */
  374.     protected JMenuBar createMenubar() {
  375.     JMenuItem mi;
  376.     JMenuBar mb = new JMenuBar();
  377.  
  378.     String[] menuKeys = tokenize(getResourceString("menubar"));
  379.     for (int i = 0; i < menuKeys.length; i++) {
  380.         JMenu m = createMenu(menuKeys[i]);
  381.         if (m != null) {
  382.         mb.add(m);
  383.         }
  384.     }
  385.     return mb;
  386.     }
  387.  
  388.     /**
  389.      * Create a menu for the app.  By default this pulls the
  390.      * definition of the menu from the associated resource file.
  391.      */
  392.     protected JMenu createMenu(String key) {
  393.     String[] itemKeys = tokenize(getResourceString(key));
  394.     JMenu menu = new JMenu(getResourceString(key + "Label"));
  395.     for (int i = 0; i < itemKeys.length; i++) {
  396.         if (itemKeys[i].equals("-")) {
  397.         menu.addSeparator();
  398.         } else {
  399.         JMenuItem mi = createMenuItem(itemKeys[i]);
  400.         menu.add(mi);
  401.         }
  402.     }
  403.     return menu;
  404.     }
  405.  
  406.     // Yarked from JMenu, ideally this would be public.
  407.     protected PropertyChangeListener createActionChangeListener(JMenuItem b) {
  408.     return new ActionChangedListener(b);
  409.     }
  410.  
  411.     // Yarked from JMenu, ideally this would be public.
  412.     private class ActionChangedListener implements PropertyChangeListener {
  413.         JMenuItem menuItem;
  414.         
  415.         ActionChangedListener(JMenuItem mi) {
  416.             super();
  417.             this.menuItem = mi;
  418.         }
  419.         public void propertyChange(PropertyChangeEvent e) {
  420.             String propertyName = e.getPropertyName();
  421.             if (e.getPropertyName().equals(Action.NAME)) {
  422.                 String text = (String) e.getNewValue();
  423.                 menuItem.setText(text);
  424.             } else if (propertyName.equals("enabled")) {
  425.                 Boolean enabledState = (Boolean) e.getNewValue();
  426.                 menuItem.setEnabled(enabledState.booleanValue());
  427.             }
  428.         }
  429.     }
  430.  
  431.     private JTextComponent editor;
  432.     private Hashtable commands;
  433.     private Hashtable menuItems;
  434.     private JMenuBar menubar;
  435.     private JToolBar toolbar;
  436.     private JComponent status;
  437.     private JFrame elementTreeFrame;
  438.     protected ElementTreePanel elementTreePanel;
  439.  
  440.     protected FileDialog fileDialog;
  441.  
  442.     /**
  443.      * Listener for the edits on the current document.
  444.      */
  445.     protected UndoableEditListener undoHandler = new UndoHandler();
  446.  
  447.     /** UndoManager that we add edits to. */
  448.     protected UndoManager undo = new UndoManager();
  449.  
  450.     /**
  451.      * Suffix applied to the key used in resource file
  452.      * lookups for an image.
  453.      */
  454.     public static final String imageSuffix = "Image";
  455.  
  456.     /**
  457.      * Suffix applied to the key used in resource file
  458.      * lookups for a label.
  459.      */
  460.     public static final String labelSuffix = "Label";
  461.  
  462.     /**
  463.      * Suffix applied to the key used in resource file
  464.      * lookups for an action.
  465.      */
  466.     public static final String actionSuffix = "Action";
  467.  
  468.     /**
  469.      * Suffix applied to the key used in resource file
  470.      * lookups for tooltip text.
  471.      */
  472.     public static final String tipSuffix = "Tooltip";
  473.  
  474.     public static final String openAction = "open";
  475.     public static final String newAction  = "new";
  476.     public static final String saveAction = "save";
  477.     public static final String exitAction = "exit";
  478.     public static final String showElementTreeAction = "showElementTree";
  479.  
  480.     class UndoHandler implements UndoableEditListener {
  481.  
  482.     /**
  483.      * Messaged when the Document has created an edit, the edit is
  484.      * added to <code>undo</code>, an instance of UndoManager.
  485.      */
  486.         public void undoableEditHappened(UndoableEditEvent e) {
  487.         undo.addEdit(e.getEdit());
  488.         undoAction.update();
  489.         redoAction.update();
  490.     }
  491.     }
  492.  
  493.     /**
  494.      * FIXME - I'm not very useful yet
  495.      */
  496.     class StatusBar extends JComponent {
  497.  
  498.         public StatusBar() {
  499.         super();
  500.         setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
  501.     }
  502.  
  503.         public void paint(Graphics g) {
  504.         super.paint(g);
  505.     }
  506.  
  507.     }
  508.  
  509.     // --- action implementations -----------------------------------
  510.  
  511.     private UndoAction undoAction = new UndoAction();
  512.     private RedoAction redoAction = new RedoAction();
  513.  
  514.     /**
  515.      * Actions defined by the Notepad class
  516.      */
  517.     private Action[] defaultActions = {
  518.     new NewAction(),
  519.     new OpenAction(),
  520.     new ExitAction(),
  521.     new ShowElementTreeAction(),
  522.         undoAction,
  523.         redoAction
  524.     };
  525.  
  526.     class UndoAction extends AbstractAction {
  527.     public UndoAction() {
  528.         super("Undo");
  529.         setEnabled(false);
  530.     }
  531.  
  532.     public void actionPerformed(ActionEvent e) {
  533.         try {
  534.         undo.undo();
  535.         } catch (CannotUndoException ex) {
  536.         System.out.println("Unable to undo: " + ex);
  537.         ex.printStackTrace();
  538.         }
  539.         update();
  540.         redoAction.update();
  541.     }
  542.  
  543.     protected void update() {
  544.         if(undo.canUndo()) {
  545.         setEnabled(true);
  546.         putValue(Action.NAME, undo.getUndoPresentationName());
  547.         }
  548.         else {
  549.         setEnabled(false);
  550.         putValue(Action.NAME, "Undo");
  551.         }
  552.     }
  553.     }
  554.  
  555.     class RedoAction extends AbstractAction {
  556.     public RedoAction() {
  557.         super("Redo");
  558.         setEnabled(false);
  559.     }
  560.  
  561.     public void actionPerformed(ActionEvent e) {
  562.         try {
  563.         undo.redo();
  564.         } catch (CannotRedoException ex) {
  565.         System.out.println("Unable to redo: " + ex);
  566.         ex.printStackTrace();
  567.         }
  568.         update();
  569.         undoAction.update();
  570.     }
  571.  
  572.     protected void update() {
  573.         if(undo.canRedo()) {
  574.         setEnabled(true);
  575.         putValue(Action.NAME, undo.getRedoPresentationName());
  576.         }
  577.         else {
  578.         setEnabled(false);
  579.         putValue(Action.NAME, "Redo");
  580.         }
  581.     }
  582.     }
  583.  
  584.     class OpenAction extends NewAction {
  585.  
  586.     OpenAction() {
  587.         super(openAction);
  588.     }
  589.  
  590.         public void actionPerformed(ActionEvent e) {
  591.         Frame frame = getFrame();
  592.         if (fileDialog == null) {
  593.         fileDialog = new FileDialog(frame);
  594.         }
  595.         fileDialog.setMode(FileDialog.LOAD);
  596.         fileDialog.show();
  597.  
  598.         String file = fileDialog.getFile();
  599.         if (file == null) {
  600.         return;
  601.         }
  602.         String directory = fileDialog.getDirectory();
  603.         File f = new File(directory, file);
  604.         if (f.exists()) {
  605.         Document oldDoc = getEditor().getDocument();
  606.         if(oldDoc != null)
  607.             oldDoc.removeUndoableEditListener(undoHandler);
  608.         if (elementTreePanel != null) {
  609.             elementTreePanel.setEditor(null);
  610.         }
  611.         getEditor().setDocument(new PlainDocument());
  612.         frame.setTitle(file);
  613.         Thread loader = new FileLoader(f, editor.getDocument());
  614.         loader.start();
  615.         }
  616.     }
  617.     }
  618.     
  619.     class NewAction extends AbstractAction {
  620.  
  621.     NewAction() {
  622.         super(newAction);
  623.     }
  624.  
  625.     NewAction(String nm) {
  626.         super(nm);
  627.     }
  628.  
  629.         public void actionPerformed(ActionEvent e) {
  630.         Document oldDoc = getEditor().getDocument();
  631.         if(oldDoc != null)
  632.         oldDoc.removeUndoableEditListener(undoHandler);
  633.         getEditor().setDocument(new PlainDocument());
  634.         getEditor().getDocument().addUndoableEditListener(undoHandler);
  635.         resetUndoManager();
  636.         revalidate();
  637.     }
  638.     }
  639.  
  640.     /**
  641.      * Really lame implementation of an exit command
  642.      */
  643.     class ExitAction extends AbstractAction {
  644.  
  645.     ExitAction() {
  646.         super(exitAction);
  647.     }
  648.  
  649.         public void actionPerformed(ActionEvent e) {
  650.         System.exit(0);
  651.     }
  652.     }
  653.  
  654.     /**
  655.      * Action that brings up a JFrame with a JTree showing the structure
  656.      * of the document.
  657.      */
  658.     class ShowElementTreeAction extends AbstractAction {
  659.  
  660.     ShowElementTreeAction() {
  661.         super(showElementTreeAction);
  662.     }
  663.  
  664.     ShowElementTreeAction(String nm) {
  665.         super(nm);
  666.     }
  667.  
  668.         public void actionPerformed(ActionEvent e) {
  669.         if(elementTreeFrame == null) {
  670.         // Create a frame containing an instance of 
  671.         // ElementTreePanel.
  672.         try {
  673.             String    title = resources.getString
  674.                             ("ElementTreeFrameTitle");
  675.             elementTreeFrame = new JFrame(title);
  676.         } catch (MissingResourceException mre) {
  677.             elementTreeFrame = new JFrame();
  678.         }
  679.  
  680.         elementTreeFrame.addWindowListener(new WindowAdapter() {
  681.             public void windowClosing(WindowEvent weeee) {
  682.             elementTreeFrame.setVisible(false);
  683.             }
  684.         });
  685.         Container fContentPane = elementTreeFrame.getContentPane();
  686.  
  687.         fContentPane.setLayout(new BorderLayout());
  688.         elementTreePanel = new ElementTreePanel(getEditor());
  689.         fContentPane.add(elementTreePanel);
  690.         elementTreeFrame.pack();
  691.         }
  692.         elementTreeFrame.show();
  693.     }
  694.     }
  695.  
  696.     /**
  697.      * Thread to load a file into the text storage model
  698.      */
  699.     class FileLoader extends Thread {
  700.  
  701.     FileLoader(File f, Document doc) {
  702.         setPriority(4);
  703.         this.f = f;
  704.         this.doc = doc;
  705.     }
  706.  
  707.         public void run() {
  708.         try {
  709.         // initialize the statusbar
  710.         status.removeAll();
  711.         JProgressBar progress = new JProgressBar();
  712.         progress.setMinimum(0);
  713.         progress.setMaximum((int) f.length());
  714.         status.add(progress);
  715.         status.revalidate();
  716.  
  717.         // try to start reading
  718.         Reader in = new FileReader(f);
  719.         char[] buff = new char[4096];
  720.         int nch;
  721.         while ((nch = in.read(buff, 0, buff.length)) != -1) {
  722.             doc.insertString(doc.getLength(), new String(buff, 0, nch), null);
  723.             progress.setValue(progress.getValue() + nch);
  724.         }
  725.  
  726.         // we are done... get rid of progressbar
  727.         doc.addUndoableEditListener(undoHandler);
  728.         status.removeAll();
  729.         status.revalidate();
  730.  
  731.         resetUndoManager();
  732.         }
  733.         catch (IOException e) {
  734.         System.err.println(e.toString());
  735.         }
  736.         catch (BadLocationException e) {
  737.         System.err.println(e.getMessage());
  738.         }
  739.         if (elementTreePanel != null) {
  740.         SwingUtilities.invokeLater(new Runnable() {
  741.             public void run() {
  742.             elementTreePanel.setEditor(getEditor());
  743.             }
  744.         });
  745.         }
  746.     }
  747.  
  748.     Document doc;
  749.     File f;
  750.     }
  751.  
  752. }
  753.