OpenJDK / jdk / hs
changeset 8967:57934762bad8
7027697: /jfc/Notepad demo needs to be improved
Reviewed-by: rupashka
author | mrkam |
---|---|
date | Fri, 25 Mar 2011 13:24:39 +0100 |
parents | ccf9551ddbd8 |
children | 46991a517c09 |
files | jdk/src/share/demo/jfc/Notepad/ElementTreePanel.java jdk/src/share/demo/jfc/Notepad/Notepad.java |
diffstat | 2 files changed, 359 insertions(+), 256 deletions(-) [+] |
line wrap: on
line diff
--- a/jdk/src/share/demo/jfc/Notepad/ElementTreePanel.java Fri Mar 25 13:23:09 2011 +0100 +++ b/jdk/src/share/demo/jfc/Notepad/ElementTreePanel.java Fri Mar 25 13:24:39 2011 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2000, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -29,17 +29,36 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - */ -import javax.swing.*; -import javax.swing.event.*; -import javax.swing.text.*; -import javax.swing.tree.*; -import javax.swing.undo.*; -import java.awt.*; -import java.beans.*; +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Font; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; import java.util.*; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTree; +import javax.swing.SwingConstants; +import javax.swing.event.CaretEvent; +import javax.swing.event.CaretListener; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.text.AttributeSet; +import javax.swing.text.Document; +import javax.swing.text.Element; +import javax.swing.text.JTextComponent; +import javax.swing.text.StyleConstants; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeCellRenderer; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreeModel; +import javax.swing.tree.TreeNode; +import javax.swing.tree.TreePath; + /** * Displays a tree showing all the elements in a text Document. Selecting @@ -49,16 +68,20 @@ * * @author Scott Violet */ -public class ElementTreePanel extends JPanel implements CaretListener, DocumentListener, PropertyChangeListener, TreeSelectionListener { +@SuppressWarnings("serial") +public class ElementTreePanel extends JPanel implements CaretListener, + DocumentListener, PropertyChangeListener, TreeSelectionListener { + /** Tree showing the documents element structure. */ - protected JTree tree; + protected JTree tree; /** Text component showing elemenst for. */ - protected JTextComponent editor; + protected JTextComponent editor; /** Model for the tree. */ - protected ElementTreeModel treeModel; + protected ElementTreeModel treeModel; /** Set to true when updatin the selection. */ - protected boolean updatingSelection; + protected boolean updatingSelection; + @SuppressWarnings("LeakingThisInConstructor") public ElementTreePanel(JTextComponent editor) { this.editor = editor; @@ -67,25 +90,28 @@ // Create the tree. treeModel = new ElementTreeModel(document); tree = new JTree(treeModel) { + + @Override public String convertValueToText(Object value, boolean selected, - boolean expanded, boolean leaf, - int row, boolean hasFocus) { + boolean expanded, boolean leaf, + int row, boolean hasFocus) { // Should only happen for the root - if(!(value instanceof Element)) + if (!(value instanceof Element)) { return value.toString(); + } - Element e = (Element)value; - AttributeSet as = e.getAttributes().copyAttributes(); - String asString; + Element e = (Element) value; + AttributeSet as = e.getAttributes().copyAttributes(); + String asString; - if(as != null) { - StringBuffer retBuffer = new StringBuffer("["); - Enumeration names = as.getAttributeNames(); + if (as != null) { + StringBuilder retBuffer = new StringBuilder("["); + Enumeration names = as.getAttributeNames(); - while(names.hasMoreElements()) { - Object nextName = names.nextElement(); + while (names.hasMoreElements()) { + Object nextName = names.nextElement(); - if(nextName != StyleConstants.ResolveAttribute) { + if (nextName != StyleConstants.ResolveAttribute) { retBuffer.append(" "); retBuffer.append(nextName); retBuffer.append("="); @@ -94,16 +120,16 @@ } retBuffer.append(" ]"); asString = retBuffer.toString(); + } else { + asString = "[ ]"; } - else - asString = "[ ]"; - if(e.isLeaf()) - return e.getName() + " [" + e.getStartOffset() + - ", " + e.getEndOffset() +"] Attributes: " + asString; - return e.getName() + " [" + e.getStartOffset() + - ", " + e.getEndOffset() + "] Attributes: " + - asString; + if (e.isLeaf()) { + return e.getName() + " [" + e.getStartOffset() + ", " + e. + getEndOffset() + "] Attributes: " + asString; + } + return e.getName() + " [" + e.getStartOffset() + ", " + e. + getEndOffset() + "] Attributes: " + asString; } }; tree.addTreeSelectionListener(this); @@ -117,10 +143,13 @@ // This is a temporary workaround, increase the needed size by 15, // hoping that will be enough. tree.setCellRenderer(new DefaultTreeCellRenderer() { + + @Override public Dimension getPreferredSize() { Dimension retValue = super.getPreferredSize(); - if(retValue != null) + if (retValue != null) { retValue.width += 15; + } return retValue; } }); @@ -139,7 +168,8 @@ add(new JScrollPane(tree), BorderLayout.CENTER); // Add a label above tree to describe what is being shown - JLabel label = new JLabel("Elements that make up the current document", SwingConstants.CENTER); + JLabel label = new JLabel("Elements that make up the current document", + SwingConstants.CENTER); label.setFont(new Font("Dialog", Font.BOLD, 14)); add(label, BorderLayout.NORTH); @@ -157,7 +187,7 @@ } if (this.editor != null) { - Document oldDoc = this.editor.getDocument(); + Document oldDoc = this.editor.getDocument(); oldDoc.removeDocumentListener(this); this.editor.removePropertyChangeListener(this); @@ -167,9 +197,8 @@ if (editor == null) { treeModel = null; tree.setModel(null); - } - else { - Document newDoc = editor.getDocument(); + } else { + Document newDoc = editor.getDocument(); newDoc.addDocumentListener(this); editor.addPropertyChangeListener(this); @@ -180,17 +209,15 @@ } // PropertyChangeListener - /** * Invoked when a property changes. We are only interested in when the * Document changes to reset the DocumentListener. */ public void propertyChange(PropertyChangeEvent e) { - if (e.getSource() == getEditor() && - e.getPropertyName().equals("document")) { - JTextComponent editor = getEditor(); - Document oldDoc = (Document)e.getOldValue(); - Document newDoc = (Document)e.getNewValue(); + if (e.getSource() == getEditor() && e.getPropertyName().equals( + "document")) { + Document oldDoc = (Document) e.getOldValue(); + Document newDoc = (Document) e.getNewValue(); // Reset the DocumentListener oldDoc.removeDocumentListener(this); @@ -202,9 +229,7 @@ } } - // DocumentListener - /** * Gives notification that there was an insert into the document. The * given range bounds the freshly inserted region. @@ -236,53 +261,50 @@ } // CaretListener - /** * Messaged when the selection in the editor has changed. Will update * the selection in the tree. */ public void caretUpdate(CaretEvent e) { - if(!updatingSelection) { - JTextComponent editor = getEditor(); - int selBegin = Math.min(e.getDot(), e.getMark()); - int end = Math.max(e.getDot(), e.getMark()); - Vector paths = new Vector(); - TreeModel model = getTreeModel(); - Object root = model.getRoot(); - int rootCount = model.getChildCount(root); + if (!updatingSelection) { + int selBegin = Math.min(e.getDot(), e.getMark()); + int end = Math.max(e.getDot(), e.getMark()); + List<TreePath> paths = new ArrayList<TreePath>(); + TreeModel model = getTreeModel(); + Object root = model.getRoot(); + int rootCount = model.getChildCount(root); // Build an array of all the paths to all the character elements // in the selection. - for(int counter = 0; counter < rootCount; counter++) { - int start = selBegin; + for (int counter = 0; counter < rootCount; counter++) { + int start = selBegin; - while(start <= end) { - TreePath path = getPathForIndex(start, root, - (Element)model.getChild(root, counter)); - Element charElement = (Element)path. - getLastPathComponent(); + while (start <= end) { + TreePath path = getPathForIndex(start, root, + (Element) model.getChild(root, counter)); + Element charElement = (Element) path.getLastPathComponent(); - paths.addElement(path); - if(start >= charElement.getEndOffset()) + paths.add(path); + if (start >= charElement.getEndOffset()) { start++; - else + } else { start = charElement.getEndOffset(); + } } } // If a path was found, select it (them). - int numPaths = paths.size(); + int numPaths = paths.size(); - if(numPaths > 0) { - TreePath[] pathArray = new TreePath[numPaths]; + if (numPaths > 0) { + TreePath[] pathArray = new TreePath[numPaths]; - paths.copyInto(pathArray); + paths.toArray(pathArray); updatingSelection = true; try { getTree().setSelectionPaths(pathArray); getTree().scrollPathToVisible(pathArray[0]); - } - finally { + } finally { updatingSelection = false; } } @@ -290,27 +312,24 @@ } // TreeSelectionListener - /** - * Called whenever the value of the selection changes. - * @param e the event that characterizes the change. - */ + * Called whenever the value of the selection changes. + * @param e the event that characterizes the change. + */ public void valueChanged(TreeSelectionEvent e) { - JTree tree = getTree(); - if(!updatingSelection && tree.getSelectionCount() == 1) { - TreePath selPath = tree.getSelectionPath(); - Object lastPathComponent = selPath.getLastPathComponent(); + if (!updatingSelection && tree.getSelectionCount() == 1) { + TreePath selPath = tree.getSelectionPath(); + Object lastPathComponent = selPath.getLastPathComponent(); - if(!(lastPathComponent instanceof DefaultMutableTreeNode)) { - Element selElement = (Element)lastPathComponent; + if (!(lastPathComponent instanceof DefaultMutableTreeNode)) { + Element selElement = (Element) lastPathComponent; updatingSelection = true; try { getEditor().select(selElement.getStartOffset(), - selElement.getEndOffset()); - } - finally { + selElement.getEndOffset()); + } finally { updatingSelection = false; } } @@ -318,7 +337,6 @@ } // Local methods - /** * @return tree showing elements. */ @@ -347,15 +365,14 @@ protected void updateTree(DocumentEvent event) { updatingSelection = true; try { - TreeModel model = getTreeModel(); - Object root = model.getRoot(); + TreeModel model = getTreeModel(); + Object root = model.getRoot(); - for(int counter = model.getChildCount(root) - 1; counter >= 0; - counter--) { - updateTree(event, (Element)model.getChild(root, counter)); + for (int counter = model.getChildCount(root) - 1; counter >= 0; + counter--) { + updateTree(event, (Element) model.getChild(root, counter)); } - } - finally { + } finally { updatingSelection = false; } } @@ -372,53 +389,50 @@ DocumentEvent.ElementChange ec = event.getChange(element); if (ec != null) { - Element[] removed = ec.getChildrenRemoved(); - Element[] added = ec.getChildrenAdded(); - int startIndex = ec.getIndex(); + Element[] removed = ec.getChildrenRemoved(); + Element[] added = ec.getChildrenAdded(); + int startIndex = ec.getIndex(); // Check for removed. - if(removed != null && removed.length > 0) { - int[] indices = new int[removed.length]; + if (removed != null && removed.length > 0) { + int[] indices = new int[removed.length]; - for(int counter = 0; counter < removed.length; counter++) { + for (int counter = 0; counter < removed.length; counter++) { indices[counter] = startIndex + counter; } - getTreeModel().nodesWereRemoved((TreeNode)element, indices, - removed); + getTreeModel().nodesWereRemoved((TreeNode) element, indices, + removed); } // check for added - if(added != null && added.length > 0) { - int[] indices = new int[added.length]; + if (added != null && added.length > 0) { + int[] indices = new int[added.length]; - for(int counter = 0; counter < added.length; counter++) { + for (int counter = 0; counter < added.length; counter++) { indices[counter] = startIndex + counter; } - getTreeModel().nodesWereInserted((TreeNode)element, indices); + getTreeModel().nodesWereInserted((TreeNode) element, indices); } } - if(!element.isLeaf()) { - int startIndex = element.getElementIndex - (event.getOffset()); - int elementCount = element.getElementCount(); - int endIndex = Math.min(elementCount - 1, - element.getElementIndex - (event.getOffset() + event.getLength())); + if (!element.isLeaf()) { + int startIndex = element.getElementIndex(event.getOffset()); + int elementCount = element.getElementCount(); + int endIndex = Math.min(elementCount - 1, + element.getElementIndex(event.getOffset() + + event.getLength())); - if(startIndex > 0 && startIndex < elementCount && - element.getElement(startIndex).getStartOffset() == - event.getOffset()) { + if (startIndex > 0 && startIndex < elementCount && element. + getElement(startIndex).getStartOffset() == event.getOffset()) { // Force checking the previous element. startIndex--; } - if(startIndex != -1 && endIndex != -1) { - for(int counter = startIndex; counter <= endIndex; counter++) { + if (startIndex != -1 && endIndex != -1) { + for (int counter = startIndex; counter <= endIndex; counter++) { updateTree(event, element.getElement(counter)); } } - } - else { + } else { // Element is a leaf, assume it changed - getTreeModel().nodeChanged((TreeNode)element); + getTreeModel().nodeChanged((TreeNode) element); } } @@ -426,14 +440,14 @@ * Returns a TreePath to the element at <code>position</code>. */ protected TreePath getPathForIndex(int position, Object root, - Element rootElement) { - TreePath path = new TreePath(root); - Element child = rootElement.getElement - (rootElement.getElementIndex(position)); + Element rootElement) { + TreePath path = new TreePath(root); + Element child = rootElement.getElement(rootElement.getElementIndex( + position)); path = path.pathByAddingChild(rootElement); path = path.pathByAddingChild(child); - while(!child.isLeaf()) { + while (!child.isLeaf()) { child = child.getElement(child.getElementIndex(position)); path = path.pathByAddingChild(child); } @@ -456,7 +470,8 @@ * methods have been subclassed, primarily to special case the root. */ public static class ElementTreeModel extends DefaultTreeModel { - protected Element[] rootElements; + + protected Element[] rootElements; public ElementTreeModel(Document document) { super(new DefaultMutableTreeNode("root"), false); @@ -474,13 +489,14 @@ * @param parent a node in the tree, obtained from this data source * @return the child of <I>parent</I> at index <I>index</I> */ + @Override public Object getChild(Object parent, int index) { - if(parent == root) + if (parent == root) { return rootElements[index]; + } return super.getChild(parent, index); } - /** * Returns the number of children of <I>parent</I>. Returns 0 * if the node is a leaf or if it has no children. @@ -490,13 +506,14 @@ * @param parent a node in the tree, obtained from this data source * @return the number of children of the node <I>parent</I> */ + @Override public int getChildCount(Object parent) { - if(parent == root) + if (parent == root) { return rootElements.length; + } return super.getChildCount(parent); } - /** * Returns true if <I>node</I> is a leaf. It is possible for * this method to return false even if <I>node</I> has no @@ -507,21 +524,25 @@ * @param node a node in the tree, obtained from this data source * @return true if <I>node</I> is a leaf */ + @Override public boolean isLeaf(Object node) { - if(node == root) + if (node == root) { return false; + } return super.isLeaf(node); } /** * Returns the index of child in parent. */ + @Override public int getIndexOfChild(Object parent, Object child) { - if(parent == root) { - for(int counter = rootElements.length - 1; counter >= 0; - counter--) { - if(rootElements[counter] == child) + if (parent == root) { + for (int counter = rootElements.length - 1; counter >= 0; + counter--) { + if (rootElements[counter] == child) { return counter; + } } return -1; } @@ -532,18 +553,19 @@ * Invoke this method after you've changed how node is to be * represented in the tree. */ + @Override public void nodeChanged(TreeNode node) { - if(listenerList != null && node != null) { - TreeNode parent = node.getParent(); + if (listenerList != null && node != null) { + TreeNode parent = node.getParent(); - if(parent == null && node != root) { + if (parent == null && node != root) { parent = root; } - if(parent != null) { - int anIndex = getIndexOfChild(parent, node); + if (parent != null) { + int anIndex = getIndexOfChild(parent, node); - if(anIndex != -1) { - int[] cIndexs = new int[1]; + if (anIndex != -1) { + int[] cIndexs = new int[1]; cIndexs[0] = anIndex; nodesChanged(parent, cIndexs); @@ -555,26 +577,28 @@ /** * Returns the path to a particluar node. This is recursive. */ + @Override protected TreeNode[] getPathToRoot(TreeNode aNode, int depth) { - TreeNode[] retNodes; + TreeNode[] retNodes; /* Check for null, in case someone passed in a null node, or - they passed in an element that isn't rooted at root. */ - if(aNode == null) { - if(depth == 0) + they passed in an element that isn't rooted at root. */ + if (aNode == null) { + if (depth == 0) { return null; - else + } else { retNodes = new TreeNode[depth]; - } - else { + } + } else { depth++; - if(aNode == root) + if (aNode == root) { retNodes = new TreeNode[depth]; - else { + } else { TreeNode parent = aNode.getParent(); - if(parent == null) + if (parent == null) { parent = root; + } retNodes = getPathToRoot(parent, depth); } retNodes[retNodes.length - depth] = aNode;
--- a/jdk/src/share/demo/jfc/Notepad/Notepad.java Fri Mar 25 13:23:09 2011 +0100 +++ b/jdk/src/share/demo/jfc/Notepad/Notepad.java Fri Mar 25 13:24:39 2011 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -29,20 +29,73 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - */ -import java.awt.*; -import java.awt.event.*; -import java.beans.*; -import java.io.*; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.FileDialog; +import java.awt.Font; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Insets; +import java.awt.event.ActionEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.Reader; +import java.io.Writer; import java.net.URL; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.MissingResourceException; +import java.util.ResourceBundle; +import java.util.StringTokenizer; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.BorderFactory; +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JProgressBar; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; +import javax.swing.JToolBar; +import javax.swing.JViewport; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.UIManager.LookAndFeelInfo; +import javax.swing.event.UndoableEditEvent; +import javax.swing.event.UndoableEditListener; +import javax.swing.text.BadLocationException; +import javax.swing.text.Document; +import javax.swing.text.JTextComponent; +import javax.swing.text.PlainDocument; +import javax.swing.text.Segment; +import javax.swing.text.TextAction; +import javax.swing.undo.CannotRedoException; +import javax.swing.undo.CannotUndoException; +import javax.swing.undo.UndoManager; -import javax.swing.text.*; -import javax.swing.undo.*; -import javax.swing.event.*; -import javax.swing.*; /** * Sample application using the simple text editor component that @@ -50,22 +103,24 @@ * * @author Timothy Prinzing */ +@SuppressWarnings("serial") class Notepad extends JPanel { private static ResourceBundle resources; - private final static String EXIT_AFTER_PAINT = new String("-exit"); + private final static String EXIT_AFTER_PAINT = "-exit"; private static boolean exitAfterFirstPaint; static { try { resources = ResourceBundle.getBundle("resources.Notepad", - Locale.getDefault()); + Locale.getDefault()); } catch (MissingResourceException mre) { System.err.println("resources/Notepad.properties not found"); System.exit(1); } } + @Override public void paintChildren(Graphics g) { super.paintChildren(g); if (exitAfterFirstPaint) { @@ -73,17 +128,19 @@ } } + @SuppressWarnings("OverridableMethodCallInConstructor") Notepad() { super(true); - // Force SwingSet to come up in the Cross Platform L&F + // Trying to set Nimbus look and feel 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); + for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) { + if ("Nimbus".equals(info.getName())) { + UIManager.setLookAndFeel(info.getClassName()); + break; + } + } + } catch (Exception ignored) { } setBorder(BorderFactory.createEtchedBorder()); @@ -95,7 +152,7 @@ editor.getDocument().addUndoableEditListener(undoHandler); // install the command table - commands = new Hashtable(); + commands = new HashMap<Object, Action>(); Action[] actions = getActions(); for (int i = 0; i < actions.length; i++) { Action a = actions[i]; @@ -109,15 +166,17 @@ try { String vpFlag = resources.getString("ViewportBackingStore"); Boolean bs = Boolean.valueOf(vpFlag); - port.setBackingStoreEnabled(bs.booleanValue()); - } catch (MissingResourceException mre) { + port.setScrollMode(bs.booleanValue() + ? JViewport.BACKINGSTORE_SCROLL_MODE + : JViewport.BLIT_SCROLL_MODE); + } catch (MissingResourceException ignored) { // just use the viewport default } - menuItems = new Hashtable(); + menuItems = new HashMap<String, JMenuItem>(); JPanel panel = new JPanel(); panel.setLayout(new BorderLayout()); - panel.add("North",createToolbar()); + panel.add("North", createToolbar()); panel.add("Center", scroller); add("Center", panel); add("South", createStatusbar()); @@ -125,28 +184,28 @@ 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!!!"); - } - if (args.length > 0 && args[0].equals(EXIT_AFTER_PAINT)) { - exitAfterFirstPaint = true; - } - JFrame frame = new JFrame(); - frame.setTitle(resources.getString("Title")); - frame.setBackground(Color.lightGray); - frame.getContentPane().setLayout(new BorderLayout()); - Notepad notepad = new Notepad(); - frame.getContentPane().add("Center", notepad); - frame.setJMenuBar(notepad.createMenubar()); - frame.addWindowListener(new AppCloser()); - frame.pack(); - frame.setSize(500, 600); - frame.show(); + if (args.length > 0 && args[0].equals(EXIT_AFTER_PAINT)) { + exitAfterFirstPaint = true; + } + SwingUtilities.invokeAndWait(new Runnable() { + + public void run() { + JFrame frame = new JFrame(); + frame.setTitle(resources.getString("Title")); + frame.setBackground(Color.lightGray); + frame.getContentPane().setLayout(new BorderLayout()); + Notepad notepad = new Notepad(); + frame.getContentPane().add("Center", notepad); + frame.setJMenuBar(notepad.createMenubar()); + frame.addWindowListener(new AppCloser()); + frame.pack(); + frame.setSize(500, 600); + frame.setVisible(true); + } + }); } catch (Throwable t) { - System.out.println("uncaught exception: " + t); - t.printStackTrace(); + Logger.getLogger(Notepad.class.getName()).log(Level.SEVERE, + "uncaught exception", t); } } @@ -177,6 +236,7 @@ return editor; } + /** * To shutdown when run as an application. This is a * fairly lame implementation. A more self-respecting @@ -184,6 +244,8 @@ * was needed. */ protected static final class AppCloser extends WindowAdapter { + + @Override public void windowClosing(WindowEvent e) { System.exit(0); } @@ -239,11 +301,11 @@ * if one wasn't created. */ protected JMenuItem getMenuItem(String cmd) { - return (JMenuItem) menuItems.get(cmd); + return menuItems.get(cmd); } protected Action getAction(String cmd) { - return (Action) commands.get(cmd); + return commands.get(cmd); } protected String getResourceString(String nm) { @@ -328,10 +390,14 @@ protected JButton createToolbarButton(String key) { URL url = getResource(key + imageSuffix); JButton b = new JButton(new ImageIcon(url)) { - public float getAlignmentY() { return 0.5f; } + + @Override + public float getAlignmentY() { + return 0.5f; + } }; b.setRequestFocusEnabled(false); - b.setMargin(new Insets(1,1,1,1)); + b.setMargin(new Insets(1, 1, 1, 1)); String astr = getResourceString(key + actionSuffix); if (astr == null) { @@ -360,15 +426,17 @@ * resource file. */ protected String[] tokenize(String input) { - Vector v = new Vector(); + List<String> v = new ArrayList<String>(); StringTokenizer t = new StringTokenizer(input); String cmd[]; - while (t.hasMoreTokens()) - v.addElement(t.nextToken()); + while (t.hasMoreTokens()) { + v.add(t.nextToken()); + } cmd = new String[v.size()]; - for (int i = 0; i < cmd.length; i++) - cmd[i] = (String) v.elementAt(i); + for (int i = 0; i < cmd.length; i++) { + cmd[i] = v.get(i); + } return cmd; } @@ -416,13 +484,16 @@ } // 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)) { @@ -434,56 +505,48 @@ } } } - private JTextComponent editor; - private Hashtable commands; - private Hashtable menuItems; + private Map<Object, Action> commands; + private Map<String, JMenuItem> menuItems; private JMenuBar menubar; private JToolBar toolbar; private JComponent status; private JFrame elementTreeFrame; protected ElementTreePanel elementTreePanel; - protected FileDialog fileDialog; - /** * Listener for the edits on the current document. */ protected UndoableEditListener undoHandler = new UndoHandler(); - /** 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 newAction = "new"; public static final String saveAction = "save"; public static final String exitAction = "exit"; public static final String showElementTreeAction = "showElementTree"; + class UndoHandler implements UndoableEditListener { /** @@ -497,6 +560,7 @@ } } + /** * FIXME - I'm not very useful yet */ @@ -507,17 +571,14 @@ setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); } + @Override 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 */ @@ -531,7 +592,9 @@ redoAction }; + class UndoAction extends AbstractAction { + public UndoAction() { super("Undo"); setEnabled(false); @@ -541,26 +604,27 @@ try { undo.undo(); } catch (CannotUndoException ex) { - System.out.println("Unable to undo: " + ex); - ex.printStackTrace(); + Logger.getLogger(UndoAction.class.getName()).log(Level.SEVERE, + "Unable to undo", ex); } update(); redoAction.update(); } protected void update() { - if(undo.canUndo()) { + if (undo.canUndo()) { setEnabled(true); putValue(Action.NAME, undo.getUndoPresentationName()); - } - else { + } else { setEnabled(false); putValue(Action.NAME, "Undo"); } } } + class RedoAction extends AbstractAction { + public RedoAction() { super("Redo"); setEnabled(false); @@ -570,31 +634,32 @@ try { undo.redo(); } catch (CannotRedoException ex) { - System.out.println("Unable to redo: " + ex); - ex.printStackTrace(); + Logger.getLogger(RedoAction.class.getName()).log(Level.SEVERE, + "Unable to redo", ex); } update(); undoAction.update(); } protected void update() { - if(undo.canRedo()) { + if (undo.canRedo()) { setEnabled(true); putValue(Action.NAME, undo.getRedoPresentationName()); - } - else { + } else { setEnabled(false); putValue(Action.NAME, "Redo"); } } } + class OpenAction extends NewAction { OpenAction() { super(openAction); } + @Override public void actionPerformed(ActionEvent e) { Frame frame = getFrame(); JFileChooser chooser = new JFileChooser(); @@ -607,8 +672,9 @@ File f = chooser.getSelectedFile(); if (f.isFile() && f.canRead()) { Document oldDoc = getEditor().getDocument(); - if(oldDoc != null) + if (oldDoc != null) { oldDoc.removeUndoableEditListener(undoHandler); + } if (elementTreePanel != null) { elementTreePanel.setEditor(null); } @@ -625,6 +691,7 @@ } } + class SaveAction extends AbstractAction { SaveAction() { @@ -647,6 +714,7 @@ } } + class NewAction extends AbstractAction { NewAction() { @@ -659,8 +727,9 @@ public void actionPerformed(ActionEvent e) { Document oldDoc = getEditor().getDocument(); - if(oldDoc != null) + if (oldDoc != null) { oldDoc.removeUndoableEditListener(undoHandler); + } getEditor().setDocument(new PlainDocument()); getEditor().getDocument().addUndoableEditListener(undoHandler); resetUndoManager(); @@ -669,6 +738,7 @@ } } + /** * Really lame implementation of an exit command */ @@ -683,6 +753,7 @@ } } + /** * Action that brings up a JFrame with a JTree showing the structure * of the document. @@ -698,18 +769,19 @@ } public void actionPerformed(ActionEvent e) { - if(elementTreeFrame == null) { + if (elementTreeFrame == null) { // Create a frame containing an instance of // ElementTreePanel. try { - String title = resources.getString - ("ElementTreeFrameTitle"); + String title = resources.getString("ElementTreeFrameTitle"); elementTreeFrame = new JFrame(title); } catch (MissingResourceException mre) { elementTreeFrame = new JFrame(); } elementTreeFrame.addWindowListener(new WindowAdapter() { + + @Override public void windowClosing(WindowEvent weeee) { elementTreeFrame.setVisible(false); } @@ -721,10 +793,11 @@ fContentPane.add(elementTreePanel); elementTreeFrame.pack(); } - elementTreeFrame.show(); + elementTreeFrame.setVisible(true); } } + /** * Thread to load a file into the text storage model */ @@ -736,6 +809,7 @@ this.doc = doc; } + @Override public void run() { try { // initialize the statusbar @@ -751,22 +825,22 @@ 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); + doc.insertString(doc.getLength(), new String(buff, 0, nch), + null); progress.setValue(progress.getValue() + nch); } - } - catch (IOException e) { + } catch (IOException e) { final String msg = e.getMessage(); SwingUtilities.invokeLater(new Runnable() { + public void run() { JOptionPane.showMessageDialog(getFrame(), "Could not open file: " + msg, "Error opening file", JOptionPane.ERROR_MESSAGE); - } + } }); - } - catch (BadLocationException e) { + } catch (BadLocationException e) { System.err.println(e.getMessage()); } doc.addUndoableEditListener(undoHandler); @@ -778,21 +852,23 @@ if (elementTreePanel != null) { SwingUtilities.invokeLater(new Runnable() { + public void run() { elementTreePanel.setEditor(getEditor()); } }); } } - Document doc; File f; } + /** * Thread to save a document to file */ class FileSaver extends Thread { + Document doc; File f; @@ -802,13 +878,15 @@ this.doc = doc; } + @Override + @SuppressWarnings("SleepWhileHoldingLock") public void run() { try { // initialize the statusbar status.removeAll(); JProgressBar progress = new JProgressBar(); progress.setMinimum(0); - progress.setMaximum((int) doc.getLength()); + progress.setMaximum(doc.getLength()); status.add(progress); status.revalidate(); @@ -827,24 +905,25 @@ try { Thread.sleep(10); } catch (InterruptedException e) { - e.printStackTrace(); + Logger.getLogger(FileSaver.class.getName()).log( + Level.SEVERE, + null, e); } } out.flush(); out.close(); - } - catch (IOException e) { + } catch (IOException e) { final String msg = e.getMessage(); SwingUtilities.invokeLater(new Runnable() { + public void run() { JOptionPane.showMessageDialog(getFrame(), "Could not save file: " + msg, "Error saving file", JOptionPane.ERROR_MESSAGE); - } + } }); - } - catch (BadLocationException e) { + } catch (BadLocationException e) { System.err.println(e.getMessage()); } // we are done... get rid of progressbar