KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > Notepad


1 /*
2  * @(#)Notepad.java 1.31 05/11/17
3  *
4  * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * -Redistribution of source code must retain the above copyright notice, this
10  * list of conditions and the following disclaimer.
11  *
12  * -Redistribution in binary form must reproduce the above copyright notice,
13  * this list of conditions and the following disclaimer in the documentation
14  * and/or other materials provided with the distribution.
15  *
16  * Neither the name of Sun Microsystems, Inc. or the names of contributors may
17  * be used to endorse or promote products derived from this software without
18  * specific prior written permission.
19  *
20  * This software is provided "AS IS," without a warranty of any kind. ALL
21  * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
22  * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
23  * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN")
24  * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
25  * AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
26  * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
27  * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
28  * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
29  * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
30  * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
31  *
32  * You acknowledge that this software is not designed, licensed or intended
33  * for use in the design, construction, operation or maintenance of any
34  * nuclear facility.
35  */

36
37 /*
38  * @(#)Notepad.java 1.31 05/11/17
39  */

40
41 import java.awt.*;
42 import java.awt.event.*;
43 import java.beans.*;
44 import java.io.*;
45 import java.net.URL JavaDoc;
46 import java.util.*;
47
48 import javax.swing.text.*;
49 import javax.swing.undo.*;
50 import javax.swing.event.*;
51 import javax.swing.*;
52
53 /**
54  * Sample application using the simple text editor component that
55  * supports only one font.
56  *
57  * @author Timothy Prinzing
58  * @version 1.31 11/17/05
59  */

60 class Notepad extends JPanel {
61
62     private static ResourceBundle resources;
63     private final static String JavaDoc EXIT_AFTER_PAINT = new String JavaDoc("-exit");
64     private static boolean exitAfterFirstPaint;
65
66     static {
67         try {
68             resources = ResourceBundle.getBundle("resources.Notepad",
69                                                  Locale.getDefault());
70         } catch (MissingResourceException mre) {
71             System.err.println("resources/Notepad.properties not found");
72             System.exit(1);
73         }
74     }
75
76     public void paintChildren(Graphics g) {
77         super.paintChildren(g);
78         if (exitAfterFirstPaint) {
79             System.exit(0);
80         }
81     }
82
83     Notepad() {
84     super(true);
85
86     // Force SwingSet to come up in the Cross Platform L&F
87
try {
88         UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
89         // If you want the System L&F instead, comment out the above line and
90
// uncomment the following:
91
// UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
92
} catch (Exception JavaDoc exc) {
93         System.err.println("Error loading L&F: " + exc);
94     }
95
96     setBorder(BorderFactory.createEtchedBorder());
97     setLayout(new BorderLayout());
98
99     // create the embedded JTextComponent
100
editor = createEditor();
101     // Add this as a listener for undoable edits.
102
editor.getDocument().addUndoableEditListener(undoHandler);
103
104     // install the command table
105
commands = new Hashtable();
106     Action[] actions = getActions();
107     for (int i = 0; i < actions.length; i++) {
108         Action a = actions[i];
109         //commands.put(a.getText(Action.NAME), a);
110
commands.put(a.getValue(Action.NAME), a);
111     }
112     
113     JScrollPane scroller = new JScrollPane();
114     JViewport port = scroller.getViewport();
115     port.add(editor);
116     try {
117         String JavaDoc vpFlag = resources.getString("ViewportBackingStore");
118         Boolean JavaDoc bs = Boolean.valueOf(vpFlag);
119         port.setBackingStoreEnabled(bs.booleanValue());
120     } catch (MissingResourceException mre) {
121         // just use the viewport default
122
}
123
124     menuItems = new Hashtable();
125     JPanel panel = new JPanel();
126     panel.setLayout(new BorderLayout());
127     panel.add("North",createToolbar());
128     panel.add("Center", scroller);
129     add("Center", panel);
130     add("South", createStatusbar());
131     }
132
133     public static void main(String JavaDoc[] args) {
134         try {
135         String JavaDoc vers = System.getProperty("java.version");
136         if (vers.compareTo("1.1.2") < 0) {
137             System.out.println("!!!WARNING: Swing must be run with a " +
138                                "1.1.2 or higher version VM!!!");
139         }
140         if (args.length > 0 && args[0].equals(EXIT_AFTER_PAINT)) {
141             exitAfterFirstPaint = true;
142         }
143         JFrame frame = new JFrame();
144         frame.setTitle(resources.getString("Title"));
145     frame.setBackground(Color.lightGray);
146     frame.getContentPane().setLayout(new BorderLayout());
147         Notepad notepad = new Notepad();
148     frame.getContentPane().add("Center", notepad);
149         frame.setJMenuBar(notepad.createMenubar());
150     frame.addWindowListener(new AppCloser());
151     frame.pack();
152     frame.setSize(500, 600);
153         frame.show();
154         } catch (Throwable JavaDoc t) {
155             System.out.println("uncaught exception: " + t);
156             t.printStackTrace();
157         }
158     }
159
160     /**
161      * Fetch the list of actions supported by this
162      * editor. It is implemented to return the list
163      * of actions supported by the embedded JTextComponent
164      * augmented with the actions defined locally.
165      */

166     public Action[] getActions() {
167     return TextAction.augmentList(editor.getActions(), defaultActions);
168     }
169
170     /**
171      * Create an editor to represent the given document.
172      */

173     protected JTextComponent createEditor() {
174     JTextComponent c = new JTextArea();
175     c.setDragEnabled(true);
176     c.setFont(new Font("monospaced", Font.PLAIN, 12));
177     return c;
178     }
179
180     /**
181      * Fetch the editor contained in this panel
182      */

183     protected JTextComponent getEditor() {
184     return editor;
185     }
186
187     /**
188      * To shutdown when run as an application. This is a
189      * fairly lame implementation. A more self-respecting
190      * implementation would at least check to see if a save
191      * was needed.
192      */

193     protected static final class AppCloser extends WindowAdapter {
194         public void windowClosing(WindowEvent e) {
195         System.exit(0);
196     }
197     }
198
199     /**
200      * Find the hosting frame, for the file-chooser dialog.
201      */

202     protected Frame getFrame() {
203     for (Container p = getParent(); p != null; p = p.getParent()) {
204         if (p instanceof Frame) {
205         return (Frame) p;
206         }
207     }
208     return null;
209     }
210
211     /**
212      * This is the hook through which all menu items are
213      * created. It registers the result with the menuitem
214      * hashtable so that it can be fetched with getMenuItem().
215      * @see #getMenuItem
216      */

217     protected JMenuItem createMenuItem(String JavaDoc cmd) {
218     JMenuItem mi = new JMenuItem(getResourceString(cmd + labelSuffix));
219         URL JavaDoc url = getResource(cmd + imageSuffix);
220     if (url != null) {
221         mi.setHorizontalTextPosition(JButton.RIGHT);
222         mi.setIcon(new ImageIcon(url));
223     }
224     String JavaDoc astr = getResourceString(cmd + actionSuffix);
225     if (astr == null) {
226         astr = cmd;
227     }
228     mi.setActionCommand(astr);
229     Action a = getAction(astr);
230     if (a != null) {
231         mi.addActionListener(a);
232         a.addPropertyChangeListener(createActionChangeListener(mi));
233         mi.setEnabled(a.isEnabled());
234     } else {
235         mi.setEnabled(false);
236     }
237     menuItems.put(cmd, mi);
238     return mi;
239     }
240
241     /**
242      * Fetch the menu item that was created for the given
243      * command.
244      * @param cmd Name of the action.
245      * @returns item created for the given command or null
246      * if one wasn't created.
247      */

248     protected JMenuItem getMenuItem(String JavaDoc cmd) {
249     return (JMenuItem) menuItems.get(cmd);
250     }
251
252     protected Action getAction(String JavaDoc cmd) {
253     return (Action) commands.get(cmd);
254     }
255
256     protected String JavaDoc getResourceString(String JavaDoc nm) {
257     String JavaDoc str;
258     try {
259         str = resources.getString(nm);
260     } catch (MissingResourceException mre) {
261         str = null;
262     }
263     return str;
264     }
265
266     protected URL JavaDoc getResource(String JavaDoc key) {
267     String JavaDoc name = getResourceString(key);
268     if (name != null) {
269         URL JavaDoc url = this.getClass().getResource(name);
270         return url;
271     }
272     return null;
273     }
274
275     protected Container getToolbar() {
276     return toolbar;
277     }
278
279     protected JMenuBar getMenubar() {
280     return menubar;
281     }
282
283     /**
284      * Create a status bar
285      */

286     protected Component createStatusbar() {
287     // need to do something reasonable here
288
status = new StatusBar();
289     return status;
290     }
291
292     /**
293      * Resets the undo manager.
294      */

295     protected void resetUndoManager() {
296     undo.discardAllEdits();
297     undoAction.update();
298     redoAction.update();
299     }
300
301     /**
302      * Create the toolbar. By default this reads the
303      * resource file for the definition of the toolbar.
304      */

305     private Component createToolbar() {
306     toolbar = new JToolBar();
307     String JavaDoc[] toolKeys = tokenize(getResourceString("toolbar"));
308     for (int i = 0; i < toolKeys.length; i++) {
309         if (toolKeys[i].equals("-")) {
310         toolbar.add(Box.createHorizontalStrut(5));
311         } else {
312         toolbar.add(createTool(toolKeys[i]));
313         }
314     }
315     toolbar.add(Box.createHorizontalGlue());
316     return toolbar;
317     }
318
319     /**
320      * Hook through which every toolbar item is created.
321      */

322     protected Component createTool(String JavaDoc key) {
323     return createToolbarButton(key);
324     }
325
326     /**
327      * Create a button to go inside of the toolbar. By default this
328      * will load an image resource. The image filename is relative to
329      * the classpath (including the '.' directory if its a part of the
330      * classpath), and may either be in a JAR file or a separate file.
331      *
332      * @param key The key in the resource file to serve as the basis
333      * of lookups.
334      */

335     protected JButton createToolbarButton(String JavaDoc key) {
336     URL JavaDoc url = getResource(key + imageSuffix);
337         JButton b = new JButton(new ImageIcon(url)) {
338             public float getAlignmentY() { return 0.5f; }
339     };
340         b.setRequestFocusEnabled(false);
341         b.setMargin(new Insets(1,1,1,1));
342
343     String JavaDoc astr = getResourceString(key + actionSuffix);
344     if (astr == null) {
345         astr = key;
346     }
347     Action a = getAction(astr);
348     if (a != null) {
349         b.setActionCommand(astr);
350         b.addActionListener(a);
351     } else {
352         b.setEnabled(false);
353     }
354
355     String JavaDoc tip = getResourceString(key + tipSuffix);
356     if (tip != null) {
357         b.setToolTipText(tip);
358     }
359  
360         return b;
361     }
362
363     /**
364      * Take the given string and chop it up into a series
365      * of strings on whitespace boundaries. This is useful
366      * for trying to get an array of strings out of the
367      * resource file.
368      */

369     protected String JavaDoc[] tokenize(String JavaDoc input) {
370     Vector v = new Vector();
371     StringTokenizer t = new StringTokenizer(input);
372     String JavaDoc cmd[];
373
374     while (t.hasMoreTokens())
375         v.addElement(t.nextToken());
376     cmd = new String JavaDoc[v.size()];
377     for (int i = 0; i < cmd.length; i++)
378         cmd[i] = (String JavaDoc) v.elementAt(i);
379
380     return cmd;
381     }
382
383     /**
384      * Create the menubar for the app. By default this pulls the
385      * definition of the menu from the associated resource file.
386      */

387     protected JMenuBar createMenubar() {
388     JMenuItem mi;
389     JMenuBar mb = new JMenuBar();
390
391     String JavaDoc[] menuKeys = tokenize(getResourceString("menubar"));
392     for (int i = 0; i < menuKeys.length; i++) {
393         JMenu m = createMenu(menuKeys[i]);
394         if (m != null) {
395         mb.add(m);
396         }
397     }
398         this.menubar = mb;
399     return mb;
400     }
401
402     /**
403      * Create a menu for the app. By default this pulls the
404      * definition of the menu from the associated resource file.
405      */

406     protected JMenu createMenu(String JavaDoc key) {
407     String JavaDoc[] itemKeys = tokenize(getResourceString(key));
408     JMenu menu = new JMenu(getResourceString(key + "Label"));
409     for (int i = 0; i < itemKeys.length; i++) {
410         if (itemKeys[i].equals("-")) {
411         menu.addSeparator();
412         } else {
413         JMenuItem mi = createMenuItem(itemKeys[i]);
414         menu.add(mi);
415         }
416     }
417     return menu;
418     }
419
420     // Yarked from JMenu, ideally this would be public.
421
protected PropertyChangeListener createActionChangeListener(JMenuItem b) {
422     return new ActionChangedListener(b);
423     }
424
425     // Yarked from JMenu, ideally this would be public.
426
private class ActionChangedListener implements PropertyChangeListener {
427         JMenuItem menuItem;
428         
429         ActionChangedListener(JMenuItem mi) {
430             super();
431             this.menuItem = mi;
432         }
433         public void propertyChange(PropertyChangeEvent e) {
434             String JavaDoc propertyName = e.getPropertyName();
435             if (e.getPropertyName().equals(Action.NAME)) {
436                 String JavaDoc text = (String JavaDoc) e.getNewValue();
437                 menuItem.setText(text);
438             } else if (propertyName.equals("enabled")) {
439                 Boolean JavaDoc enabledState = (Boolean JavaDoc) e.getNewValue();
440                 menuItem.setEnabled(enabledState.booleanValue());
441             }
442         }
443     }
444
445     private JTextComponent editor;
446     private Hashtable commands;
447     private Hashtable menuItems;
448     private JMenuBar menubar;
449     private JToolBar toolbar;
450     private JComponent status;
451     private JFrame elementTreeFrame;
452     protected ElementTreePanel elementTreePanel;
453
454     protected FileDialog fileDialog;
455
456     /**
457      * Listener for the edits on the current document.
458      */

459     protected UndoableEditListener undoHandler = new UndoHandler();
460
461     /** UndoManager that we add edits to. */
462     protected UndoManager undo = new UndoManager();
463
464     /**
465      * Suffix applied to the key used in resource file
466      * lookups for an image.
467      */

468     public static final String JavaDoc imageSuffix = "Image";
469
470     /**
471      * Suffix applied to the key used in resource file
472      * lookups for a label.
473      */

474     public static final String JavaDoc labelSuffix = "Label";
475
476     /**
477      * Suffix applied to the key used in resource file
478      * lookups for an action.
479      */

480     public static final String JavaDoc actionSuffix = "Action";
481
482     /**
483      * Suffix applied to the key used in resource file
484      * lookups for tooltip text.
485      */

486     public static final String JavaDoc tipSuffix = "Tooltip";
487
488     public static final String JavaDoc openAction = "open";
489     public static final String JavaDoc newAction = "new";
490     public static final String JavaDoc saveAction = "save";
491     public static final String JavaDoc exitAction = "exit";
492     public static final String JavaDoc showElementTreeAction = "showElementTree";
493
494     class UndoHandler implements UndoableEditListener {
495
496     /**
497      * Messaged when the Document has created an edit, the edit is
498      * added to <code>undo</code>, an instance of UndoManager.
499      */

500         public void undoableEditHappened(UndoableEditEvent e) {
501         undo.addEdit(e.getEdit());
502         undoAction.update();
503         redoAction.update();
504     }
505     }
506
507     /**
508      * FIXME - I'm not very useful yet
509      */

510     class StatusBar extends JComponent {
511
512         public StatusBar() {
513         super();
514         setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
515     }
516
517         public void paint(Graphics g) {
518         super.paint(g);
519     }
520
521     }
522
523     // --- action implementations -----------------------------------
524

525     private UndoAction undoAction = new UndoAction();
526     private RedoAction redoAction = new RedoAction();
527
528     /**
529      * Actions defined by the Notepad class
530      */

531     private Action[] defaultActions = {
532     new NewAction(),
533     new OpenAction(),
534         new SaveAction(),
535     new ExitAction(),
536     new ShowElementTreeAction(),
537         undoAction,
538         redoAction
539     };
540
541     class UndoAction extends AbstractAction {
542     public UndoAction() {
543         super("Undo");
544         setEnabled(false);
545     }
546
547     public void actionPerformed(ActionEvent e) {
548         try {
549         undo.undo();
550         } catch (CannotUndoException ex) {
551         System.out.println("Unable to undo: " + ex);
552         ex.printStackTrace();
553         }
554         update();
555         redoAction.update();
556     }
557
558     protected void update() {
559         if(undo.canUndo()) {
560         setEnabled(true);
561         putValue(Action.NAME, undo.getUndoPresentationName());
562         }
563         else {
564         setEnabled(false);
565         putValue(Action.NAME, "Undo");
566         }
567     }
568     }
569
570     class RedoAction extends AbstractAction {
571     public RedoAction() {
572         super("Redo");
573         setEnabled(false);
574     }
575
576     public void actionPerformed(ActionEvent e) {
577         try {
578         undo.redo();
579         } catch (CannotRedoException ex) {
580         System.out.println("Unable to redo: " + ex);
581         ex.printStackTrace();
582         }
583         update();
584         undoAction.update();
585     }
586
587     protected void update() {
588         if(undo.canRedo()) {
589         setEnabled(true);
590         putValue(Action.NAME, undo.getRedoPresentationName());
591         }
592         else {
593         setEnabled(false);
594         putValue(Action.NAME, "Redo");
595         }
596     }
597     }
598
599     class OpenAction extends NewAction {
600
601     OpenAction() {
602         super(openAction);
603     }
604
605         public void actionPerformed(ActionEvent e) {
606         Frame frame = getFrame();
607             JFileChooser chooser = new JFileChooser();
608             int ret = chooser.showOpenDialog(frame);
609
610             if (ret != JFileChooser.APPROVE_OPTION) {
611         return;
612         }
613
614             File f = chooser.getSelectedFile();
615         if (f.isFile() && f.canRead()) {
616         Document oldDoc = getEditor().getDocument();
617         if(oldDoc != null)
618             oldDoc.removeUndoableEditListener(undoHandler);
619         if (elementTreePanel != null) {
620             elementTreePanel.setEditor(null);
621         }
622         getEditor().setDocument(new PlainDocument());
623                 frame.setTitle(f.getName());
624         Thread JavaDoc loader = new FileLoader(f, editor.getDocument());
625         loader.start();
626         } else {
627                 JOptionPane.showMessageDialog(getFrame(),
628                         "Could not open file: " + f,
629                         "Error opening file",
630                         JOptionPane.ERROR_MESSAGE);
631         }
632     }
633     }
634     
635     class SaveAction extends AbstractAction {
636
637     SaveAction() {
638         super(saveAction);
639     }
640
641         public void actionPerformed(ActionEvent e) {
642             Frame frame = getFrame();
643             JFileChooser chooser = new JFileChooser();
644             int ret = chooser.showSaveDialog(frame);
645
646             if (ret != JFileChooser.APPROVE_OPTION) {
647                 return;
648             }
649
650             File f = chooser.getSelectedFile();
651             frame.setTitle(f.getName());
652             Thread JavaDoc saver = new FileSaver(f, editor.getDocument());
653             saver.start();
654     }
655     }
656
657     class NewAction extends AbstractAction {
658
659     NewAction() {
660         super(newAction);
661     }
662
663     NewAction(String JavaDoc nm) {
664         super(nm);
665     }
666
667         public void actionPerformed(ActionEvent e) {
668         Document oldDoc = getEditor().getDocument();
669         if(oldDoc != null)
670         oldDoc.removeUndoableEditListener(undoHandler);
671         getEditor().setDocument(new PlainDocument());
672         getEditor().getDocument().addUndoableEditListener(undoHandler);
673         resetUndoManager();
674             getFrame().setTitle(resources.getString("Title"));
675         revalidate();
676     }
677     }
678
679     /**
680      * Really lame implementation of an exit command
681      */

682     class ExitAction extends AbstractAction {
683
684     ExitAction() {
685         super(exitAction);
686     }
687
688         public void actionPerformed(ActionEvent e) {
689         System.exit(0);
690     }
691     }
692
693     /**
694      * Action that brings up a JFrame with a JTree showing the structure
695      * of the document.
696      */

697     class ShowElementTreeAction extends AbstractAction {
698
699     ShowElementTreeAction() {
700         super(showElementTreeAction);
701     }
702
703     ShowElementTreeAction(String JavaDoc nm) {
704         super(nm);
705     }
706
707         public void actionPerformed(ActionEvent e) {
708         if(elementTreeFrame == null) {
709         // Create a frame containing an instance of
710
// ElementTreePanel.
711
try {
712             String JavaDoc title = resources.getString
713                             ("ElementTreeFrameTitle");
714             elementTreeFrame = new JFrame(title);
715         } catch (MissingResourceException mre) {
716             elementTreeFrame = new JFrame();
717         }
718
719         elementTreeFrame.addWindowListener(new WindowAdapter() {
720             public void windowClosing(WindowEvent weeee) {
721             elementTreeFrame.setVisible(false);
722             }
723         });
724         Container fContentPane = elementTreeFrame.getContentPane();
725
726         fContentPane.setLayout(new BorderLayout());
727         elementTreePanel = new ElementTreePanel(getEditor());
728         fContentPane.add(elementTreePanel);
729         elementTreeFrame.pack();
730         }
731         elementTreeFrame.show();
732     }
733     }
734
735     /**
736      * Thread to load a file into the text storage model
737      */

738     class FileLoader extends Thread JavaDoc {
739
740     FileLoader(File f, Document doc) {
741         setPriority(4);
742         this.f = f;
743         this.doc = doc;
744     }
745
746         public void run() {
747         try {
748         // initialize the statusbar
749
status.removeAll();
750         JProgressBar progress = new JProgressBar();
751         progress.setMinimum(0);
752         progress.setMaximum((int) f.length());
753         status.add(progress);
754         status.revalidate();
755
756         // try to start reading
757
Reader in = new FileReader(f);
758         char[] buff = new char[4096];
759         int nch;
760         while ((nch = in.read(buff, 0, buff.length)) != -1) {
761             doc.insertString(doc.getLength(), new String JavaDoc(buff, 0, nch), null);
762             progress.setValue(progress.getValue() + nch);
763         }
764         }
765         catch (IOException e) {
766                 final String JavaDoc msg = e.getMessage();
767                 SwingUtilities.invokeLater(new Runnable JavaDoc() {
768                     public void run() {
769                         JOptionPane.showMessageDialog(getFrame(),
770                                 "Could not open file: " + msg,
771                                 "Error opening file",
772                                 JOptionPane.ERROR_MESSAGE);
773         }
774                 });
775             }
776         catch (BadLocationException e) {
777         System.err.println(e.getMessage());
778         }
779             doc.addUndoableEditListener(undoHandler);
780             // we are done... get rid of progressbar
781
status.removeAll();
782             status.revalidate();
783
784             resetUndoManager();
785
786         if (elementTreePanel != null) {
787         SwingUtilities.invokeLater(new Runnable JavaDoc() {
788             public void run() {
789             elementTreePanel.setEditor(getEditor());
790             }
791         });
792         }
793     }
794
795     Document doc;
796     File f;
797     }
798
799     /**
800      * Thread to save a document to file
801      */

802     class FileSaver extends Thread JavaDoc {
803         Document doc;
804         File f;
805
806     FileSaver(File f, Document doc) {
807         setPriority(4);
808         this.f = f;
809         this.doc = doc;
810     }
811
812         public void run() {
813         try {
814         // initialize the statusbar
815
status.removeAll();
816         JProgressBar progress = new JProgressBar();
817         progress.setMinimum(0);
818         progress.setMaximum((int) doc.getLength());
819         status.add(progress);
820         status.revalidate();
821
822         // start writing
823
Writer out = new FileWriter(f);
824                 Segment text = new Segment();
825                 text.setPartialReturn(true);
826                 int charsLeft = doc.getLength();
827         int offset = 0;
828                 while (charsLeft > 0) {
829                     doc.getText(offset, Math.min(4096, charsLeft), text);
830                     out.write(text.array, text.offset, text.count);
831                     charsLeft -= text.count;
832                     offset += text.count;
833                     progress.setValue(offset);
834                     try {
835                         Thread.sleep(10);
836                     } catch (InterruptedException JavaDoc e) {
837                         e.printStackTrace();
838                     }
839                 }
840                 out.flush();
841                 out.close();
842         }
843         catch (IOException e) {
844                 final String JavaDoc msg = e.getMessage();
845                 SwingUtilities.invokeLater(new Runnable JavaDoc() {
846                     public void run() {
847                         JOptionPane.showMessageDialog(getFrame(),
848                                 "Could not save file: " + msg,
849                                 "Error saving file",
850                                 JOptionPane.ERROR_MESSAGE);
851         }
852                 });
853         }
854         catch (BadLocationException e) {
855         System.err.println(e.getMessage());
856         }
857             // we are done... get rid of progressbar
858
status.removeAll();
859             status.revalidate();
860     }
861     }
862 }
863
Popular Tags