commit-classpath
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[commit-cp] classpath ChangeLog javax/swing/plaf/basic/Basi...


From: Roman Kennke
Subject: [commit-cp] classpath ChangeLog javax/swing/plaf/basic/Basi...
Date: Wed, 21 Jun 2006 13:13:42 +0000

CVSROOT:        /cvsroot/classpath
Module name:    classpath
Changes by:     Roman Kennke <rabbit78> 06/06/21 13:13:40

Modified files:
        .              : ChangeLog 
        javax/swing/plaf/basic: BasicButtonListener.java 
                                BasicButtonUI.java 
                                BasicGraphicsUtils.java 
                                BasicMenuItemUI.java BasicMenuUI.java 

Log message:
        2006-06-21  Roman Kennke  <address@hidden>
        
                * javax/swing/plaf/basic/BasicButtonListener.java
                (propertyChange): Create a TextLayout and store it in the button
                when the 'text' property changes.
                * javax/swing/plaf/basic/BasicButtonUI.java
                (paintText): Call BasicGraphicsUtils utility method for
                drawing strings, instead of Graphics.drawString().
                * javax/swing/plaf/basic/BasicGraphicsUtils.java
                (CACHE_TEXT_LAYOUT): New constant field. Used as a key for 
storing
                cached text layouts as client properties in JComponents.
                (drawString(JComponent,Graphics,String,int,int)): New helper 
method.
                (drawStringUnderlineCharAt): New helper method.
                * javax/swing/plaf/basic/BasicMenuItemUI.java
                (PropertyChangeHandler.propertyChange): Update cached text 
layout
                when 'text' property changes. Use equals() instead of == for
                string comparison.
                (paintText): Use new BasicGraphicsUtils methods for painting
                the cached text layout.
                (installListeners): Call super.installListeners() and remove
                the unneeded listener installs.
                (uninstallListeners): Call super.uninstallListeners() and remove
                the unneeded listener uninstalls.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/classpath/ChangeLog?cvsroot=classpath&r1=1.7896&r2=1.7897
http://cvs.savannah.gnu.org/viewcvs/classpath/javax/swing/plaf/basic/BasicButtonListener.java?cvsroot=classpath&r1=1.13&r2=1.14
http://cvs.savannah.gnu.org/viewcvs/classpath/javax/swing/plaf/basic/BasicButtonUI.java?cvsroot=classpath&r1=1.38&r2=1.39
http://cvs.savannah.gnu.org/viewcvs/classpath/javax/swing/plaf/basic/BasicGraphicsUtils.java?cvsroot=classpath&r1=1.17&r2=1.18
http://cvs.savannah.gnu.org/viewcvs/classpath/javax/swing/plaf/basic/BasicMenuItemUI.java?cvsroot=classpath&r1=1.47&r2=1.48
http://cvs.savannah.gnu.org/viewcvs/classpath/javax/swing/plaf/basic/BasicMenuUI.java?cvsroot=classpath&r1=1.23&r2=1.24

Patches:
Index: ChangeLog
===================================================================
RCS file: /cvsroot/classpath/classpath/ChangeLog,v
retrieving revision 1.7896
retrieving revision 1.7897
diff -u -b -r1.7896 -r1.7897
--- ChangeLog   21 Jun 2006 12:57:05 -0000      1.7896
+++ ChangeLog   21 Jun 2006 13:13:39 -0000      1.7897
@@ -1,5 +1,29 @@
 2006-06-21  Roman Kennke  <address@hidden>
 
+       * javax/swing/plaf/basic/BasicButtonListener.java
+       (propertyChange): Create a TextLayout and store it in the button
+       when the 'text' property changes.
+       * javax/swing/plaf/basic/BasicButtonUI.java
+       (paintText): Call BasicGraphicsUtils utility method for
+       drawing strings, instead of Graphics.drawString().
+       * javax/swing/plaf/basic/BasicGraphicsUtils.java
+       (CACHE_TEXT_LAYOUT): New constant field. Used as a key for storing
+       cached text layouts as client properties in JComponents.
+       (drawString(JComponent,Graphics,String,int,int)): New helper method.
+       (drawStringUnderlineCharAt): New helper method.
+       * javax/swing/plaf/basic/BasicMenuItemUI.java
+       (PropertyChangeHandler.propertyChange): Update cached text layout
+       when 'text' property changes. Use equals() instead of == for
+       string comparison.
+       (paintText): Use new BasicGraphicsUtils methods for painting
+       the cached text layout.
+       (installListeners): Call super.installListeners() and remove
+       the unneeded listener installs.
+       (uninstallListeners): Call super.uninstallListeners() and remove
+       the unneeded listener uninstalls.
+
+2006-06-21  Roman Kennke  <address@hidden>
+
        * javax/swing/plaf/basic/BasicTextUI.java
        (PropertyChangeHandler.propertyChange): Handle document listener
        update here.

Index: javax/swing/plaf/basic/BasicButtonListener.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/javax/swing/plaf/basic/BasicButtonListener.java,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -b -r1.13 -r1.14
--- javax/swing/plaf/basic/BasicButtonListener.java     4 May 2006 14:45:50 
-0000       1.13
+++ javax/swing/plaf/basic/BasicButtonListener.java     21 Jun 2006 13:13:40 
-0000      1.14
@@ -41,10 +41,12 @@
 import java.awt.event.ActionEvent;
 import java.awt.event.FocusEvent;
 import java.awt.event.FocusListener;
-import java.awt.event.InputEvent;
 import java.awt.event.MouseEvent;
 import java.awt.event.MouseListener;
 import java.awt.event.MouseMotionListener;
+import java.awt.font.FontRenderContext;
+import java.awt.font.TextLayout;
+import java.awt.geom.AffineTransform;
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
 
@@ -66,7 +68,21 @@
   
   public void propertyChange(PropertyChangeEvent e)
   {
-    // TODO: What should be done here, if anything?
+    // Store the TextLayout for this in a client property for speed-up
+    // painting of the label.
+    String property = e.getPropertyName();
+    if (property.equals(AbstractButton.TEXT_CHANGED_PROPERTY)
+        || property.equals("font"))
+      {
+        AbstractButton b = (AbstractButton) e.getSource();
+        String text = b.getText();
+        if (text == null)
+          text = "";
+        FontRenderContext frc = new FontRenderContext(new AffineTransform(),
+                                                      false, false);
+        TextLayout layout = new TextLayout(text, b.getFont(), frc);
+        b.putClientProperty(BasicGraphicsUtils.CACHED_TEXT_LAYOUT, layout);
+      }
   }
   
   protected void checkOpacity(AbstractButton b) 

Index: javax/swing/plaf/basic/BasicButtonUI.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/javax/swing/plaf/basic/BasicButtonUI.java,v
retrieving revision 1.38
retrieving revision 1.39
diff -u -b -r1.38 -r1.39
--- javax/swing/plaf/basic/BasicButtonUI.java   1 Jun 2006 05:17:02 -0000       
1.38
+++ javax/swing/plaf/basic/BasicButtonUI.java   21 Jun 2006 13:13:40 -0000      
1.39
@@ -442,13 +442,17 @@
     if (b.isEnabled())
       {
         g.setColor(b.getForeground());
-        g.drawString(text, textRect.x, textRect.y + fm.getAscent());
+        // FIXME: Underline mnemonic.
+        BasicGraphicsUtils.drawString(b, g, text, -1, textRect.x,
+                                      textRect.y + fm.getAscent());
       }
     else
       {
         String prefix = getPropertyPrefix();
         g.setColor(UIManager.getColor(prefix + "disabledText"));
-        g.drawString(text, textRect.x, textRect.y + fm.getAscent());
+        // FIXME: Underline mnemonic.
+        BasicGraphicsUtils.drawString(b, g, text, -1, textRect.x,
+                                      textRect.y + fm.getAscent());
       }
   } 
 }

Index: javax/swing/plaf/basic/BasicGraphicsUtils.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/javax/swing/plaf/basic/BasicGraphicsUtils.java,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -b -r1.17 -r1.18
--- javax/swing/plaf/basic/BasicGraphicsUtils.java      18 Oct 2005 22:10:32 
-0000      1.17
+++ javax/swing/plaf/basic/BasicGraphicsUtils.java      21 Jun 2006 13:13:40 
-0000      1.18
@@ -37,6 +37,8 @@
 
 package javax.swing.plaf.basic;
 
+import gnu.classpath.SystemProperties;
+
 import java.awt.Color;
 import java.awt.Dimension;
 import java.awt.Font;
@@ -65,6 +67,14 @@
 public class BasicGraphicsUtils
 {
   /**
+   * Used as a key for a client property to store cached TextLayouts in. This
+   * is used for speed-up drawing of text in
+   * address@hidden #drawString(Graphics, String, int, int, int)}.
+   */
+  static final String CACHED_TEXT_LAYOUT =
+    "BasicGraphicsUtils.cachedTextLayout";
+
+  /**
    * Constructor. It is utterly unclear why this class should
    * be constructable, but this is what the API specification
    * says.
@@ -536,6 +546,170 @@
     g2.fill(underline);
   }
 
+  /**
+   * Draws a string on the specified component.
+   *
+   * @param c the component
+   * @param g the Graphics context
+   * @param text the string
+   * @param underlinedChar the character to be underlined
+   * @param x the X location
+   * @param y the Y location
+   */
+  static void drawString(JComponent c, Graphics g, String text,
+                                int underlinedChar, int x, int y)
+  {
+    int index = -1;
+
+    /* It is intentional that lower case is used. In some languages,
+     * the set of lowercase characters is larger than the set of
+     * uppercase ones. Therefore, it is good practice to use lowercase
+     * for such comparisons (which really means that the author of this
+     * code can vaguely remember having read some Unicode techreport
+     * with this recommendation, but is too lazy to look for the URL).
+     */
+    if ((underlinedChar >= 0) || (underlinedChar <= 0xffff))
+      index = text.toLowerCase().indexOf(
+        Character.toLowerCase((char) underlinedChar));
+
+    drawStringUnderlineCharAt(c, g, text, index, x, y);
+  }
+
+
+  /**
+   * Draws a String at the given location, underlining the character
+   * at the specified index. Drawing is performed in the current color
+   * and font of <code>g</code>.
+   *
+   * <p><img src="doc-files/BasicGraphicsUtils-5.png" width="500"
+   * height="100" alt="[An illustration showing how to use the
+   * method]" />
+   *
+   * This is an accelerated version of the method with the same name. It
+   * uses a pre-laid out TextLayout stored in a client property.
+   *
+   * @param c the component that is drawn
+   * @param g the graphics into which the String is drawn.
+   *
+   * @param text the String to draw.
+   *
+   * @param underlinedIndex the index of the underlined character in
+   *        <code>text</code>.  If <code>underlinedIndex</code> falls
+   *        outside the range <code>[0, text.length() - 1]</code>, the
+   *        text will be drawn without underlining anything.
+   *        
+   * @param x the x coordinate of the text, as it would be passed to
+   *        address@hidden java.awt.Graphics#drawString(java.lang.String,
+   *        int, int)}.
+   *
+   * @param y the y coordinate of the text, as it would be passed to
+   *        address@hidden java.awt.Graphics#drawString(java.lang.String,
+   *        int, int)}.
+   */
+  static void drawStringUnderlineCharAt(JComponent c, Graphics g, String text,
+                                        int underlinedIndex,
+                                        int x, int y)
+  {
+    Graphics2D g2;
+    Rectangle2D.Double underline;
+    FontRenderContext frc;
+    FontMetrics fmet;
+    LineMetrics lineMetrics;
+    Font font;
+    TextLayout layout;
+    double underlineX1, underlineX2;
+    boolean drawUnderline;
+    int textLength;
+
+    textLength = text.length();
+    if (textLength == 0)
+      return;
+
+    drawUnderline = (underlinedIndex >= 0) && (underlinedIndex < textLength);
+
+    // FIXME: unfortunately pango and cairo can't agree on metrics
+    // so for the time being we continue to *not* use TextLayouts.
+    if (!(g instanceof Graphics2D)
+       || SystemProperties.getProperty("gnu.javax.swing.noGraphics2D") != null)
+    {
+      /* Fall-back. This is likely to produce garbage for any text
+       * containing right-to-left (Hebrew or Arabic) characters, even
+       * if the underlined character is left-to-right.
+       */
+      g.drawString(text, x, y);
+      if (drawUnderline)
+      {
+        fmet = g.getFontMetrics();
+        g.fillRect(
+          /* x */ x + fmet.stringWidth(text.substring(0, underlinedIndex)),
+          /* y */ y + fmet.getDescent() - 1,
+          /* width */ fmet.charWidth(text.charAt(underlinedIndex)),
+          /* height */ 1);
+      }
+
+      return;
+    }
+
+    g2 = (Graphics2D) g;
+    font = g2.getFont();
+    frc = g2.getFontRenderContext();
+    lineMetrics = font.getLineMetrics(text, frc);
+    layout = (TextLayout) c.getClientProperty(CACHED_TEXT_LAYOUT);
+    if (layout == null)
+      {
+        layout = new TextLayout(text, font, frc);
+        System.err.println("Unable to use cached TextLayout for: " + text);
+      }
+
+    /* Draw the text. */
+    layout.draw(g2, x, y);
+    if (!drawUnderline)
+      return;
+
+    underlineX1 = x + layout.getLogicalHighlightShape(
+     underlinedIndex, underlinedIndex).getBounds2D().getX();
+    underlineX2 = x + layout.getLogicalHighlightShape(
+     underlinedIndex + 1, underlinedIndex + 1).getBounds2D().getX();
+
+    underline = new Rectangle2D.Double();
+    if (underlineX1 < underlineX2)
+    {
+      underline.x = underlineX1;
+      underline.width = underlineX2 - underlineX1;
+    }
+    else
+    {
+      underline.x = underlineX2;
+      underline.width = underlineX1 - underlineX2;
+    }
+
+    
+    underline.height = lineMetrics.getUnderlineThickness();
+    underline.y = lineMetrics.getUnderlineOffset();
+    if (underline.y == 0)
+    {
+      /* Some fonts do not specify an underline offset, although they
+       * actually should do so. In that case, the result of calling
+       * lineMetrics.getUnderlineOffset() will be zero. Since it would
+       * look very ugly if the underline was be positioned immediately
+       * below the baseline, we check for this and move the underline
+       * below the descent, as shown in the following ASCII picture:
+       *
+       *   #####       ##### #
+       *  #     #     #     #
+       *  #     #     #     #
+       *  #     #     #     #
+       *   #####       ######        ---- baseline (0)
+       *                    #
+       *                    #
+       * ------------------###----------- lineMetrics.getDescent()
+       */
+      underline.y = lineMetrics.getDescent();
+    }
+
+    underline.y += y;
+    g2.fill(underline);
+  }
 
   /**
    * Draws a rectangle, simulating a dotted stroke by painting only

Index: javax/swing/plaf/basic/BasicMenuItemUI.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/javax/swing/plaf/basic/BasicMenuItemUI.java,v
retrieving revision 1.47
retrieving revision 1.48
diff -u -b -r1.47 -r1.48
--- javax/swing/plaf/basic/BasicMenuItemUI.java 13 Jun 2006 09:28:57 -0000      
1.47
+++ javax/swing/plaf/basic/BasicMenuItemUI.java 21 Jun 2006 13:13:40 -0000      
1.48
@@ -52,11 +52,15 @@
 import java.awt.event.ItemListener;
 import java.awt.event.KeyEvent;
 import java.awt.event.MouseEvent;
+import java.awt.font.FontRenderContext;
+import java.awt.font.TextLayout;
+import java.awt.geom.AffineTransform;
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
 import java.util.ArrayList;
 
 import javax.swing.AbstractAction;
+import javax.swing.AbstractButton;
 import javax.swing.ActionMap;
 import javax.swing.ButtonModel;
 import javax.swing.Icon;
@@ -237,7 +241,8 @@
      */
     public void propertyChange(PropertyChangeEvent e)
     {
-      if (e.getPropertyName() == "accelerator")
+      String property = e.getPropertyName();
+      if (property.equals("accelerator"))
         {
           InputMap map = SwingUtilities.getUIInputMap(menuItem, 
               JComponent.WHEN_IN_FOCUSED_WINDOW);
@@ -250,6 +255,19 @@
           if (accelerator != null)
             map.put(accelerator, "doClick");
         }
+      // TextLayout caching for speed-up drawing of text.
+      else if (property.equals(AbstractButton.TEXT_CHANGED_PROPERTY)
+          || property.equals("font"))
+        {
+          AbstractButton b = (AbstractButton) e.getSource();
+          String text = b.getText();
+          if (text == null)
+            text = "";
+          FontRenderContext frc = new FontRenderContext(new AffineTransform(),
+                                                        false, false);
+          TextLayout layout = new TextLayout(text, b.getFont(), frc);
+          b.putClientProperty(BasicGraphicsUtils.CACHED_TEXT_LAYOUT, layout);
+        }
     }
   }
   
@@ -833,12 +851,13 @@
         int mnemonicIndex = menuItem.getDisplayedMnemonicIndex();
 
         if (mnemonicIndex != -1)
-          BasicGraphicsUtils.drawStringUnderlineCharAt(g, text, mnemonicIndex,
+          BasicGraphicsUtils.drawStringUnderlineCharAt(menuItem, g, text,
+                                                       mnemonicIndex,
                                                        textRect.x,
                                                        textRect.y
                                                            + fm.getAscent());
         else
-          BasicGraphicsUtils.drawString(g, text, 0, textRect.x,
+          BasicGraphicsUtils.drawString(menuItem, g, text, 0, textRect.x,
                                         textRect.y + fm.getAscent());
       }
   }

Index: javax/swing/plaf/basic/BasicMenuUI.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/plaf/basic/BasicMenuUI.java,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -b -r1.23 -r1.24
--- javax/swing/plaf/basic/BasicMenuUI.java     17 Apr 2006 07:41:05 -0000      
1.23
+++ javax/swing/plaf/basic/BasicMenuUI.java     21 Jun 2006 13:13:40 -0000      
1.24
@@ -230,10 +230,8 @@
    */
   protected void installListeners()
   {
-    ((JMenu) menuItem).addMouseListener(mouseInputListener);
-    ((JMenu) menuItem).addMouseMotionListener(mouseInputListener);
+    super.installListeners();
     ((JMenu) menuItem).addMenuListener(menuListener);
-    ((JMenu) menuItem).addMenuDragMouseListener(menuDragMouseListener);
   }
 
   protected void setupPostTimer(JMenu menu)
@@ -276,9 +274,8 @@
    */
   protected void uninstallListeners()
   {
-    ((JMenu) menuItem).removeMouseListener(mouseInputListener);
+    super.uninstallListeners();
     ((JMenu) menuItem).removeMenuListener(menuListener);
-    ((JMenu) menuItem).removePropertyChangeListener(propertyChangeListener);
   }
 
   /**




reply via email to

[Prev in Thread] Current Thread [Next in Thread]