Here are some general fixes I made (and committed tests for) for the
text package while I was trying to correct DefaultStyledDocument's
behaviour.
2006-01-05 Anthony Balkissoon <[EMAIL PROTECTED]>
* javax/swing/JTextPane.java:
(replaceSelection): If the document is an AbstractDocument, use replace
rather than remove and insert.
* javax/swing/event/EventListenerList.java:
(getListeners): Reversed the order of the listeners to match the
reference implementation.
* javax/swing/text/AbstractDocument.java:
(insertString): Add the UndoableEdit from the content.insertString call
to the DocumentEvent.
(DefaultDocumentEvent.toString): Implemented.
* javax/swing/text/DefaultCaret.java:
(setDot): Make sure dot is > 0 and less than the length of the
document.
* javax/swing/text/DefaultStyledDocument.java:
(ElementBuffer.insertUpdate): Set the modified tag of the document
event when we get start and end tags. This ensures that we create the
proper BranchElements in endEdit().
(ElementBuffer.insertUpdate): Added FIXME to handle
JoinFractureDirection case.
(insertUpdate): Added code to check if we're inserting immediately
after a newline and to handle this case (create start and end tags).
Only change the direction of the first and last tags if they are of
type ContentType.
(checkForInsertAfterNewline): New helper method.
(handleInsertAfterNewline): Likewise.
* javax/swing/text/View.java:
(updateLayout): Avoid NPE by checking if shape is null. Repaint
container.
--Tony
? include/gnu_java_net_PlainDatagramSocketImpl.h
? include/gnu_java_net_PlainSocketImpl.h
Index: javax/swing/JTextPane.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/JTextPane.java,v
retrieving revision 1.13
diff -u -r1.13 JTextPane.java
--- javax/swing/JTextPane.java 17 Nov 2005 21:42:48 -0000 1.13
+++ javax/swing/JTextPane.java 5 Jan 2006 20:13:57 -0000
@@ -40,6 +40,7 @@
import java.awt.Component;
+import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Caret;
@@ -151,38 +152,34 @@
{
Caret caret = getCaret();
StyledDocument doc = getStyledDocument();
+ AttributeSet a = getInputAttributes().copyAttributes();
+ if (doc == null)
+ return;
int dot = caret.getDot();
int mark = caret.getMark();
- // If content is empty delete selection.
- if (content == null)
- {
- caret.setDot(dot);
- return;
- }
+ int p0 = Math.min (dot, mark);
+ int p1 = Math.max (dot, mark);
try
{
- int start = getSelectionStart();
- int end = getSelectionEnd();
- int contentLength = content.length();
-
- // Remove selected text.
- if (dot != mark)
- doc.remove(start, end - start);
-
- // Insert new text.
- doc.insertString(start, content, null);
- // Set attributes for inserted text
- doc.setCharacterAttributes(start, contentLength, getInputAttributes(),
- true);
-
+ if (doc instanceof AbstractDocument)
+ ((AbstractDocument)doc).replace(p0, p1 - p0, content, a);
+ else
+ {
+ // Remove selected text.
+ if (dot != mark)
+ doc.remove(p0, p1 - p0);
+ // Insert new text.
+ if (content != null && content.length() > 0)
+ doc.insertString(p0, content, a);
+ }
}
catch (BadLocationException e)
{
- throw new AssertionError
- ("No BadLocationException should be thrown here");
+ throw new AssertionError
+ ("No BadLocationException should be thrown here");
}
}
Index: javax/swing/event/EventListenerList.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/event/EventListenerList.java,v
retrieving revision 1.13
diff -u -r1.13 EventListenerList.java
--- javax/swing/event/EventListenerList.java 18 Oct 2005 20:38:05 -0000 1.13
+++ javax/swing/event/EventListenerList.java 5 Jan 2006 20:13:57 -0000
@@ -228,7 +228,7 @@
count = getListenerCount(c);
result = (EventListener[]) Array.newInstance(c, count);
f = 0;
- for (int i = 0; i < listenerList.length; i += 2)
+ for (int i = listenerList.length - 2; i >= 0; i -= 2)
if (listenerList[i] == c)
result[f++] = (EventListener) listenerList[i + 1];
Index: javax/swing/text/AbstractDocument.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/AbstractDocument.java,v
retrieving revision 1.42
diff -u -r1.42 AbstractDocument.java
--- javax/swing/text/AbstractDocument.java 20 Dec 2005 21:28:16 -0000 1.42
+++ javax/swing/text/AbstractDocument.java 5 Jan 2006 20:13:58 -0000
@@ -541,6 +541,9 @@
writeLock();
UndoableEdit undo = content.insertString(offset, text);
+ if (undo != null)
+ event.addEdit(undo);
+
insertUpdate(event, attributes);
writeUnlock();
@@ -1911,6 +1914,15 @@
// XXX - Fully qualify ElementChange to work around gcj bug #2499.
return (DocumentEvent.ElementChange) changes.get(elem);
}
+
+ /**
+ * Returns a String description of the change event. This returns the
+ * toString method of the Vector of edits.
+ */
+ public String toString()
+ {
+ return edits.toString();
+ }
}
/**
Index: javax/swing/text/DefaultCaret.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/DefaultCaret.java,v
retrieving revision 1.26
diff -u -r1.26 DefaultCaret.java
--- javax/swing/text/DefaultCaret.java 22 Nov 2005 16:10:27 -0000 1.26
+++ javax/swing/text/DefaultCaret.java 5 Jan 2006 20:13:58 -0000
@@ -829,9 +829,12 @@
public void setDot(int dot)
{
if (dot >= 0)
- {
+ {
+ Document doc = textComponent.getDocument();
+ if (doc != null)
+ this.dot = Math.min(dot, doc.getLength());
+ this.dot = Math.max(dot, 0);
this.mark = dot;
- this.dot = dot;
handleHighlight();
adjustVisibility(this);
appear();
Index: javax/swing/text/DefaultStyledDocument.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/DefaultStyledDocument.java,v
retrieving revision 1.25
diff -u -r1.25 DefaultStyledDocument.java
--- javax/swing/text/DefaultStyledDocument.java 3 Jan 2006 13:38:11 -0000 1.25
+++ javax/swing/text/DefaultStyledDocument.java 5 Jan 2006 20:13:58 -0000
@@ -789,9 +789,11 @@
{
case ElementSpec.StartTagType:
numStartTags++;
+ documentEvent.modified = true;
break;
case ElementSpec.EndTagType:
numEndTags++;
+ documentEvent.modified = true;
break;
default:
insertContentTag(data[i]);
@@ -929,7 +931,11 @@
// Add this action to the document event.
addEdit(paragraph, currentIndex, remove, add);
}
- else
+ else if (dir == ElementSpec.JoinFractureDirection)
+ {
+ // TODO: What should be done here?
+ }
+ else if (dir == ElementSpec.OriginateDirection)
{
BranchElement paragraph = (BranchElement) elementStack.peek();
int index = paragraph.getElementIndex(offset);
@@ -1564,7 +1570,7 @@
int length = ev.getLength();
int endOffset = offset + length;
AttributeSet paragraphAttributes =
- getParagraphElement(endOffset).getAttributes();
+ getParagraphElement(endOffset).getAttributes();
Segment txt = new Segment();
try
{
@@ -1579,46 +1585,75 @@
int len = 0;
Vector specs = new Vector();
-
+ ElementSpec finalStartTag = null;
+ short finalStartDirection = ElementSpec.OriginateDirection;
+ boolean prevCharWasNewline = false;
Element prev = getCharacterElement(offset);
- Element next = getCharacterElement(endOffset);
+ Element next = getCharacterElement(endOffset);
+ Element prevParagraph = getParagraphElement(offset);
+ Element paragraph = getParagraphElement(endOffset);
int segmentEnd = txt.offset + txt.count;
+
+ // Check to see if we're inserting immediately after a newline.
+ checkForInsertAfterNewline(offset, endOffset, prevParagraph, paragraph,
+ paragraphAttributes, prevCharWasNewline,
+ finalStartTag, finalStartDirection, specs);
+
for (int i = txt.offset; i < segmentEnd; ++i)
{
len++;
if (txt.array[i] == '\n')
{
- ElementSpec spec = new ElementSpec(attr, ElementSpec.ContentType,
- len);
- specs.add(spec);
+ // Add the ElementSpec for the content.
+ specs.add(new ElementSpec(attr, ElementSpec.ContentType, len));
// Add ElementSpecs for the newline.
- ElementSpec endTag = new ElementSpec(null, ElementSpec.EndTagType);
- specs.add(endTag);
- ElementSpec startTag = new ElementSpec(paragraphAttributes,
+ specs.add(new ElementSpec(null, ElementSpec.EndTagType));
+ finalStartTag = new ElementSpec(paragraphAttributes,
ElementSpec.StartTagType);
- startTag.setDirection(ElementSpec.JoinFractureDirection);
- specs.add(startTag);
-
+ specs.add(finalStartTag);
len = 0;
}
}
// Create last element if last character hasn't been a newline.
if (len > 0)
- specs.add(new ElementSpec(attr, ElementSpec.ContentType, len));
+ specs.add(new ElementSpec(attr, ElementSpec.ContentType, len));
+ // Set the direction of the last spec of type StartTagType.
+ // If we are inserting after a newline then this value comes from
+ // handleInsertAfterNewline.
+ if (finalStartTag != null)
+ {
+ if (prevCharWasNewline)
+ finalStartTag.setDirection(finalStartDirection);
+ else if (prevParagraph.getEndOffset() != endOffset)
+ finalStartTag.setDirection(ElementSpec.JoinFractureDirection);
+ else
+ {
+ // If there is an element AFTER this one, then set the
+ // direction to JoinNextDirection.
+ Element parent = prevParagraph.getParentElement();
+ int index = parent.getElementIndex(offset);
+ if (index + 1 < parent.getElementCount()
+ && !parent.getElement(index + 1).isLeaf())
+ finalStartTag.setDirection(ElementSpec.JoinNextDirection);
+ }
+ }
+
// If we are at the last index, then check if we could probably be
// joined with the next element.
- ElementSpec last = (ElementSpec) specs.lastElement();
- if (next.getAttributes().isEqual(attr))
+ ElementSpec last = (ElementSpec) specs.lastElement();
+ if (next.getAttributes().isEqual(attr)
+ && last.getType() == ElementSpec.ContentType)
last.setDirection(ElementSpec.JoinNextDirection);
// If we are at the first new element, then check if it could be
// joined with the previous element.
ElementSpec first = (ElementSpec) specs.firstElement();
- if (prev.getAttributes().isEqual(attr))
+ if (prev.getAttributes().isEqual(attr)
+ && first.getType() == ElementSpec.ContentType)
first.setDirection(ElementSpec.JoinPreviousDirection);
ElementSpec[] elSpecs =
@@ -1628,6 +1663,73 @@
}
/**
+ * A helper method that checks to see if insertUpdate was called when text
+ * was inserted immediately after a newline, and calls
+ * handleInsertAfterNewline if that is the case.
+ */
+ void checkForInsertAfterNewline(int offset, int endOffset,
+ Element prevParagraph, Element paragraph,
+ AttributeSet paragraphAttributes,
+ boolean prevCharWasNewline,
+ ElementSpec finalStartTag,
+ short finalStartDirection, Vector specs)
+ {
+ if (offset > 0)
+ {
+ try
+ {
+ String s = getText(offset - 1, 1);
+ if (s.equals("\n"))
+ {
+ finalStartDirection =
+ handleInsertAfterNewline(specs, offset, endOffset,
+ prevParagraph,
+ paragraph,
+ paragraphAttributes);
+
+ prevCharWasNewline = true;
+ // Find the final start tag from the ones just created.
+ for (int i = 0; i < specs.size(); i++)
+ if (((ElementSpec) specs.get(i)).getType()
+ == ElementSpec.StartTagType)
+ finalStartTag = (ElementSpec)specs.get(i);
+ }
+ }
+ catch (BadLocationException ble)
+ {
+ // This shouldn't happen.
+ AssertionError ae = new AssertionError();
+ ae.initCause(ble);
+ throw ae;
+ }
+ }
+ }
+
+ /**
+ * A helper method to set up the ElementSpec buffer for the special
+ * case of an insertion occurring immediately after a newline.
+ * @param specs the ElementSpec buffer to initialize.
+ */
+ short handleInsertAfterNewline(Vector specs, int offset, int endOffset,
+ Element prevParagraph, Element paragraph,
+ AttributeSet a)
+ {
+ if (prevParagraph.getParentElement() == paragraph.getParentElement())
+ {
+ specs.add(new ElementSpec(a, ElementSpec.EndTagType));
+ specs.add(new ElementSpec(a, ElementSpec.StartTagType));
+ if (prevParagraph.getEndOffset() != endOffset)
+ return ElementSpec.JoinFractureDirection;
+
+ }
+ else
+ {
+ // TODO: What to do here?
+ }
+ return ElementSpec.OriginateDirection;
+ }
+
+ /**
* Updates the document structure in response to text removal. This is
* forwarded to the [EMAIL PROTECTED] ElementBuffer} of this document. Any changes to
* the document structure are added to the specified document event and
@@ -1671,7 +1773,22 @@
else if (start instanceof AbstractDocument.BranchElement)
System.out.println ("BranchElement ("+start.getStartOffset()+", "+start.getEndOffset()+")");
else
- System.out.println ("LeafElement ("+start.getStartOffset()+", "+start.getEndOffset()+")");
+ {
+ {
+ try
+ {
+ System.out.println ("LeafElement ("+start.getStartOffset()+", "
+ + start.getEndOffset()+"): "+
+ start.getDocument().
+ getText(start.getStartOffset(),
+ start.getEndOffset() -
+ start.getStartOffset()));
+ }
+ catch (BadLocationException ble)
+ {
+ }
+ }
+ }
for (int i = 0; i < start.getElementCount(); i ++)
printElements (start.getElement(i), pad+3);
}
Index: javax/swing/text/View.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/View.java,v
retrieving revision 1.24
diff -u -r1.24 View.java
--- javax/swing/text/View.java 23 Nov 2005 11:59:30 -0000 1.24
+++ javax/swing/text/View.java 5 Jan 2006 20:13:58 -0000
@@ -447,9 +447,11 @@
protected void updateLayout(DocumentEvent.ElementChange ec,
DocumentEvent ev, Shape shape)
{
- Rectangle b = shape.getBounds();
- if (ec != null)
- preferenceChanged(this, true, true);
+ if (ec != null && shape != null)
+ preferenceChanged(null, true, true);
+ Container c = getContainer();
+ if (c != null)
+ c.repaint();
}
/**
_______________________________________________
Classpath-patches mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/classpath-patches