Revision: 809
Author: allain.lalonde
Date: Fri Oct 23 13:53:33 2009
Log: Rolling Back All paint changes to PSwing. It was working acceptably  
for clients and the changes were breaking changes. A rollback is the  
simplest thing to do to get this into a "working" state again.

Also, starting on a cleaner PSwing Example to really test all the edge  
cases we can.
http://code.google.com/p/piccolo2d/source/detail?r=809

Added:
   
/piccolo2d.java/trunk/examples/src/main/java/edu/umd/cs/piccolo/examples/pswing/PSwingExample3.java
Modified:
   
/piccolo2d.java/trunk/extras/src/main/java/edu/umd/cs/piccolox/pswing/PSwing.java
   
/piccolo2d.java/trunk/extras/src/test/java/edu/umd/cs/piccolox/pswing/PSwingTest.java

=======================================
--- /dev/null
+++  
/piccolo2d.java/trunk/examples/src/main/java/edu/umd/cs/piccolo/examples/pswing/PSwingExample3.java
      
Fri Oct 23 13:53:33 2009
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2008-2009, Piccolo2D project, http://piccolo2d.org
+ * Copyright (c) 1998-2008, University of Maryland
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without  
modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,  
this list of conditions
+ * and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright  
notice, this list of conditions
+ * and the following disclaimer in the documentation and/or other  
materials provided with the
+ * distribution.
+ *
+ * None of the name of the University of Maryland, the name of the  
Piccolo2D project, or the names of its
+ * contributors may be used to endorse or promote products derived from  
this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS  
IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF  
MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  
OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL  
DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,  
DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN  
CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE  
USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package edu.umd.cs.piccolo.examples.pswing;
+
+import java.awt.Dimension;
+import java.awt.Graphics2D;
+
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+
+import edu.umd.cs.piccolo.PNode;
+import edu.umd.cs.piccolo.nodes.PText;
+import edu.umd.cs.piccolo.util.PPaintContext;
+import edu.umd.cs.piccolox.pswing.PSwing;
+import edu.umd.cs.piccolox.pswing.PSwingCanvas;
+
+/**
+ * User: Sam Reid Date: Jul 11, 2005 Time: 12:15:55 PM
+ */
+public class PSwingExample3 extends JFrame {
+    private static final long serialVersionUID = 1L;
+    private ExampleList exampleList;
+
+    public PSwingExample3() {
+        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+        PSwingCanvas canvas;
+
+        // Set up basic frame
+        setBounds(50, 50, 750, 750);
+        setResizable(true);
+        setBackground(null);
+        setVisible(true);
+        canvas = new PSwingCanvas();
+        canvas.setPanEventHandler(null);
+        getContentPane().add(canvas);
+        validate();
+
+        exampleList = new ExampleList("Button Examples");
+
+        addButtonExamples();
+
+        canvas.getLayer().addChild(exampleList);
+
+         
canvas.getCamera().animateViewToCenterBounds(canvas.getLayer().getFullBounds(), 
 
true, 1200);
+    }
+
+    private void addButtonExamples() {
+        addButtonAloneNoSizing();
+        addButtonAlone200x50();
+        addButtonOnPanelNoSizing();
+        addButtonOnPanel200x50();
+        addButtonAlone10x10();
+    }
+
+    private void addButtonAloneNoSizing() {
+        JButton button = new JButton("Button");
+        PSwing pButton = new PSwing(button);
+        exampleList.addExample("Alone - No Sizing", pButton);
+    }
+
+    private void addButtonAlone200x50() {
+        JButton button = new JButton("Button");
+        button.setPreferredSize(new Dimension(200, 50));
+        PSwing pButton = new PSwing(button);
+        exampleList.addExample("Alone - 200x50", pButton);
+    }
+
+    private void addButtonAlone10x10() {
+        JButton button = new JButton("Button");
+        button.setPreferredSize(new Dimension(10, 10));
+        PSwing pButton = new PSwing(button);
+        exampleList.addExample("Alone - 10x10", pButton);
+    }
+
+    private void addButtonOnPanelNoSizing() {
+        JButton button = new JButton("Button");
+        JPanel panel = new JPanel();
+        panel.add(button);
+        PSwing pPanel = new PSwing(panel);
+
+        exampleList.addExample("On JPanel - No Sizing", pPanel);
+    }
+
+    private void addButtonOnPanel200x50() {
+        JButton button = new JButton("Button");
+        button.setPreferredSize(new Dimension(200, 50));
+
+        JPanel panel = new JPanel();
+        panel.add(button);
+        PSwing pPanel = new PSwing(panel);
+
+        exampleList.addExample("On JPanel - 200x50", pPanel);
+    }
+
+    public static void main(final String[] args) {
+        new PSwingExample3().setVisible(true);
+    }
+
+    class ExampleList extends PText {
+        ExampleList(String name) {
+            super(name);
+            setScale(2);
+        }
+
+        public void layoutChildren() {
+            PNode node;
+            double currentY = getHeight();
+            for (int i=0; i<getChildrenCount(); i++) {
+                node = getChild(i);
+                node.setOffset(0, currentY);
+                currentY += node.getFullBounds().getHeight() + 5;
+            }
+        }
+
+        public void addExample(String name, PNode example) {
+            ExampleNode exampleNode = new ExampleNode(name, example);
+            exampleNode.setScale(0.5);
+            addChild(exampleNode);
+        }
+
+        class ExampleNode extends PText {
+            ExampleNode(String name, PNode example) {
+                super(name);
+
+                addChild(example);
+            }
+
+            public void layoutChildren() {
+                PNode example = getChild(0);
+                example.setOffset(getWidth()+5, 0);
+                //example.setScale(getHeight() / example.getHeight());
+            }
+        }
+    }
+}
=======================================
---  
/piccolo2d.java/trunk/extras/src/main/java/edu/umd/cs/piccolox/pswing/PSwing.java
        
Thu Oct 22 20:02:42 2009
+++  
/piccolo2d.java/trunk/extras/src/main/java/edu/umd/cs/piccolox/pswing/PSwing.java
        
Fri Oct 23 13:53:33 2009
@@ -35,14 +35,16 @@
  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;
  import java.awt.event.ComponentAdapter;
  import java.awt.event.ComponentEvent;
  import java.awt.event.ContainerAdapter;
  import java.awt.event.ContainerEvent;
+import java.awt.geom.AffineTransform;
  import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
  import java.beans.PropertyChangeEvent;
  import java.beans.PropertyChangeListener;
  import java.io.IOException;
@@ -57,7 +59,6 @@
  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;
@@ -219,6 +220,8 @@

      /** Minimum font size. */
      private double minFontSize = Double.MAX_VALUE;
+
+    private static final AffineTransform IDENTITY_TRANSFORM = new  
AffineTransform();

      /**
       * Default stroke, <code>new BasicStroke()</code>. Cannot be made  
static
@@ -226,6 +229,8 @@
       */
      private transient Stroke defaultStroke = new BasicStroke();

+    private static final Color BUFFER_BACKGROUND_COLOR = new Color( 0, 0,  
0, 0 );
+
      /**
       * Default font, 12 point <code>"SansSerif"</code>. Will be made final  
in
       * version 2.0.
@@ -240,6 +245,8 @@
      /** Swing canvas for this swing node. */
      private PSwingCanvas canvas;

+    private BufferedImage buffer;
+
      /**
       * Used to keep track of which nodes we've attached listeners to since  
no
       * built in support in PNode.
@@ -326,18 +333,8 @@
       * bounds of this PNode.
       */
      void reshape() {
-        final Border border = component.getBorder();
-
-        int width = Math.max(component.getMinimumSize().width,  
component.getPreferredSize().width);
-        final int height = component.getPreferredSize().height;
-
-        if (border != null) {
-            final Insets borderInsets = border.getBorderInsets(component);
-            width += borderInsets.left + borderInsets.right;
-        }
-
-        component.setBounds(0, 0, width, height);
-        setBounds(0, 0, width, height);
+        component.setBounds( 0, 0, component.getPreferredSize().width,  
component.getPreferredSize().height );
+        setBounds( 0, 0, component.getPreferredSize().width,  
component.getPreferredSize().height );
      }

      /** {...@inheritdoc} */
@@ -354,52 +351,15 @@
          if (component.getParent() == null) {
              component.revalidate();
          }
-
-        if (component instanceof JLabel) {
-            final JLabel label = (JLabel) component;
-            enforceNoEllipsis(label.getText(), label.getIcon(),  
label.getIconTextGap(), graphics);
-        }
-        else if (component instanceof JButton) {
-            final JButton button = (JButton) component;
-            enforceNoEllipsis(button.getText(), button.getIcon(),  
button.getIconTextGap(), graphics);
-        }
-
+
          if (shouldRenderGreek(paintContext)) {
-            paintGreek(paintContext);
+            paintGreek(graphics);
          }
          else {
-            paintComponent(paintContext);
-        }
-    }
-
-    /**
-     * Workaround to prevent text-rendering Swing components from drawing  
an
-     * ellipsis incorrectly.
-     *
-     * @param text text
-     * @param icon icon
-     * @param iconGap icon gap
-     * @param graphics graphics
-     */
-    private void enforceNoEllipsis(final String text, final Icon icon,  
final int iconGap, final Graphics2D graphics) {
-        final Rectangle2D textBounds =  
component.getFontMetrics(component.getFont()).getStringBounds(text,  
graphics);
-        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) {
-            final Dimension newMinimumSize = new Dimension((int)  
Math.ceil(minAcceptableWidth), (int) Math
-                    .ceil(minAcceptableHeight));
-            component.setMinimumSize(newMinimumSize);
-            reshape();
-        }
-    }
-
+            paintComponent(graphics);
+        }
+    }
+
      /**
       * Return the greek threshold in scale. When the scale will be below  
this
       * threshold the Swing component is rendered as 'greek' instead of  
painting
@@ -445,8 +405,7 @@
       *
       * @param paintContext paint context
       */
-    protected void paintGreek(final PPaintContext paintContext) {
-        final Graphics2D graphics = paintContext.getGraphics();
+    protected void paintGreek(final Graphics2D graphics) {
          final Color background = component.getBackground();
          final Color foreground = component.getForeground();
          final Rectangle2D rect = getBounds();
@@ -477,18 +436,55 @@
       *
       * @param paintContext paint context
       */
-    protected void paintComponent(final PPaintContext paintContext) {
-        if (component.getBounds().isEmpty()) {
+    protected void paintComponent(final Graphics2D g2) {
+        if( component.getBounds().isEmpty() ) {
              // The component has not been initialized yet.
              return;
          }

-        final Graphics2D graphics = paintContext.getGraphics();
-        final PSwingRepaintManager manager = (PSwingRepaintManager)  
RepaintManager.currentManager(component);
-        manager.lockRepaint(component);
-        component.paint(graphics);
-        manager.unlockRepaint(component);
-    }
+        PSwingRepaintManager manager =  
(PSwingRepaintManager)RepaintManager.currentManager( component );
+        manager.lockRepaint( component );
+
+        Graphics2D bufferedGraphics = null;
+        if( !isBufferValid() ) {
+            // Get the graphics context associated with a new buffered  
image.
+            // Use TYPE_INT_ARGB_PRE so that transparent components look  
good on Windows.
+            buffer = new BufferedImage( component.getWidth(),  
component.getHeight(), BufferedImage.TYPE_INT_ARGB_PRE );
+            bufferedGraphics = buffer.createGraphics();
+        }
+        else {
+            // Use the graphics context associated with the existing  
buffered image
+            bufferedGraphics = buffer.createGraphics();
+            // Clear the buffered image to prevent artifacts on Macintosh
+            bufferedGraphics.setBackground( BUFFER_BACKGROUND_COLOR );
+            bufferedGraphics.clearRect( 0, 0, component.getWidth(),  
component.getHeight() );
+        }
+
+        // Start with the rendering hints from the provided graphics  
context
+        bufferedGraphics.setRenderingHints( g2.getRenderingHints() );
+
+        //PSwing sometimes causes JComponent text to render with "..."  
when fractional font metrics are enabled.  These are now always disabled  
for the offscreen buffer.
+        bufferedGraphics.setRenderingHint(  
RenderingHints.KEY_FRACTIONALMETRICS,  
RenderingHints.VALUE_FRACTIONALMETRICS_OFF );
+
+        // Draw the component to the buffer
+        component.paint( bufferedGraphics );
+
+        // Draw the buffer to g2's associated drawing surface
+        g2.drawRenderedImage( buffer, IDENTITY_TRANSFORM );
+
+        manager.unlockRepaint( component );
+    }
+
+    /**
+     * Tells whether the buffer for the image of the Swing components
+     * is currently valid.
+     *
+     * @return true if the buffer is currently valid
+     */
+    private boolean isBufferValid() {
+        return !( buffer == null || buffer.getWidth() !=  
component.getWidth() || buffer.getHeight() != component.getHeight() );
+    }
+

      /** {...@inheritdoc} */
      public void setVisible(final boolean visible) {
=======================================
---  
/piccolo2d.java/trunk/extras/src/test/java/edu/umd/cs/piccolox/pswing/PSwingTest.java
    
Tue Oct 20 19:27:31 2009
+++  
/piccolo2d.java/trunk/extras/src/test/java/edu/umd/cs/piccolox/pswing/PSwingTest.java
    
Fri Oct 23 13:53:33 2009
@@ -291,17 +291,16 @@
              return image;
          }

-        public void paintComponentOnto(BufferedImage image) {
-            PPaintContext paintContext = new  
PPaintContext(image.createGraphics());
-            paintComponent(paintContext);
+        public void paintComponentOnto(BufferedImage image) {
+            paintComponent(image.createGraphics());
          }

-        protected void paintComponent(PPaintContext paintContext) {
+        protected void paintComponent(Graphics2D paintContext) {
              super.paintComponent(paintContext);
              paintedComponent = true;
          }

-        protected void paintGreek(PPaintContext paintContext) {
+        protected void paintGreek(Graphics2D paintContext) {
              super.paintGreek(paintContext);
              paintedGreek = true;
          }

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

Reply via email to