Index: graph/examples/src/org/netbeans/modules/visual/examples/RunDialog.java =================================================================== RCS file: /cvs/graph/examples/src/org/netbeans/modules/visual/examples/RunDialog.java,v retrieving revision 1.77 diff -u -r1.77 RunDialog.java --- graph/examples/src/org/netbeans/modules/visual/examples/RunDialog.java 19 Jul 2007 07:15:42 -0000 1.77 +++ graph/examples/src/org/netbeans/modules/visual/examples/RunDialog.java 3 Aug 2007 08:00:17 -0000 @@ -105,6 +105,7 @@ "test.swingborder.SwingBorderTest", "test.tool.CtrlKeySwitchToolTest", "test.tool.ToolTest", + "test.view.OffscreenRenderingTest", "test.visible.VisibilityTest", "test.vmd.VMDCollisionTest", "test.vmd.VMDColorSchemeTest", Index: graph/examples/src/test/view/OffscreenRenderingTest.java =================================================================== RCS file: graph/examples/src/test/view/OffscreenRenderingTest.java diff -N graph/examples/src/test/view/OffscreenRenderingTest.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ graph/examples/src/test/view/OffscreenRenderingTest.java 3 Aug 2007 08:00:18 -0000 @@ -0,0 +1,65 @@ +/* + * The contents of this file are subject to the terms of the Common Development + * and Distribution License (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the License at http://www.netbeans.org/cddl.html + * or http://www.netbeans.org/cddl.txt. + * + * When distributing Covered Code, include this CDDL Header Notice in each file + * and include the License file at http://www.netbeans.org/cddl.txt. + * If applicable, add the following below the CDDL Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun + * Microsystems, Inc. All Rights Reserved. + */ + +package test.view; + +import org.netbeans.api.visual.border.BorderFactory; +import org.netbeans.api.visual.widget.LabelWidget; +import org.netbeans.api.visual.widget.Scene; +import test.SceneSupport; + +import javax.swing.*; +import java.awt.*; +import java.awt.image.BufferedImage; + +/** + * @author David Kaspar + */ +public class OffscreenRenderingTest { + + public static void main (String[] args) { + Scene scene = new Scene (); + + LabelWidget widget = new LabelWidget (scene, "Hi"); + widget.setVerticalAlignment (LabelWidget.VerticalAlignment.CENTER); + widget.setAlignment (LabelWidget.Alignment.CENTER); + widget.setBorder (BorderFactory.createLineBorder ()); + widget.setPreferredSize (new Dimension (40, 40)); + scene.addChild (widget); + + // validate the scene with a off-screen graphics + BufferedImage emptyImage = new BufferedImage (1, 1, BufferedImage.TYPE_4BYTE_ABGR); + Graphics2D emptyGraphics = emptyImage.createGraphics (); + scene.validate (emptyGraphics); + emptyGraphics.dispose (); + + // now the scene is calculated using the emptyGraphics, all widgets should be layout and scene has its size resolved + // paint the scene with a off-screen graphics + Rectangle viewBounds = scene.convertSceneToView (scene.getBounds ()); + BufferedImage image = new BufferedImage (viewBounds.width, viewBounds.height, BufferedImage.TYPE_4BYTE_ABGR); + Graphics2D graphics = image.createGraphics (); + double zoomFactor = scene.getZoomFactor (); + graphics.scale (zoomFactor, zoomFactor); + scene.paint (graphics); + graphics.dispose (); + + SceneSupport.show (new JLabel (new ImageIcon (image))); + } + +} Index: graph/lib/apichanges.xml =================================================================== RCS file: /cvs/graph/lib/apichanges.xml,v retrieving revision 1.33 diff -u -r1.33 apichanges.xml --- graph/lib/apichanges.xml 1 Aug 2007 08:13:34 -0000 1.33 +++ graph/lib/apichanges.xml 3 Aug 2007 08:00:18 -0000 @@ -444,6 +444,21 @@ + + + + Widget.validate(Graphics2D) method added to support off-screen rendering + + + + + + Scene.validate(Graphics2D) method has been added. It allows to validate a scene without having a main scene view created and shown on screen. + See test.view.OffscreenRenderingTest example for usage. + + + + Index: graph/lib/manifest.mf =================================================================== RCS file: /cvs/graph/lib/manifest.mf,v retrieving revision 1.14 diff -u -r1.14 manifest.mf --- graph/lib/manifest.mf 1 Aug 2007 07:31:49 -0000 1.14 +++ graph/lib/manifest.mf 3 Aug 2007 08:00:18 -0000 @@ -1,4 +1,4 @@ Manifest-Version: 1.0 OpenIDE-Module: org.netbeans.api.visual OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/visual/resources/Bundle.properties -OpenIDE-Module-Specification-Version: 2.6 +OpenIDE-Module-Specification-Version: 2.7 Index: graph/lib/src/org/netbeans/api/visual/widget/Scene.java =================================================================== RCS file: /cvs/graph/lib/src/org/netbeans/api/visual/widget/Scene.java,v retrieving revision 1.46 diff -u -r1.46 Scene.java --- graph/lib/src/org/netbeans/api/visual/widget/Scene.java 8 Jun 2007 08:15:35 -0000 1.46 +++ graph/lib/src/org/netbeans/api/visual/widget/Scene.java 3 Aug 2007 08:00:18 -0000 @@ -190,6 +190,21 @@ } /** + * This method invokes Scene.validate method with a specific Graphics2D instance. This is useful for rendering a scene off-screen + * without creating and showning the main scene view. See test.view.OffscreenRenderingTest example for usages. + *

+ * Note: Do not call this method unless you know the consequences. The scene is going to be validated using the specified Graphics2D + * instance even after the method call therefore it may break scene layout when your main scene view is finally created and shown. + * @param graphics the graphics instance used for validation + * @since 2.7 + */ + public final void validate (Graphics2D graphics) { + Graphics2D prevoiusGraphics = getGraphics (); + setGraphics (graphics); + validate (); + setGraphics (prevoiusGraphics); +} + /** * Paints the whole scene into the graphics instance. The method calls validate before rendering. * @param graphics the Graphics2D instance where the scene is going to be painted */ @@ -294,29 +309,31 @@ Dimension preferredSize = rect != null ? rect.getSize () : new Dimension (); preferredSize = new Dimension ((int) (preferredSize.width * zoomFactor), (int) (preferredSize.height * zoomFactor)); - if (! preferredSize.equals (component.getPreferredSize ())) { - component.setPreferredSize (preferredSize); - component.revalidate (); -// repaintSatellite (); - } - - Dimension componentSize = component.getSize (); - componentSize.width = (int) (componentSize.width / zoomFactor); - componentSize.height = (int) (componentSize.height / zoomFactor); Rectangle bounds = getBounds (); + if (component != null) { + if (! preferredSize.equals (component.getPreferredSize ())) { + component.setPreferredSize (preferredSize); + component.revalidate (); + bounds = getBounds (); +// repaintSatellite (); + } - boolean sceneResized = false; - if (bounds.width < componentSize.width) { - bounds.width = componentSize.width; - sceneResized = true; - } - if (bounds.height < componentSize.height) { - bounds.height = componentSize.height; - sceneResized = true; + Dimension componentSize = component.getSize (); + componentSize.width = (int) (componentSize.width / zoomFactor); + componentSize.height = (int) (componentSize.height / zoomFactor); + + boolean sceneResized = false; + if (bounds.width < componentSize.width) { + bounds.width = componentSize.width; + sceneResized = true; + } + if (bounds.height < componentSize.height) { + bounds.height = componentSize.height; + sceneResized = true; + } + if (sceneResized) + resolveBounds (getLocation (), bounds); } - if (sceneResized) - resolveBounds (getLocation (), bounds); - if (! getLocation ().equals (preLocation) || ! bounds.equals (preBounds)) { Rectangle rectangle = convertLocalToScene (getBounds ()); if (repaintRegion == null) @@ -363,7 +380,8 @@ if (repaintRegion != null) { Rectangle r = convertSceneToView (repaintRegion); r.grow (1, 1); - component.repaint (r); + if (component != null) + component.repaint (r); repaintSatellite (); repaintRegion = null; } Index: graph/lib/src/org/netbeans/api/visual/widget/doc-files/documentation.html =================================================================== RCS file: /cvs/graph/lib/src/org/netbeans/api/visual/widget/doc-files/documentation.html,v retrieving revision 1.21 diff -u -r1.21 documentation.html --- graph/lib/src/org/netbeans/api/visual/widget/doc-files/documentation.html 1 Aug 2007 07:45:32 -0000 1.21 +++ graph/lib/src/org/netbeans/api/visual/widget/doc-files/documentation.html 3 Aug 2007 08:00:18 -0000 @@ -521,6 +521,9 @@ validate This method validates whole scene with all widgets. Usually it is called automatically e.g. at the end of event processing. See Validation Process section. +validate(Graphics2D) +This method validates whole scene with all widgets using specified Graphics2D. This is used for off-screen rendering when you do not have a main scene view created yet. Be aware that the scene is going to remain validated with specified font metrics after the method call. This may break scene layout when your main scene view is finally created and shown. See Validation Process section. + getMaximumBounds
setMaximumBounds Controls the maximum bounds of the scene. By default it is [-Integer.MAX_VALUE/2,-Integer.MAX_VALUE/2,Integer.MAX_VALUE,Integer.MAX_VALUE]. This is used to limit the scene bounds e.g. to positive values only. Index: graph/lib/test/unit/src/apichanges/OffscreenRenderingTest.java =================================================================== RCS file: graph/lib/test/unit/src/apichanges/OffscreenRenderingTest.java diff -N graph/lib/test/unit/src/apichanges/OffscreenRenderingTest.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ graph/lib/test/unit/src/apichanges/OffscreenRenderingTest.java 3 Aug 2007 08:00:18 -0000 @@ -0,0 +1,81 @@ +/* + * The contents of this file are subject to the terms of the Common Development + * and Distribution License (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the License at http://www.netbeans.org/cddl.html + * or http://www.netbeans.org/cddl.txt. + * + * When distributing Covered Code, include this CDDL Header Notice in each file + * and include the License file at http://www.netbeans.org/cddl.txt. + * If applicable, add the following below the CDDL Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun + * Microsystems, Inc. All Rights Reserved. + */ + +package apichanges; + +import framework.VisualTestCase; +import org.netbeans.api.visual.border.BorderFactory; +import org.netbeans.api.visual.widget.LabelWidget; +import org.netbeans.api.visual.widget.Scene; +import org.netbeans.api.visual.widget.LayerWidget; + +import java.awt.*; +import java.awt.image.BufferedImage; + +/** + * @author David Kaspar + */ +public class OffscreenRenderingTest extends VisualTestCase { + + public OffscreenRenderingTest (String testName) { + super (testName); + } + + public void testOffscreenRendering () { + Scene scene = new Scene (); + + LayerWidget layer = new LayerWidget (scene); + layer.setPreferredBounds (new Rectangle (0, 0, 80, 80)); + scene.addChild (layer); + + LabelWidget widget = new LabelWidget (scene, "Hi"); + widget.setVerticalAlignment (LabelWidget.VerticalAlignment.CENTER); + widget.setAlignment (LabelWidget.Alignment.CENTER); + widget.setBorder (BorderFactory.createLineBorder ()); + widget.setPreferredLocation (new Point (20, 20)); + widget.setPreferredBounds (new Rectangle (0, 0, 40, 40)); + layer.addChild (widget); + + BufferedImage image = dumpSceneOffscreenRendering (scene); + assertCleaness (testCleaness (image, Color.WHITE, Color.BLACK), image, null); + + assertScene (scene, Color.WHITE, new Rectangle (19, 19, 42, 42)); + } + + private BufferedImage dumpSceneOffscreenRendering (Scene scene) { + // validate the scene with a off-screen graphics + BufferedImage emptyImage = new BufferedImage (1, 1, BufferedImage.TYPE_4BYTE_ABGR); + Graphics2D emptyGraphics = emptyImage.createGraphics (); + scene.validate (emptyGraphics); + emptyGraphics.dispose (); + + // now the scene is calculated using the emptyGraphics, all widgets should be layout and scene has its size resolved + // paint the scene with a off-screen graphics + Rectangle viewBounds = scene.convertSceneToView (scene.getBounds ()); + BufferedImage image = new BufferedImage (viewBounds.width, viewBounds.height, BufferedImage.TYPE_4BYTE_ABGR); + Graphics2D graphics = image.createGraphics (); + double zoomFactor = scene.getZoomFactor (); + graphics.scale (zoomFactor, zoomFactor); + scene.paint (graphics); + graphics.dispose (); + + return image; + } + +} Index: graph/www/documentation.html =================================================================== RCS file: /cvs/graph/www/documentation.html,v retrieving revision 1.97 diff -u -r1.97 documentation.html --- graph/www/documentation.html 19 Jul 2007 07:15:43 -0000 1.97 +++ graph/www/documentation.html 3 Aug 2007 08:00:18 -0000 @@ -175,6 +175,7 @@

  • test.swingborder.SwingBorderTest - how to use borders for Swing
  • test.tool.CtrlKeySwitchToolTest - how to create active-tool switching using ctrl key
  • test.tool.ToolTest - how to use action-tools +
  • test.view.OffscreenRenderingTest - how to off-screen render a scene
  • test.visible.NotifyAddedRemovedTest - test of Widget.notifyAdded and Widget.notifyRemoved methods
  • test.visible.VisibilityTest - compatibility test of Layout implementations with Widget.visible property
  • test.vmd.VMDCollisionTest - test of WidgetCollisionCollector