On Tue, 2006-02-21 at 11:56 +0100, Robert Schuster wrote:
> Committed - Roman reviewed the first version.
> 
> cya
> Robert
> 

I get this when I run the swing demo. Any idea why?

[EMAIL PROTECTED] examples]$ jamvm gnu/classpath/examples/swing/Demo
Exception during event dispatch:
java.lang.NullPointerException
   at javax.swing.text.WrappedPlainView.updateMetrics
(WrappedPlainView.java:300)
   at javax.swing.text.WrappedPlainView.getPreferredSpan
(WrappedPlainView.java:309)
   at javax.swing.plaf.basic.BasicTextUI$RootView.getPreferredSpan
(BasicTextUI.java:236)
   at javax.swing.plaf.basic.BasicTextUI.getPreferredSize
(BasicTextUI.java:789)
   at javax.swing.JComponent.getPreferredSize (JComponent.java:1161)
   at javax.swing.JEditorPane.getPreferredSize (JEditorPane.java:689)
   at javax.swing.text.WrappedPlainView.calculateBreakPosition
(WrappedPlainView.java:274)
   at javax.swing.text.WrappedPlainView$WrappedLine.determineNumLines
(WrappedPlainView.java:471)
   at javax.swing.text.WrappedPlainView$WrappedLine.<init>
(WrappedPlainView.java:413)
   at javax.swing.text.WrappedPlainView.loadChildren
(WrappedPlainView.java:256)
   at javax.swing.text.CompositeView.setParent (CompositeView.java:122)
   at javax.swing.plaf.basic.BasicTextUI$RootView.setView
(BasicTextUI.java:182)
   at javax.swing.plaf.basic.BasicTextUI.setView (BasicTextUI.java:1219)
   at javax.swing.plaf.basic.BasicTextUI.modelChanged
(BasicTextUI.java:1243)
   at javax.swing.plaf.basic.BasicTextUI
$PropertyChangeHandler.propertyChange (BasicTextUI.java:385)
   at java.beans.PropertyChangeSupport.firePropertyChange
(PropertyChangeSupport.java:388)
   at java.beans.PropertyChangeSupport.firePropertyChange
(PropertyChangeSupport.java:332)
   at java.awt.Component.firePropertyChange (Component.java:4455)
   at javax.swing.text.JTextComponent.setDocument
(JTextComponent.java:1148)
   at javax.swing.JEditorPane.setEditorKit (JEditorPane.java:833)
   at javax.swing.JEditorPane.<init> (JEditorPane.java:523)
   at gnu.classpath.examples.swing.Demo.mkEditorPane (Demo.java:946)
   at gnu.classpath.examples.swing.Demo.mkMenuBar (Demo.java:237)
   at gnu.classpath.examples.swing.Demo.<init> (Demo.java:708)
   at gnu.classpath.examples.swing.Demo$LaterMain.run (Demo.java:727)
   at java.awt.event.InvocationEvent.dispatch (InvocationEvent.java:200)
   at java.awt.EventQueue.dispatchEvent (EventQueue.java:465)
   at java.awt.EventDispatchThread.run (EventDispatchThread.java:75)

> Robert Schuster wrote:
> > Hi all.
> > 
> > I fixed to small errors in this patch that lead to strange behavior:
> > 
> > 
> >>+      // Last line, from beginning-of-line to p1.
> >>+      r0.width = r1.x + r1.width;
> > 
> > Had to add -1 to the calculation above otherwise there were drawing 
> > differences
> > between single line and multi line selections.
> > 
> > 
> >>+      paintHighlight(g, r0);
> >>     }
> >>+    
> >>+    // Prevent useless write & repaint operations.
> >>+    if (o0 == o1 && o1 == p1)
> >>+      return;
> >>+    
> > 
> > This expression wanted to be
> > 
> > 
> >>+    if (o0 == p0 && o1 == p1)
> > 
> > 
> > Apart from that I updated the copyright headers in the affected files.
> > 
> > After fixing that I cannot see any more problems with the highlighting 
> > mechanism.
> > 
> > 
> > ChangeLog stays the same:
> > 
> > 2006-02-21  Robert Schuster  <[EMAIL PROTECTED]>
> > 
> >         * javax/swing/plaf/basic/BasicTextUI.java:
> >         (paint): Remove unneccessary part of the if-expression.
> >         (damageRange): Added case where the range spans multiple lines.
> >         * javax/swing/text/DefaultCaret.java:
> >         (clearHighlight): New method.
> >         (handleHighlight): Removed unneccessary part of the if-expression.
> >         (setDot): Use clearHighlight method.
> >         * javax/swing/text/DefaultHighlighter.java: Use ArrayList instead
> >         of Vector.
> >         (paint): Prevented calling size() on every loop iteration, fixed
> >         calculation of allocation area bounds.
> >         (getHighlights): Implemented.
> >         (removeHighlight): Mark damaged area in textcomponent.
> >         (addHighlight): Mark damaged area in textcomponent.
> >         (changeHighlight): Mark damaged area in textcomponent.
> >         (DefaultHighlighter.HighlightEntry): Made it a real
> >         Highlighter.Highlight implementation.
> >         (DefaultHighlighter.DefaultHighlightPainter.paint): Fixed
> >         calculations.
> > 
> > cya
> > Robert
> > 
> > 
> > 
> > ------------------------------------------------------------------------
> > 
> > Index: javax/swing/text/DefaultCaret.java
> > ===================================================================
> > RCS file: /cvsroot/classpath/classpath/javax/swing/text/DefaultCaret.java,v
> > retrieving revision 1.30
> > diff -u -r1.30 DefaultCaret.java
> > --- javax/swing/text/DefaultCaret.java      9 Feb 2006 17:15:33 -0000       
> > 1.30
> > +++ javax/swing/text/DefaultCaret.java      21 Feb 2006 10:25:59 -0000
> > @@ -577,7 +577,39 @@
> >    {
> >      return mark;
> >    }
> > -
> > +  
> > +  private void clearHighlight()
> > +  {
> > +    Highlighter highlighter = textComponent.getHighlighter();
> > +    
> > +    if (highlighter == null)
> > +      return;
> > +    
> > +    if (selectionVisible)
> > +      {
> > +    try
> > +      {
> > +        if (highlightEntry == null)
> > +          highlightEntry = highlighter.addHighlight(0, 0, 
> > getSelectionPainter());
> > +        else
> > +          highlighter.changeHighlight(highlightEntry, 0, 0);
> > +      }
> > +    catch (BadLocationException e)
> > +      {
> > +        // This should never happen.
> > +        throw new InternalError();
> > +      }
> > +      }
> > +    else
> > +      {
> > +    if (highlightEntry != null)
> > +      {
> > +        highlighter.removeHighlight(highlightEntry);
> > +        highlightEntry = null;
> > +      }
> > +      }
> > +  }
> > +  
> >    private void handleHighlight()
> >    {
> >      Highlighter highlighter = textComponent.getHighlighter();
> > @@ -588,7 +620,7 @@
> >      int p0 = Math.min(dot, mark);
> >      int p1 = Math.max(dot, mark);
> >      
> > -    if (selectionVisible && p0 != p1)
> > +    if (selectionVisible)
> >        {
> >     try
> >       {
> > @@ -818,6 +850,7 @@
> >          if (doc != null)
> >            this.dot = Math.min(dot, doc.getLength());
> >          this.dot = Math.max(this.dot, 0);
> > +        
> >          handleHighlight();
> >          adjustVisibility(this);
> >          appear();
> > @@ -842,7 +875,8 @@
> >            this.dot = Math.min(dot, doc.getLength());
> >          this.dot = Math.max(this.dot, 0);
> >          this.mark = this.dot;
> > -        handleHighlight();
> > +        
> > +        clearHighlight();
> >          adjustVisibility(this);
> >          appear();
> >        }
> > Index: javax/swing/text/DefaultHighlighter.java
> > ===================================================================
> > RCS file: 
> > /cvsroot/classpath/classpath/javax/swing/text/DefaultHighlighter.java,v
> > retrieving revision 1.6
> > diff -u -r1.6 DefaultHighlighter.java
> > --- javax/swing/text/DefaultHighlighter.java        19 Oct 2005 14:57:30 
> > -0000      1.6
> > +++ javax/swing/text/DefaultHighlighter.java        21 Feb 2006 10:25:59 
> > -0000
> > @@ -1,5 +1,5 @@
> >  /* DefaultHighlighter.java --
> > -   Copyright (C) 2004  Free Software Foundation, Inc.
> > +   Copyright (C) 2004, 2006  Free Software Foundation, Inc.
> >  
> >  This file is part of GNU Classpath.
> >  
> > @@ -40,9 +40,10 @@
> >  
> >  import java.awt.Color;
> >  import java.awt.Graphics;
> > +import java.awt.Insets;
> >  import java.awt.Rectangle;
> >  import java.awt.Shape;
> > -import java.util.Vector;
> > +import java.util.ArrayList;
> >  
> >  public class DefaultHighlighter extends LayeredHighlighter
> >  {
> > @@ -84,7 +85,7 @@
> >       // This should never occur.
> >            return;
> >     }
> > -
> > +      
> >        if (r0 == null || r1 == null)
> >     return;
> >  
> > @@ -100,7 +101,7 @@
> >       paintHighlight(g, r0);
> >       return;
> >     }
> > -
> > +      
> >        // First line, from p0 to end-of-line.
> >        r0.width = rect.x + rect.width - r0.x;
> >        paintHighlight(g, r0);
> > @@ -109,15 +110,19 @@
> >        // have the same height -- not a good assumption with 
> > JEditorPane/JTextPane).
> >        r0.y += r0.height;
> >        r0.x = rect.x;
> > -
> > +      r0.width = rect.width;
> > +      
> >        while (r0.y < r1.y)
> >     {
> >       paintHighlight(g, r0);
> >       r0.y += r0.height;
> >     }
> >  
> > -      // Last line, from beginnin-of-line to p1.
> > -      paintHighlight(g, r1);
> > +      // Last line, from beginning-of-line to p1.
> > +      // The "-1" is neccessary else we would paint one pixel column more
> > +      // than in the case where the selection is only on one line. 
> > +      r0.width = r1.x + r1.width - 1;
> > +      paintHighlight(g, r0);
> >      }
> >  
> >      public Shape paintLayer(Graphics g, int p0, int p1, Shape bounds,
> > @@ -127,7 +132,7 @@
> >      }
> >    }
> >    
> > -  private class HighlightEntry
> > +  private class HighlightEntry implements Highlighter.Highlight
> >    {
> >      int p0;
> >      int p1;
> > @@ -140,12 +145,12 @@
> >        this.painter = painter;
> >      }
> >  
> > -    public int getStartPosition()
> > +    public int getStartOffset()
> >      {
> >        return p0;
> >      }
> >  
> > -    public int getEndPosition()
> > +    public int getEndOffset()
> >      {
> >        return p1;
> >      }
> > @@ -163,7 +168,7 @@
> >      new DefaultHighlightPainter(null);
> >    
> >    private JTextComponent textComponent;
> > -  private Vector highlights = new Vector();
> > +  private ArrayList highlights = new ArrayList();
> >    private boolean drawsLayeredHighlights = true;
> >    
> >    public DefaultHighlighter()
> > @@ -208,12 +213,20 @@
> >      checkPositions(p0, p1);
> >      HighlightEntry entry = new HighlightEntry(p0, p1, painter);
> >      highlights.add(entry);
> > +    
> > +    textComponent.getUI().damageRange(textComponent, p0, p1);
> > +    
> >      return entry;
> >    }
> >  
> >    public void removeHighlight(Object tag)
> >    {
> >      highlights.remove(tag);
> > +
> > +    HighlightEntry entry = (HighlightEntry) tag;
> > +    textComponent.getUI().damageRange(textComponent,
> > +                                      entry.p0,
> > +                                      entry.p1);
> >    }
> >  
> >    public void removeAllHighlights()
> > @@ -223,16 +236,30 @@
> >  
> >    public Highlighter.Highlight[] getHighlights()
> >    {
> > -    return null;
> > +    return (Highlighter.Highlight[]) 
> > +      highlights.toArray(new Highlighter.Highlight[highlights.size()]);
> >    }
> >  
> >    public void changeHighlight(Object tag, int p0, int p1)
> >      throws BadLocationException
> >    {
> > +    int o0, o1;
> > +    
> >      checkPositions(p0, p1);
> >      HighlightEntry entry = (HighlightEntry) tag;
> > +    o0 = entry.p0;
> > +    o1 = entry.p1;
> > +    
> > +    // Prevent useless write & repaint operations.
> > +    if (o0 == p0 && o1 == p1)
> > +      return;
> > +    
> >      entry.p0 = p0;
> >      entry.p1 = p1;
> > +    
> > +    textComponent.getUI().damageRange(textComponent,
> > +                                      Math.min(p0, o0),
> > +                                      Math.max(p1, o1));
> >    }
> >  
> >    public void paintLayeredHighlights(Graphics g, int p0, int p1,
> > @@ -244,13 +271,21 @@
> >  
> >    public void paint(Graphics g)
> >    {
> > +    int size = highlights.size();
> > +    
> >      // Check if there are any highlights.
> > -    if (highlights.size() == 0)
> > +    if (size == 0)
> >        return;
> > +
> > +    // Prepares the rectangle of the inner drawing area.
> > +    Insets insets = textComponent.getInsets();
> > +    Shape bounds =
> > +      new Rectangle(insets.left,
> > +                    insets.top,
> > +                    textComponent.getWidth() - insets.left - insets.right,
> > +                    textComponent.getHeight() - insets.top - 
> > insets.bottom);
> >      
> > -    Shape bounds = textComponent.getBounds();
> > -    
> > -    for (int index = 0; index < highlights.size(); ++index)
> > +    for (int index = 0; index < size; ++index)
> >        {
> >     HighlightEntry entry = (HighlightEntry) highlights.get(index);
> >     entry.painter.paint(g, entry.p0, entry.p1, bounds, textComponent);
> > Index: javax/swing/plaf/basic/BasicTextUI.java
> > ===================================================================
> > RCS file: 
> > /cvsroot/classpath/classpath/javax/swing/plaf/basic/BasicTextUI.java,v
> > retrieving revision 1.69
> > diff -u -r1.69 BasicTextUI.java
> > --- javax/swing/plaf/basic/BasicTextUI.java 20 Feb 2006 12:40:42 -0000      
> > 1.69
> > +++ javax/swing/plaf/basic/BasicTextUI.java 21 Feb 2006 10:25:59 -0000
> > @@ -1,5 +1,5 @@
> >  /* BasicTextUI.java --
> > -   Copyright (C) 2002, 2003, 2004, 2005  Free Software Foundation, Inc.
> > +   Copyright (C) 2002, 2003, 2004, 2005, 2006  Free Software Foundation, 
> > Inc.
> >  
> >  This file is part of GNU Classpath.
> >  
> > @@ -79,6 +79,7 @@
> >  import javax.swing.text.JTextComponent;
> >  import javax.swing.text.Keymap;
> >  import javax.swing.text.Position;
> > +import javax.swing.text.Utilities;
> >  import javax.swing.text.View;
> >  import javax.swing.text.ViewFactory;
> >  
> > @@ -875,9 +876,19 @@
> >      if (textComponent.isOpaque())
> >        paintBackground(g);
> >  
> > -    if (highlighter != null
> > -        && textComponent.getSelectionStart() != 
> > textComponent.getSelectionEnd())
> > -      highlighter.paint(g);
> > +    // Try painting with the highlighter without checking whether there
> > +    // is a selection because a highlighter can be used to do more than
> > +    // marking selected text.
> > +    if (highlighter != null)
> > +      {
> > +        // Handle restoring of the color here to prevent
> > +        // drawing problems when the Highlighter implementor
> > +        // forgets to restore it.
> > +        Color oldColor = g.getColor();
> > +        highlighter.paint(g);
> > +        g.setColor(oldColor);
> > +      }
> > +      
> >  
> >      rootView.paint(g, getVisibleEditorRect());
> >  
> > @@ -945,9 +956,75 @@
> >    {
> >      try
> >        {
> > +        // Limit p0 and p1 to sane values to prevent unfriendly
> > +        // BadLocationExceptions. This makes it possible for the 
> > highlighter
> > +        // to send us illegal values which can happen when a large number
> > +        // of selected characters are removed (eg. by pressing delete
> > +        // or backspace).
> > +        // The reference implementation does not throw an exception, too.
> > +        p0 = Math.min(p0, t.getDocument().getLength());
> > +        p1 = Math.min(p1, t.getDocument().getLength());
> > +        
> >          Rectangle l1 = modelToView(t, p0, firstBias);
> >          Rectangle l2 = modelToView(t, p1, secondBias);
> > -        t.repaint(l1.union(l2));
> > +        if (l1.y == l2.y)
> > +          t.repaint(l1.union(l2));
> > +        else
> > +          {
> > +            // The two rectangles lie on different lines and we need a
> > +            // different algorithm to calculate the damaged area:
> > +            // 1. The line of p0 is damaged from the position of p0
> > +            // to the right border.
> > +            // 2. All lines between the ones where p0 and p1 lie on
> > +            // are completely damaged. Use the allocation area to find
> > +            // out the bounds.
> > +            // 3. The final line is damaged from the left bound to the
> > +            // position of p1.
> > +            Insets insets = t.getInsets();
> > +
> > +            // Damage first line until the end.
> > +            l1.width = insets.right + t.getWidth() - l1.x;
> > +            t.repaint(l1);
> > +            
> > +            // Note: Utilities.getPositionBelow() may return the offset
> > +            // that was put in. In that case there is no next line and
> > +            // we should stop searching for one.
> > +            
> > +            int posBelow = Utilities.getPositionBelow(t, p0, l1.x);
> > +            if (posBelow < p1 && posBelow != -1 && posBelow != p0)
> > +              {
> > +                // Take the rectangle of the offset we just found and grow 
> > it
> > +                // to the maximum width. Retain y because this is our start
> > +                // height.
> > +                Rectangle grow = modelToView(t, posBelow);
> > +                grow.x = insets.left;
> > +                grow.width = t.getWidth() + insets.right;
> > +                
> > +                // Find further lines which have to be damaged completely.
> > +                int nextPosBelow = posBelow;
> > +                while (nextPosBelow < p1 && nextPosBelow != -1 && posBelow 
> > != nextPosBelow)
> > +                  {
> > +                    posBelow = nextPosBelow;
> > +                    nextPosBelow = Utilities.getPositionBelow(t, posBelow, 
> > l1.x);
> > +                  }
> > +                // Now posBelow is an offset on the last line which has to 
> > be damaged
> > +                // completely. (newPosBelow is on the same line as p1)
> > +                 
> > +                // Retrieve the rectangle of posBelow and use its y and 
> > height
> > +                // value to calculate the final height of the multiple line
> > +                // spanning rectangle.
> > +                Rectangle end = modelToView(t, posBelow);
> > +                grow.height = end.y + end.height - grow.y;
> > +                
> > +                // Mark that area as damage.
> > +                t.repaint(grow);
> > +              }
> > +            
> > +            // Damage last line from its beginning to the position of p1.
> > +            l2.width += l2.x;
> > +            l2.x = insets.left;
> > +            t.repaint(l2);
> > +          }
> >        }
> >      catch (BadLocationException ex)
> >        {


Reply via email to