Revision: 550
Author: allain.lalonde
Date: Thu Jul 23 08:41:42 2009
Log: Fixed Issue 83; Transforming graphics context was introducing slight  
rounding errors in the font metrics measurements. Calculating string widths  
using compnent.getGraphics() would yield slightly smaller widths than  
calculating them using the active Graphics object.

The fix is to calculate the "minimum acceptable" width that erring  
components (JButtons and JLabels) can be given the current graphics context  
and checking to see if it's larger than the minimum width the JLabel is  
reporting (which is computed at creation time assuming an identity  
transform). If it's larger (ellipsis would be shown) then it changes the  
minimum size of the component to be the the nearest  
ceil(minAcceptableWidth).

The calculation for the minimum size involves measuring text, adding  
insets, affording for icons and icon gaps.

Also, when calculating the bounds of the component, insets were not being  
considered but should have been.

Only hackish element of this fix is that its only applied to JButton and  
JLabels right now since I think they're the only components I can think of  
that calculate their minimum sizes in this way.
http://code.google.com/p/piccolo2d/source/detail?r=550

Modified:
   
/piccolo2d.java/trunk/examples/src/main/java/edu/umd/cs/piccolo/examples/pswing/PSwingExample2.java
   
/piccolo2d.java/trunk/extras/src/main/java/edu/umd/cs/piccolox/pswing/PSwing.java

=======================================
---  
/piccolo2d.java/trunk/examples/src/main/java/edu/umd/cs/piccolo/examples/pswing/PSwingExample2.java
      
Fri Jul 17 06:39:05 2009
+++  
/piccolo2d.java/trunk/examples/src/main/java/edu/umd/cs/piccolo/examples/pswing/PSwingExample2.java
      
Thu Jul 23 08:41:42 2009
@@ -30,14 +30,17 @@

  import java.awt.BorderLayout;
  import java.awt.Color;
+import java.awt.Component;
  import java.awt.Cursor;
  import java.awt.Dimension;
+import java.awt.Graphics;
  import java.awt.event.ActionEvent;
  import java.io.IOException;
  import java.util.Vector;

  import javax.swing.AbstractAction;
  import javax.swing.Action;
+import javax.swing.Icon;
  import javax.swing.JButton;
  import javax.swing.JCheckBox;
  import javax.swing.JComponent;
@@ -227,13 +230,34 @@

          // A JLabel
          JLabel label = new JLabel("A JLabel", SwingConstants.CENTER);
-
          swing = new PSwing(label);
          leaf = new ZVisualLeaf(swing);
          transform = new PNode();
          transform.translate(-500, 0);
          transform.addChild(leaf);
          canvas.getLayer().addChild(transform);
+
+        label = new JLabel("A JLabel", SwingConstants.CENTER);
+        label.setIcon(new Icon() {
+
+            public int getIconHeight() {
+                return 20;
+            }
+
+            public int getIconWidth() {
+                return 20;
+            }
+
+            public void paintIcon(Component c, Graphics g, int x, int y) {
+                g.setColor(Color.BLUE);
+                g.drawRect(0, 0, 20, 20);
+            }});
+        swing = new PSwing(label);
+        leaf = new ZVisualLeaf(swing);
+        transform = new PNode();
+        transform.translate(-500, 30);
+        transform.addChild(leaf);
+        canvas.getLayer().addChild(transform);

          // Rotated copy of the Scrollable JTextArea
          leaf = new ZVisualLeaf(swing2);
=======================================
---  
/piccolo2d.java/trunk/extras/src/main/java/edu/umd/cs/piccolox/pswing/PSwing.java
        
Sun Jul 19 16:56:41 2009
+++  
/piccolo2d.java/trunk/extras/src/main/java/edu/umd/cs/piccolox/pswing/PSwing.java
        
Thu Jul 23 08:41:42 2009
@@ -32,8 +32,10 @@
  import java.awt.Color;
  import java.awt.Component;
  import java.awt.Container;
+import java.awt.Dimension;
  import java.awt.Font;
  import java.awt.Graphics2D;
+import java.awt.Insets;
  import java.awt.RenderingHints;
  import java.awt.Shape;
  import java.awt.Stroke;
@@ -50,8 +52,12 @@
  import java.util.ArrayList;
  import java.util.Arrays;

+import javax.swing.Icon;
+import javax.swing.JButton;
  import javax.swing.JComponent;
+import javax.swing.JLabel;
  import javax.swing.RepaintManager;
+import javax.swing.border.Border;

  import edu.umd.cs.piccolo.PCamera;
  import edu.umd.cs.piccolo.PLayer;
@@ -213,7 +219,7 @@
      private JComponent component = null;
      private double minFontSize = Double.MAX_VALUE;
      private Stroke defaultStroke = new BasicStroke();
-    private Font defaultFont = new Font("Serif", Font.PLAIN, 12);
+    private Font defaultFont = new Font("Serif", Font.PLAIN, 12);
      private PSwingCanvas canvas;

      // //////////////////////////////////////////////////////////
@@ -258,11 +264,11 @@
          });

          component.addComponentListener(new ComponentAdapter() {
-            public void componentHidden(ComponentEvent e) {
+            public void componentHidden(ComponentEvent e) {
                  setVisible(false);
              }

-            public void componentShown(ComponentEvent e) {
+            public void componentShown(ComponentEvent e) {
                  setVisible(true);
              }
          });
@@ -288,8 +294,19 @@
       * bounds of this PNode.
       */
      void reshape() {
-        component.setBounds(0, 0, component.getPreferredSize().width,  
component.getPreferredSize().height);
-        setBounds(0, 0, component.getPreferredSize().width,  
component.getPreferredSize().height);
+        Border border = component.getBorder();
+
+        int width = (int) Math.max(component.getMinimumSize().width,  
component.getPreferredSize().width);
+        int height = (int) Math.max(component.getMinimumSize().height,  
component.getPreferredSize().height);
+
+        if (border != null) {
+            Insets borderInsets = border.getBorderInsets(component);
+            width += borderInsets.left + borderInsets.right;
+            height += borderInsets.top + borderInsets.bottom;
+        }
+
+        component.setBounds(0, 0, width, height);
+        setBounds(0, 0, width, height);
      }

      /**
@@ -323,6 +340,15 @@
              // pSwingCanvas.getSwingWrapper().add( component );
              component.revalidate();
          }
+
+        if (component instanceof JLabel) {
+            JLabel label = (JLabel)component;
+            enforceNoEllipsis(label.getText(), label.getIcon(),  
label.getIconTextGap(), g2);
+        }
+        else if (component instanceof JButton) {
+            JButton button = (JButton)component;
+            enforceNoEllipsis(button.getText(), button.getIcon(),  
button.getIconTextGap(), g2);
+        }

          if (shouldRenderGreek(renderContext)) {
              paintAsGreek(g2);
@@ -330,7 +356,24 @@
          else {
              paint(g2);
          }
-
+    }
+
+    private void enforceNoEllipsis(String text, Icon icon, int iconGap,  
Graphics2D g2) {
+        Rectangle2D textBounds =  
component.getFontMetrics(component.getFont()).getStringBounds(text, g2);
+        double minAcceptableWidth = textBounds.getWidth();
+        double minAcceptableHeight = textBounds.getHeight();
+
+        if (icon != null) {
+            minAcceptableWidth += icon.getIconWidth();
+            minAcceptableWidth += iconGap;
+            minAcceptableHeight = Math.max(icon.getIconHeight(),  
minAcceptableHeight);
+        }
+
+        if (component.getMinimumSize().getWidth() < minAcceptableWidth ) {
+            Dimension newMinimumSize = new  
Dimension((int)Math.ceil(minAcceptableWidth),  
(int)Math.ceil(minAcceptableHeight));
+            component.setMinimumSize(newMinimumSize);
+            reshape();
+        }
      }

      protected boolean shouldRenderGreek(PPaintContext renderContext) {
@@ -387,8 +430,10 @@
          manager.lockRepaint(component);

          RenderingHints oldHints = g2.getRenderingHints();
-
+
          g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,  
RenderingHints.VALUE_FRACTIONALMETRICS_ON);
+        g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,  
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
+
          component.paint(g2);

          g2.setRenderingHints(oldHints);
@@ -399,7 +444,7 @@
      public void setVisible(boolean visible) {
          super.setVisible(visible);
          component.setVisible(visible);
-    }
+    }

      /**
       * Repaints the specified portion of this visual component Note that  
the
@@ -419,14 +464,7 @@
       * copy of these bounds
       */
      public void computeBounds() {
-        reshape();
-        // if( !component.getBounds().isEmpty() ) {
-        // Dimension d = component.getPreferredSize();
-        // getBoundsReference().setRect( 0, 0, d.getWidth(), d.getHeight()  
);
-        // if( !component.getSize().equals( d ) ) {
-        // component.setBounds( 0, 0, (int)d.getWidth(),  
(int)d.getHeight() );
-        // }
-        // }
+        reshape();
      }

      /**

--~--~---------~--~----~------------~-------~--~----~
Piccolo2D Developers Group: http://groups.google.com/group/piccolo2d-dev?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to