mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-16 13:25:34 +00:00
7027697: /jfc/Notepad demo needs to be improved
Reviewed-by: rupashka
This commit is contained in:
parent
a9452d32b7
commit
3d4529f30f
@ -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 @@ import java.util.*;
|
||||
*
|
||||
* @author Scott Violet
|
||||
*/
|
||||
public class ElementTreePanel extends JPanel implements CaretListener, DocumentListener, PropertyChangeListener, TreeSelectionListener {
|
||||
/** Tree showing the documents element structure. */
|
||||
protected JTree tree;
|
||||
/** Text component showing elemenst for. */
|
||||
protected JTextComponent editor;
|
||||
/** Model for the tree. */
|
||||
protected ElementTreeModel treeModel;
|
||||
/** Set to true when updatin the selection. */
|
||||
protected boolean updatingSelection;
|
||||
@SuppressWarnings("serial")
|
||||
public class ElementTreePanel extends JPanel implements CaretListener,
|
||||
DocumentListener, PropertyChangeListener, TreeSelectionListener {
|
||||
|
||||
/** Tree showing the documents element structure. */
|
||||
protected JTree tree;
|
||||
/** Text component showing elemenst for. */
|
||||
protected JTextComponent editor;
|
||||
/** Model for the tree. */
|
||||
protected ElementTreeModel treeModel;
|
||||
/** Set to true when updatin the selection. */
|
||||
protected boolean updatingSelection;
|
||||
|
||||
@SuppressWarnings("LeakingThisInConstructor")
|
||||
public ElementTreePanel(JTextComponent editor) {
|
||||
this.editor = editor;
|
||||
|
||||
@ -67,25 +90,28 @@ public class ElementTreePanel extends JPanel implements CaretListener, DocumentL
|
||||
// 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 @@ public class ElementTreePanel extends JPanel implements CaretListener, DocumentL
|
||||
}
|
||||
retBuffer.append(" ]");
|
||||
asString = retBuffer.toString();
|
||||
}
|
||||
else
|
||||
} 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 @@ public class ElementTreePanel extends JPanel implements CaretListener, DocumentL
|
||||
// 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 @@ public class ElementTreePanel extends JPanel implements CaretListener, DocumentL
|
||||
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 @@ public class ElementTreePanel extends JPanel implements CaretListener, DocumentL
|
||||
}
|
||||
|
||||
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 @@ public class ElementTreePanel extends JPanel implements CaretListener, DocumentL
|
||||
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 @@ public class ElementTreePanel extends JPanel implements CaretListener, DocumentL
|
||||
}
|
||||
|
||||
// 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 @@ public class ElementTreePanel extends JPanel implements CaretListener, DocumentL
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// DocumentListener
|
||||
|
||||
/**
|
||||
* Gives notification that there was an insert into the document. The
|
||||
* given range bounds the freshly inserted region.
|
||||
@ -236,53 +261,50 @@ public class ElementTreePanel extends JPanel implements CaretListener, DocumentL
|
||||
}
|
||||
|
||||
// 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 @@ public class ElementTreePanel extends JPanel implements CaretListener, DocumentL
|
||||
}
|
||||
|
||||
// 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 @@ public class ElementTreePanel extends JPanel implements CaretListener, DocumentL
|
||||
}
|
||||
|
||||
// Local methods
|
||||
|
||||
/**
|
||||
* @return tree showing elements.
|
||||
*/
|
||||
@ -347,15 +365,14 @@ public class ElementTreePanel extends JPanel implements CaretListener, DocumentL
|
||||
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 @@ public class ElementTreePanel extends JPanel implements CaretListener, DocumentL
|
||||
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 @@ public class ElementTreePanel extends JPanel implements CaretListener, DocumentL
|
||||
* 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 @@ public class ElementTreePanel extends JPanel implements CaretListener, DocumentL
|
||||
* 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 @@ public class ElementTreePanel extends JPanel implements CaretListener, DocumentL
|
||||
* @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 @@ public class ElementTreePanel extends JPanel implements CaretListener, DocumentL
|
||||
* @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 @@ public class ElementTreePanel extends JPanel implements CaretListener, DocumentL
|
||||
* @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 @@ public class ElementTreePanel extends JPanel implements CaretListener, DocumentL
|
||||
* 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 @@ public class ElementTreePanel extends JPanel implements CaretListener, DocumentL
|
||||
/**
|
||||
* 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;
|
||||
|
||||
@ -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 @@ import javax.swing.*;
|
||||
*
|
||||
* @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 @@ class Notepad extends JPanel {
|
||||
}
|
||||
}
|
||||
|
||||
@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 @@ class Notepad extends JPanel {
|
||||
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 @@ class Notepad extends JPanel {
|
||||
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 @@ class Notepad extends JPanel {
|
||||
|
||||
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 @@ class Notepad extends JPanel {
|
||||
return editor;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* To shutdown when run as an application. This is a
|
||||
* fairly lame implementation. A more self-respecting
|
||||
@ -184,6 +244,8 @@ class Notepad extends JPanel {
|
||||
* was needed.
|
||||
*/
|
||||
protected static final class AppCloser extends WindowAdapter {
|
||||
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
System.exit(0);
|
||||
}
|
||||
@ -239,11 +301,11 @@ class Notepad extends JPanel {
|
||||
* 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 @@ class Notepad extends JPanel {
|
||||
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 @@ class Notepad extends JPanel {
|
||||
* 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 @@ class Notepad extends JPanel {
|
||||
}
|
||||
|
||||
// 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 @@ class Notepad extends JPanel {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ class Notepad extends JPanel {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* FIXME - I'm not very useful yet
|
||||
*/
|
||||
@ -507,17 +571,14 @@ class Notepad extends JPanel {
|
||||
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 @@ class Notepad extends JPanel {
|
||||
redoAction
|
||||
};
|
||||
|
||||
|
||||
class UndoAction extends AbstractAction {
|
||||
|
||||
public UndoAction() {
|
||||
super("Undo");
|
||||
setEnabled(false);
|
||||
@ -541,26 +604,27 @@ class Notepad extends JPanel {
|
||||
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 @@ class Notepad extends JPanel {
|
||||
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 @@ class Notepad extends JPanel {
|
||||
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 Notepad extends JPanel {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class SaveAction extends AbstractAction {
|
||||
|
||||
SaveAction() {
|
||||
@ -647,6 +714,7 @@ class Notepad extends JPanel {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class NewAction extends AbstractAction {
|
||||
|
||||
NewAction() {
|
||||
@ -659,8 +727,9 @@ class Notepad extends JPanel {
|
||||
|
||||
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 @@ class Notepad extends JPanel {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Really lame implementation of an exit command
|
||||
*/
|
||||
@ -683,6 +753,7 @@ class Notepad extends JPanel {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Action that brings up a JFrame with a JTree showing the structure
|
||||
* of the document.
|
||||
@ -698,18 +769,19 @@ class Notepad extends JPanel {
|
||||
}
|
||||
|
||||
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 @@ class Notepad extends JPanel {
|
||||
fContentPane.add(elementTreePanel);
|
||||
elementTreeFrame.pack();
|
||||
}
|
||||
elementTreeFrame.show();
|
||||
elementTreeFrame.setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Thread to load a file into the text storage model
|
||||
*/
|
||||
@ -736,6 +809,7 @@ class Notepad extends JPanel {
|
||||
this.doc = doc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
// initialize the statusbar
|
||||
@ -751,22 +825,22 @@ class Notepad extends JPanel {
|
||||
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 @@ class Notepad extends JPanel {
|
||||
|
||||
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 @@ class Notepad extends JPanel {
|
||||
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 @@ class Notepad extends JPanel {
|
||||
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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user