home *** CD-ROM | disk | FTP | other *** search
Java Source | 1998-05-08 | 16.9 KB | 656 lines |
- /*
- * @(#)Notepad.java 1.7 98/02/23
- *
- * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
- *
- * This software is the confidential and proprietary information of Sun
- * Microsystems, Inc. ("Confidential Information"). You shall not
- * disclose such Confidential Information and shall use it only in
- * accordance with the terms of the license agreement you entered into
- * with Sun.
- *
- * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
- * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
- * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
- * THIS SOFTWARE OR ITS DERIVATIVES.
- *
- */
-
- import java.awt.*;
- import java.awt.event.*;
- import java.beans.*;
- import java.io.*;
- import java.net.URL;
- import java.util.*;
-
- import com.sun.java.swing.text.*;
- import com.sun.java.swing.undo.*;
- import com.sun.java.swing.event.*;
- import com.sun.java.swing.*;
-
- /**
- * Sample application using the simple text editor component that
- * supports only one font.
- *
- * @author Timothy Prinzing
- * @version 1.7 02/23/98
- */
- class Notepad extends JPanel implements UndoableEditListener {
-
- private static ResourceBundle resources;
-
- static {
- try {
- resources = ResourceBundle.getBundle("Notepad",
- Locale.getDefault());
- } catch (MissingResourceException mre) {
- System.err.println("Notepad.properties not found");
- System.exit(1);
- }
- }
-
- Notepad() {
- super(true);
-
- // Force SwingSet to come up in the Cross Platform L&F
- try {
- UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
- // If you want the System L&F instead, comment out the above line and
- // uncomment the following:
- // UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
- } catch (Exception exc) {
- System.err.println("Error loading L&F: " + exc);
- }
-
- setBorder(BorderFactory.createEtchedBorder());
- setLayout(new BorderLayout());
-
- // create the embedded JTextComponent
- editor = createEditor();
- editor.setFont(new Font("Courier", Font.PLAIN, 12));
- // Add this as a listener for undoable edits.
- editor.getDocument().addUndoableEditListener(this);
-
- // install the command table
- commands = new Hashtable();
- Action[] actions = getActions();
- for (int i = 0; i < actions.length; i++) {
- Action a = actions[i];
- //commands.put(a.getText(Action.NAME), a);
- commands.put(a.getValue(Action.NAME), a);
- }
-
- JScrollPane scroller = new JScrollPane();
- JViewport port = scroller.getViewport();
- port.add(editor);
- try {
- String vpFlag = resources.getString("ViewportBackingStore");
- Boolean bs = new Boolean(vpFlag);
- port.setBackingStoreEnabled(bs.booleanValue());
- } catch (MissingResourceException mre) {
- // just use the viewport default
- }
-
- menuItems = new Hashtable();
- menubar = createMenubar();
- add("North", menubar);
- JPanel panel = new JPanel();
- panel.setLayout(new BorderLayout());
- panel.add("North",createToolbar());
- panel.add("Center", scroller);
- add("Center", panel);
- add("South", createStatusbar());
- }
-
- public static void main(String[] args) {
- try {
- String vers = System.getProperty("java.version");
- if (vers.compareTo("1.1.2") < 0) {
- System.out.println("!!!WARNING: Swing must be run with a " +
- "1.1.2 or higher version VM!!!");
- }
- JFrame frame = new JFrame();
- frame.setTitle(resources.getString("Title"));
- frame.setBackground(Color.lightGray);
- frame.getContentPane().setLayout(new BorderLayout());
- frame.getContentPane().add("Center", new Notepad());
- frame.addWindowListener(new AppCloser());
- frame.pack();
- frame.setSize(500, 600);
- frame.show();
- } catch (Throwable t) {
- System.out.println("uncaught exception: " + t);
- t.printStackTrace();
- }
- }
-
- /**
- * Messaged when the Document has created an edit, the edit is
- * added to <code>undo</code>, an instance of UndoManager.
- */
- public void undoableEditHappened(UndoableEditEvent e) {
- undo.addEdit(e.getEdit());
- undoAction.update();
- redoAction.update();
- }
-
- /**
- * Fetch the list of actions supported by this
- * editor. It is implemented to return the list
- * of actions supported by the embedded JTextComponent
- * augmented with the actions defined locally.
- */
- public Action[] getActions() {
- return TextAction.augmentList(editor.getActions(), defaultActions);
- }
-
- /**
- * Create an editor to represent the given document.
- */
- protected JTextComponent createEditor() {
- return new JTextArea();
- }
-
- /**
- * Fetch the editor contained in this panel
- */
- protected JTextComponent getEditor() {
- return editor;
- }
-
- /**
- * To shutdown when run as an application. This is a
- * fairly lame implementation. A more self-respecting
- * implementation would at least check to see if a save
- * was needed.
- */
- protected static final class AppCloser extends WindowAdapter {
- public void windowClosing(WindowEvent e) {
- System.exit(0);
- }
- }
-
- /**
- * Find the hosting frame, for the file-chooser dialog.
- */
- protected Frame getFrame() {
- for (Container p = getParent(); p != null; p = p.getParent()) {
- if (p instanceof Frame) {
- return (Frame) p;
- }
- }
- return null;
- }
-
- /**
- * This is the hook through which all menu items are
- * created. It registers the result with the menuitem
- * hashtable so that it can be fetched with getMenuItem().
- * @see #getMenuItem
- */
- protected JMenuItem createMenuItem(String cmd) {
- JMenuItem mi = new JMenuItem(getResourceString(cmd + labelSuffix));
- URL url = getResource(cmd + imageSuffix);
- if (url != null) {
- mi.setHorizontalTextPosition(JButton.RIGHT);
- mi.setIcon(new ImageIcon(url));
- }
- String astr = getResourceString(cmd + actionSuffix);
- if (astr == null) {
- astr = cmd;
- }
- mi.setActionCommand(astr);
- Action a = getAction(astr);
- if (a != null) {
- mi.addActionListener(a);
- a.addPropertyChangeListener(createActionChangeListener(mi));
- mi.setEnabled(a.isEnabled());
- } else {
- mi.setEnabled(false);
- }
- menuItems.put(cmd, mi);
- return mi;
- }
-
- /**
- * Fetch the menu item that was created for the given
- * command.
- * @param cmd Name of the action.
- * @returns item created for the given command or null
- * if one wasn't created.
- */
- protected JMenuItem getMenuItem(String cmd) {
- return (JMenuItem) menuItems.get(cmd);
- }
-
- protected Action getAction(String cmd) {
- return (Action) commands.get(cmd);
- }
-
- protected String getResourceString(String nm) {
- String str;
- try {
- str = resources.getString(nm);
- } catch (MissingResourceException mre) {
- str = null;
- }
- return str;
- }
-
- protected URL getResource(String key) {
- String name = getResourceString(key);
- if (name != null) {
- URL url = this.getClass().getResource(name);
- return url;
- }
- return null;
- }
-
- protected Container getToolbar() {
- return toolbar;
- }
-
- protected JMenuBar getMenubar() {
- return menubar;
- }
-
- /**
- * Create a status bar
- */
- protected Component createStatusbar() {
- // need to do something reasonable here
- status = new StatusBar();
- return status;
- }
-
- /**
- * Create the toolbar. By default this reads the
- * resource file for the definition of the toolbar.
- */
- private Component createToolbar() {
- toolbar = new JToolBar();
- String[] toolKeys = tokenize(getResourceString("toolbar"));
- for (int i = 0; i < toolKeys.length; i++) {
- if (toolKeys[i].equals("-")) {
- toolbar.add(Box.createHorizontalStrut(5));
- } else {
- toolbar.add(createTool(toolKeys[i]));
- }
- }
- toolbar.add(Box.createHorizontalGlue());
- return toolbar;
- }
-
- /**
- * Hook through which every toolbar item is created.
- */
- protected Component createTool(String key) {
- return createToolbarButton(key);
- }
-
- /**
- * Create a button to go inside of the toolbar. By default this
- * will load an image resource. The image filename is relative to
- * the classpath (including the '.' directory if its a part of the
- * classpath), and may either be in a JAR file or a separate file.
- *
- * @param key The key in the resource file to serve as the basis
- * of lookups.
- */
- protected JButton createToolbarButton(String key) {
- URL url = getResource(key + imageSuffix);
- JButton b = new JButton(new ImageIcon(url)) {
- public float getAlignmentY() { return 0.5f; }
- };
- b.setRequestFocusEnabled(false);
- b.setMargin(new Insets(1,1,1,1));
-
- String astr = getResourceString(key + actionSuffix);
- if (astr == null) {
- astr = key;
- }
- Action a = getAction(astr);
- if (a != null) {
- b.setActionCommand(astr);
- b.addActionListener(a);
- } else {
- b.setEnabled(false);
- }
-
- String tip = getResourceString(key + tipSuffix);
- if (tip != null) {
- b.setToolTipText(tip);
- }
-
- return b;
- }
-
- /**
- * Take the given string and chop it up into a series
- * of strings on whitespace boundries. This is useful
- * for trying to get an array of strings out of the
- * resource file.
- */
- protected String[] tokenize(String input) {
- Vector v = new Vector();
- StringTokenizer t = new StringTokenizer(input);
- String cmd[];
-
- while (t.hasMoreTokens())
- v.addElement(t.nextToken());
- cmd = new String[v.size()];
- for (int i = 0; i < cmd.length; i++)
- cmd[i] = (String) v.elementAt(i);
-
- return cmd;
- }
-
- /**
- * Create the menubar for the app. By default this pulls the
- * definition of the menu from the associated resource file.
- */
- protected JMenuBar createMenubar() {
- JMenuItem mi;
- JMenuBar mb = new JMenuBar();
-
- String[] menuKeys = tokenize(getResourceString("menubar"));
- for (int i = 0; i < menuKeys.length; i++) {
- JMenu m = createMenu(menuKeys[i]);
- if (m != null) {
- mb.add(m);
- }
- }
- return mb;
- }
-
- /**
- * Create a menu for the app. By default this pulls the
- * definition of the menu from the associated resource file.
- */
- protected JMenu createMenu(String key) {
- String[] itemKeys = tokenize(getResourceString(key));
- JMenu menu = new JMenu(getResourceString(key + "Label"));
- for (int i = 0; i < itemKeys.length; i++) {
- if (itemKeys[i].equals("-")) {
- menu.addSeparator();
- } else {
- JMenuItem mi = createMenuItem(itemKeys[i]);
- menu.add(mi);
- }
- }
- return menu;
- }
-
- // Yarked from JMenu, ideally this would be public.
- protected PropertyChangeListener createActionChangeListener(JMenuItem b) {
- return new ActionChangedListener(b);
- }
-
- // Yarked from JMenu, ideally this would be public.
- private class ActionChangedListener implements PropertyChangeListener {
- JMenuItem menuItem;
-
- ActionChangedListener(JMenuItem mi) {
- super();
- this.menuItem = mi;
- }
- public void propertyChange(PropertyChangeEvent e) {
- String propertyName = e.getPropertyName();
- if (e.getPropertyName().equals(Action.NAME)) {
- String text = (String) e.getNewValue();
- menuItem.setText(text);
- } else if (propertyName.equals("enabled")) {
- Boolean enabledState = (Boolean) e.getNewValue();
- menuItem.setEnabled(enabledState.booleanValue());
- }
- }
- }
-
- private JTextComponent editor;
- private Hashtable commands;
- private Hashtable menuItems;
- private JMenuBar menubar;
- private JToolBar toolbar;
- private JComponent status;
-
- protected FileDialog fileDialog;
-
- /** UndoManager that we add edits to. */
- protected UndoManager undo = new UndoManager();
-
- /**
- * Suffix applied to the key used in resource file
- * lookups for an image.
- */
- public static final String imageSuffix = "Image";
-
- /**
- * Suffix applied to the key used in resource file
- * lookups for a label.
- */
- public static final String labelSuffix = "Label";
-
- /**
- * Suffix applied to the key used in resource file
- * lookups for an action.
- */
- public static final String actionSuffix = "Action";
-
- /**
- * Suffix applied to the key used in resource file
- * lookups for tooltip text.
- */
- public static final String tipSuffix = "Tooltip";
-
- public static final String openAction = "open";
- public static final String newAction = "new";
- public static final String saveAction = "save";
- public static final String exitAction = "exit";
-
- /**
- * FIXME - I'm not very useful yet
- */
- class StatusBar extends JComponent {
-
- public StatusBar() {
- super();
- setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
- }
-
- public void paint(Graphics g) {
- super.paint(g);
- }
-
- }
-
- // --- action implementations -----------------------------------
-
- private UndoAction undoAction = new UndoAction();
- private RedoAction redoAction = new RedoAction();
-
- /**
- * Actions defined by the Notepad class
- */
- private Action[] defaultActions = {
- new NewAction(),
- new OpenAction(),
- new ExitAction(),
- undoAction,
- redoAction
- };
-
- class UndoAction extends AbstractAction {
- public UndoAction() {
- super("Undo");
- setEnabled(false);
- }
-
- public void actionPerformed(ActionEvent e) {
- try {
- undo.undo();
- } catch (CannotUndoException ex) {
- System.out.println("Unable to undo: " + ex);
- ex.printStackTrace();
- }
- update();
- redoAction.update();
- }
-
- protected void update() {
- if(undo.canUndo()) {
- setEnabled(true);
- putValue(Action.NAME, undo.getUndoPresentationName());
- }
- else {
- setEnabled(false);
- putValue(Action.NAME, "Undo");
- }
- }
- }
-
- class RedoAction extends AbstractAction {
- public RedoAction() {
- super("Redo");
- setEnabled(false);
- }
-
- public void actionPerformed(ActionEvent e) {
- try {
- undo.redo();
- } catch (CannotRedoException ex) {
- System.out.println("Unable to redo: " + ex);
- ex.printStackTrace();
- }
- update();
- undoAction.update();
- }
-
- protected void update() {
- if(undo.canRedo()) {
- setEnabled(true);
- putValue(Action.NAME, undo.getRedoPresentationName());
- }
- else {
- setEnabled(false);
- putValue(Action.NAME, "Redo");
- }
- }
- }
-
- class OpenAction extends NewAction {
-
- OpenAction() {
- super(openAction);
- }
-
- public void actionPerformed(ActionEvent e) {
- Frame frame = getFrame();
- if (fileDialog == null) {
- fileDialog = new FileDialog(frame);
- }
- fileDialog.setMode(FileDialog.LOAD);
- fileDialog.show();
-
- String file = fileDialog.getFile();
- if (file == null) {
- return;
- }
- String directory = fileDialog.getDirectory();
- File f = new File(directory, file);
- if (f.exists()) {
- Document oldDoc = getEditor().getDocument();
- if(oldDoc != null)
- oldDoc.removeUndoableEditListener(Notepad.this);
- getEditor().setDocument(new PlainDocument());
- frame.setTitle(file);
- Thread loader = new FileLoader(f, editor.getDocument());
- loader.start();
- }
- }
- }
-
- class NewAction extends AbstractAction {
-
- NewAction() {
- super(newAction);
- }
-
- NewAction(String nm) {
- super(nm);
- }
-
- public void actionPerformed(ActionEvent e) {
- Document oldDoc = getEditor().getDocument();
- if(oldDoc != null)
- oldDoc.removeUndoableEditListener(Notepad.this);
- getEditor().setDocument(new PlainDocument());
- getEditor().getDocument().addUndoableEditListener(Notepad.this);
- revalidate();
- }
- }
-
- /**
- * Really lame implementation of an exit command
- */
- class ExitAction extends AbstractAction {
-
- ExitAction() {
- super(exitAction);
- }
-
- public void actionPerformed(ActionEvent e) {
- System.exit(0);
- }
- }
-
- /**
- * Thread to load a file into the text storage model
- */
- class FileLoader extends Thread {
-
- FileLoader(File f, Document doc) {
- setPriority(4);
- this.f = f;
- this.doc = doc;
- }
-
- public void run() {
- try {
- // initialize the statusbar
- status.removeAll();
- JProgressBar progress = new JProgressBar();
- progress.setMinimum(0);
- progress.setMaximum((int) f.length());
- status.add(progress);
- status.revalidate();
-
- // try to start reading
- Reader in = new FileReader(f);
- char[] buff = new char[4096];
- int nch;
- while ((nch = in.read(buff, 0, buff.length)) != -1) {
- doc.insertString(doc.getLength(), new String(buff, 0, nch), null);
- progress.setValue(progress.getValue() + nch);
- }
-
- // we are done... get rid of progressbar
- doc.addUndoableEditListener(Notepad.this);
- status.removeAll();
- status.revalidate();
- }
- catch (IOException e) {
- System.err.println(e.toString());
- }
- catch (BadLocationException e) {
- System.err.println(e.getMessage());
- }
- }
-
- Document doc;
- File f;
- }
-
- }
-