Index: graph/examples/src/test/layout/WeightFlowLayoutTest.java =================================================================== RCS file: graph/examples/src/test/layout/WeightFlowLayoutTest.java diff -N graph/examples/src/test/layout/WeightFlowLayoutTest.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ graph/examples/src/test/layout/WeightFlowLayoutTest.java 1 Jun 2007 14:33:51 -0000 @@ -0,0 +1,70 @@ +/* + * 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-2006 Sun + * Microsystems, Inc. All Rights Reserved. + */ + +package test.layout; + +import org.netbeans.api.visual.border.BorderFactory; +import org.netbeans.api.visual.layout.LayoutFactory; +import org.netbeans.api.visual.widget.LabelWidget; +import org.netbeans.api.visual.widget.LayerWidget; +import org.netbeans.api.visual.widget.Scene; +import org.netbeans.api.visual.widget.Widget; +import org.netbeans.api.visual.action.ActionFactory; +import test.SceneSupport; + +import java.awt.*; + +/** + * @author David Kaspar + */ +public class WeightFlowLayoutTest { + + public static void main (String[] args) { + Scene scene = new Scene (); + + LayerWidget layer = new LayerWidget (scene); + scene.addChild (layer); + + Widget widget = new Widget (scene); + widget.setBorder (BorderFactory.createResizeBorder (8, Color.BLACK, false)); + widget.setLayout (LayoutFactory.createVerticalFlowLayout (LayoutFactory.SerialAlignment.JUSTIFY, 10)); + widget.setPreferredLocation (new Point (50, 50)); + widget.setPreferredBounds (new Rectangle (200, 200)); + widget.getActions ().addAction (ActionFactory.createResizeAction ()); + layer.addChild (widget); + + createChild (widget, Color.RED, 10); + createChild (widget, Color.GREEN, 20); + createChild (widget, Color.YELLOW, 100).setVisible (false); + createChild (widget, Color.BLUE, 30); + createChild (widget, Color.BLACK, 40); + + SceneSupport.show (scene); + } + + private static LabelWidget createChild (Widget parent, Color color, int weight) { + LabelWidget child = new LabelWidget (parent.getScene (), "Weight: " + weight); + child.setOpaque (true); + child.setBackground (color); + child.setForeground (Color.WHITE); + parent.addChild (child, weight); + return child; + } + +} Index: graph/lib/apichanges.xml =================================================================== RCS file: /cvs/graph/lib/apichanges.xml,v retrieving revision 1.10 diff -u -r1.10 apichanges.xml --- graph/lib/apichanges.xml 25 May 2007 21:20:27 -0000 1.10 +++ graph/lib/apichanges.xml 1 Jun 2007 14:33:52 -0000 @@ -168,6 +168,22 @@ + + + + VerticalFlowLayout and HorizontalFlowLayout calculates with weights + + + + + + When a widget is using VerticalFlowLayout or HorizontalFlowLayout and a child widget has a Number constraint assigned, + then the Number value represent a radio in with the remaining gap in the widget is split and added to particular child widget. + See test.layout.WeightFlowLayoutTest for example. + + + + Index: graph/lib/arch.xml =================================================================== RCS file: /cvs/graph/lib/arch.xml,v retrieving revision 1.8 diff -u -r1.8 arch.xml --- graph/lib/arch.xml 27 Mar 2007 08:02:56 -0000 1.8 +++ graph/lib/arch.xml 1 Jun 2007 14:33:52 -0000 @@ -540,6 +540,9 @@ ReconnectAction must be assigned to ConnectionWidget only. WidgetCollisionCollector is treats ConnectionWidget specially by their linear path between control points and only for horizontal or vertical segments.

+

+ VerticalFlowLayout and HorizontalFlowLayout recognizes a Number-class constraint assigned to a child widget of a parent widget where the layout is assigned. +

Index: graph/lib/manifest.mf =================================================================== RCS file: /cvs/graph/lib/manifest.mf,v retrieving revision 1.10 diff -u -r1.10 manifest.mf --- graph/lib/manifest.mf 25 May 2007 21:20:27 -0000 1.10 +++ graph/lib/manifest.mf 1 Jun 2007 14:33:52 -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.2 +OpenIDE-Module-Specification-Version: 2.4 Index: graph/lib/src/org/netbeans/api/visual/layout/LayoutFactory.java =================================================================== RCS file: /cvs/graph/lib/src/org/netbeans/api/visual/layout/LayoutFactory.java,v retrieving revision 1.14 diff -u -r1.14 LayoutFactory.java --- graph/lib/src/org/netbeans/api/visual/layout/LayoutFactory.java 10 Mar 2007 14:58:42 -0000 1.14 +++ graph/lib/src/org/netbeans/api/visual/layout/LayoutFactory.java 1 Jun 2007 14:33:52 -0000 @@ -66,6 +66,8 @@ /** * Creates a vertical flow layout with default style where widgets are placed vertically one to the bottom from another. * The instance can be shared by multiple widgets. + * If child widget constraint is an Number value, + * then its integer value is takes as a weight in which the remaining height of the parent widget is split. * @return the vertical flow layout * @deprecated use createVerticalFlowLayout method instead */ @@ -77,6 +79,8 @@ /** * Creates a vertical flow layout with a specific style where widgets are placed vertically one to the bottom from another. * The instance can be shared by multiple widgets. + * If child widget constraint is an Number value, + * then its integer value is takes as a weight in which the remaining height of the parent widget is split. * @param alignment the alignment * @param gap the gap between widgets * @return the vertical flow layout @@ -90,6 +94,8 @@ /** * Creates a vertical flow layout with default style where widgets are placed vertically one to the bottom from another. * The instance can be shared by multiple widgets. + * If child widget constraint is an Number value, + * then its integer value is takes as a weight in which the remaining height of the parent widget is split. * @return the vertical flow layout */ public static Layout createVerticalFlowLayout () { @@ -99,6 +105,8 @@ /** * Creates a vertical flow layout with a specific style where widgets are placed vertically one to the bottom from another. * The instance can be shared by multiple widgets. + * If child widget constraint is an Number value, + * then its integer value is takes as a weight in which the remaining height of the parent widget is split. * @param alignment the alignment * @param gap the gap between widgets * @return the vertical flow layout @@ -110,6 +118,8 @@ /** * Creates a horizontal flow layout with default style where widgets are placed horizontally one to the right from another. * The instance can be shared by multiple widgets. + * If child widget constraint is an Number value, + * then its integer value is takes as a weight in which the remaining width of the parent widget is split. * @return the horizontal flow layout * @deprecated use createHorizontalFlowLayout method instead */ @@ -121,6 +131,8 @@ /** * Creates a horizontal flow layout with a specific style where widgets are placed horizontally one to the right from another. * The instance can be shared by multiple widgets. + * If child widget constraint is an Number value, + * then its integer value is takes as a weight in which the remaining width of the parent widget is split. * @param alignment the alignment * @param gap the gap between widgets * @return the horizontal flow layout @@ -134,6 +146,8 @@ /** * Creates a horizontal flow layout with default style where widgets are placed horizontally one to the right from another. * The instance can be shared by multiple widgets. + * If child widget constraint is an Number value, + * then its integer value is takes as a weight in which the remaining width of the parent widget is split. * @return the horizontal flow layout */ public static Layout createHorizontalFlowLayout () { @@ -143,6 +157,8 @@ /** * Creates a horizontal flow layout with a specific style where widgets are placed horizontally one to the right from another. * The instance can be shared by multiple widgets. + * If child widget constraint is an Number value, + * then its integer value is takes as a weight in which the remaining width of the parent widget is split. * @param alignment the alignment * @param gap the gap between widgets * @return the horizontal flow layout 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.11 diff -u -r1.11 documentation.html --- graph/lib/src/org/netbeans/api/visual/widget/doc-files/documentation.html 31 May 2007 08:12:47 -0000 1.11 +++ graph/lib/src/org/netbeans/api/visual/widget/doc-files/documentation.html 1 Jun 2007 14:33:52 -0000 @@ -633,6 +633,9 @@

This layout places children serially in vertical or horizontal line - one widget after another. It allows top-left, center, bottom-right and justify alignments and specifying gaps between children. It used childWidget.getPreferredBounds for resolving boundary. The layout will use the widest/highest boundaries for a cell dimension. +

+The layout allows to work with Number-class constraints. The Number constraint has to be a positive number assigned to a child widget. Then it represents a ratio in with the remaining space (height for VerticalFlowLayout and width for HorizontalFlowLayout) is split and assigned to a particular widget. See test.layout.WeightFlowLayoutTest for example. +

CardLayout

Index: graph/lib/src/org/netbeans/modules/visual/layout/FlowLayout.java =================================================================== RCS file: /cvs/graph/lib/src/org/netbeans/modules/visual/layout/FlowLayout.java,v retrieving revision 1.2 diff -u -r1.2 FlowLayout.java --- graph/lib/src/org/netbeans/modules/visual/layout/FlowLayout.java 1 Jun 2007 13:58:29 -0000 1.2 +++ graph/lib/src/org/netbeans/modules/visual/layout/FlowLayout.java 1 Jun 2007 14:33:52 -0000 @@ -23,7 +23,7 @@ import org.netbeans.api.visual.layout.LayoutFactory; import java.awt.*; -import java.util.Collection; +import java.util.*; /** * @author David Kaspar @@ -122,39 +122,93 @@ } public boolean requiresJustification (Widget widget) { - return alignment == LayoutFactory.SerialAlignment.JUSTIFY; + return true; } public void justify (Widget widget) { - if (alignment != LayoutFactory.SerialAlignment.JUSTIFY) - return; + Rectangle parentBounds = widget.getClientArea (); + int totalWeight = 0; + int totalGap = 0; + java.util.List children = widget.getChildren (); + for (int a = 0; a < children.size (); a ++) { + Widget child = children.get (a); + if (! child.isVisible ()) + continue; + totalWeight += resolveWeight (widget, child); + + if (a > 0) + totalGap -= gap; + if (verticalOrientation) { + totalGap -= child.getBounds ().height; + } else + totalGap -= child.getBounds ().width; + } + totalGap += verticalOrientation ? parentBounds.height : parentBounds.width; + if (totalGap < 0) + totalWeight = totalGap = 0; + + int gapAdd = 0; + int weightAdd = 0; for (Widget child : widget.getChildren ()) { - Rectangle bounds = widget.getClientArea (); + if (! child.isVisible ()) + continue; Point location = child.getLocation (); Rectangle childBounds = child.getBounds (); if (verticalOrientation) { - int parentX1 = bounds.x; - int parentX2 = parentX1 + bounds.width; - int childX1 = location.x + childBounds.x; - int childX2 = childX1 + childBounds.width; - - childBounds.x = Math.min (parentX1, childX1); - childBounds.width = Math.max (parentX2, childX2) - childBounds.x; - childBounds.x -= location.x; + if (alignment == LayoutFactory.SerialAlignment.JUSTIFY) { + int parentX1 = parentBounds.x; + int parentX2 = parentX1 + parentBounds.width; + int childX1 = location.x + childBounds.x; + int childX2 = childX1 + childBounds.width; + + childBounds.x = Math.min (parentX1, childX1); + childBounds.width = Math.max (parentX2, childX2) - childBounds.x; + childBounds.x -= location.x; + } + + if (totalWeight > 0) { + location.y += gapAdd; + int weight = resolveWeight (widget, child); + int gap = (weightAdd + weight) * totalGap / totalWeight - gapAdd; + childBounds.height += gap; + gapAdd += gap; + weightAdd += weight; + } } else { - int parentY1 = bounds.y; - int parentY2 = parentY1 + bounds.height; - int childY1 = location.y + childBounds.y; - int childY2 = childY1 + childBounds.height; - - childBounds.y = Math.min (parentY1, childY1); - childBounds.height = Math.max (parentY2, childY2) - childBounds.y; - childBounds.y -= location.y; + if (alignment == LayoutFactory.SerialAlignment.JUSTIFY) { + int parentY1 = parentBounds.y; + int parentY2 = parentY1 + parentBounds.height; + int childY1 = location.y + childBounds.y; + int childY2 = childY1 + childBounds.height; + + childBounds.y = Math.min (parentY1, childY1); + childBounds.height = Math.max (parentY2, childY2) - childBounds.y; + childBounds.y -= location.y; + } + + if (totalWeight > 0) { + location.x += gapAdd; + int weight = resolveWeight (widget, child); + int gap = (weightAdd + weight) * totalGap / totalWeight; + childBounds.width += gap; + gapAdd += gap; + weightAdd += weight; + } } child.resolveBounds (location, childBounds); } + } + + private static int resolveWeight (Widget widget, Widget child) { + Object o = widget.getChildConstraint (child); + if (o instanceof Number) { + int weight = ((Number) o).intValue (); + if (weight > 0) + return weight; + } + return 0; } }