This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 105390
Collapse All | Expand All

(-)graph/examples/src/test/layout/WeightFlowLayoutTest.java (+70 lines)
Added Link Here
1
/*
2
 * The contents of this file are subject to the terms of the Common Development
3
 * and Distribution License (the License). You may not use this file except in
4
 * compliance with the License.
5
 *
6
 * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7
 * or http://www.netbeans.org/cddl.txt.
8
 *
9
 * When distributing Covered Code, include this CDDL Header Notice in each file
10
 * and include the License file at http://www.netbeans.org/cddl.txt.
11
 * If applicable, add the following below the CDDL Header, with the fields
12
 * enclosed by brackets [] replaced by your own identifying information:
13
 * "Portions Copyrighted [year] [name of copyright owner]"
14
 *
15
 * The Original Software is NetBeans. The Initial Developer of the Original
16
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17
 * Microsystems, Inc. All Rights Reserved.
18
 */
19
20
package test.layout;
21
22
import org.netbeans.api.visual.border.BorderFactory;
23
import org.netbeans.api.visual.layout.LayoutFactory;
24
import org.netbeans.api.visual.widget.LabelWidget;
25
import org.netbeans.api.visual.widget.LayerWidget;
26
import org.netbeans.api.visual.widget.Scene;
27
import org.netbeans.api.visual.widget.Widget;
28
import org.netbeans.api.visual.action.ActionFactory;
29
import test.SceneSupport;
30
31
import java.awt.*;
32
33
/**
34
 * @author David Kaspar
35
 */
36
public class WeightFlowLayoutTest {
37
38
    public static void main (String[] args) {
39
        Scene scene = new Scene ();
40
41
        LayerWidget layer = new LayerWidget (scene);
42
        scene.addChild (layer);
43
44
        Widget widget = new Widget (scene);
45
        widget.setBorder (BorderFactory.createResizeBorder (8, Color.BLACK, false));
46
        widget.setLayout (LayoutFactory.createVerticalFlowLayout (LayoutFactory.SerialAlignment.JUSTIFY, 10));
47
        widget.setPreferredLocation (new Point (50, 50));
48
        widget.setPreferredBounds (new Rectangle (200, 200));
49
        widget.getActions ().addAction (ActionFactory.createResizeAction ());
50
        layer.addChild (widget);
51
52
        createChild (widget, Color.RED, 10);
53
        createChild (widget, Color.GREEN, 20);
54
        createChild (widget, Color.YELLOW, 100).setVisible (false);
55
        createChild (widget, Color.BLUE, 30);
56
        createChild (widget, Color.BLACK, 40);
57
58
        SceneSupport.show (scene);
59
    }
60
61
    private static LabelWidget createChild (Widget parent, Color color, int weight) {
62
        LabelWidget child = new LabelWidget (parent.getScene (), "Weight: " + weight);
63
        child.setOpaque (true);
64
        child.setBackground (color);
65
        child.setForeground (Color.WHITE);
66
        parent.addChild (child, weight);
67
        return child;
68
    }
69
70
}
(-)graph/lib/apichanges.xml (+16 lines)
Lines 168-173 Link Here
168
            <class package="org.netbeans.api.visual.router" name="ConnectionWidgetCollisionsCollector" link="yes"/>
168
            <class package="org.netbeans.api.visual.router" name="ConnectionWidgetCollisionsCollector" link="yes"/>
169
            <issue number="99054"/>
169
            <issue number="99054"/>
170
        </change>
170
        </change>
171
172
        <change>
173
            <api name="general"/>
174
            <summary>VerticalFlowLayout and HorizontalFlowLayout calculates with weights</summary>
175
            <version major="2" minor="4"/>
176
            <date day="1" month="6" year="2007"/>
177
            <author login="dkaspar"/>
178
            <compatibility addition="yes"/>
179
            <description>
180
                When a widget is using VerticalFlowLayout or HorizontalFlowLayout and a child widget has a Number constraint assigned,
181
                then the Number value represent a radio in with the remaining gap in the widget is split and added to particular child widget.
182
		See test.layout.WeightFlowLayoutTest for example.
183
            </description>
184
            <class package="org.netbeans.api.visual.layout" name="LayoutFactory" link="yes"/>
185
            <issue number="105390"/>
186
        </change>
171
    </changes>
187
    </changes>
172
188
173
    <htmlcontents>
189
    <htmlcontents>
(-)graph/lib/arch.xml (+3 lines)
Lines 540-545 Link Here
540
   ReconnectAction must be assigned to ConnectionWidget only.
540
   ReconnectAction must be assigned to ConnectionWidget only.
541
   WidgetCollisionCollector is treats ConnectionWidget specially by their linear path between control points and only for horizontal or vertical segments.
541
   WidgetCollisionCollector is treats ConnectionWidget specially by their linear path between control points and only for horizontal or vertical segments.
542
  </p>
542
  </p>
543
  <p>
544
   VerticalFlowLayout and HorizontalFlowLayout recognizes a Number-class constraint assigned to a child widget of a parent widget where the layout is assigned.
545
  </p>
543
 </answer>
546
 </answer>
544
547
545
548
(-)graph/lib/manifest.mf (-1 / +1 lines)
Lines 1-4 Link Here
1
Manifest-Version: 1.0
1
Manifest-Version: 1.0
2
OpenIDE-Module: org.netbeans.api.visual
2
OpenIDE-Module: org.netbeans.api.visual
3
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/visual/resources/Bundle.properties
3
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/visual/resources/Bundle.properties
4
OpenIDE-Module-Specification-Version: 2.2
4
OpenIDE-Module-Specification-Version: 2.4
(-)graph/lib/src/org/netbeans/api/visual/layout/LayoutFactory.java (+16 lines)
Lines 66-71 Link Here
66
    /**
66
    /**
67
     * Creates a vertical flow layout with default style where widgets are placed vertically one to the bottom from another.
67
     * Creates a vertical flow layout with default style where widgets are placed vertically one to the bottom from another.
68
     * The instance can be shared by multiple widgets.
68
     * The instance can be shared by multiple widgets.
69
     * If child widget constraint is an Number value,
70
     * then its integer value is takes as a weight in which the remaining height of the parent widget is split.
69
     * @return the vertical flow layout
71
     * @return the vertical flow layout
70
     * @deprecated use createVerticalFlowLayout method instead
72
     * @deprecated use createVerticalFlowLayout method instead
71
     */
73
     */
Lines 77-82 Link Here
77
    /**
79
    /**
78
     * Creates a vertical flow layout with a specific style where widgets are placed vertically one to the bottom from another.
80
     * Creates a vertical flow layout with a specific style where widgets are placed vertically one to the bottom from another.
79
     * The instance can be shared by multiple widgets.
81
     * The instance can be shared by multiple widgets.
82
     * If child widget constraint is an Number value,
83
     * then its integer value is takes as a weight in which the remaining height of the parent widget is split.
80
     * @param alignment the alignment
84
     * @param alignment the alignment
81
     * @param gap the gap between widgets
85
     * @param gap the gap between widgets
82
     * @return the vertical flow layout
86
     * @return the vertical flow layout
Lines 90-95 Link Here
90
    /**
94
    /**
91
     * Creates a vertical flow layout with default style where widgets are placed vertically one to the bottom from another.
95
     * Creates a vertical flow layout with default style where widgets are placed vertically one to the bottom from another.
92
     * The instance can be shared by multiple widgets.
96
     * The instance can be shared by multiple widgets.
97
     * If child widget constraint is an Number value,
98
     * then its integer value is takes as a weight in which the remaining height of the parent widget is split.
93
     * @return the vertical flow layout
99
     * @return the vertical flow layout
94
     */
100
     */
95
    public static Layout createVerticalFlowLayout () {
101
    public static Layout createVerticalFlowLayout () {
Lines 99-104 Link Here
99
    /**
105
    /**
100
     * Creates a vertical flow layout with a specific style where widgets are placed vertically one to the bottom from another.
106
     * Creates a vertical flow layout with a specific style where widgets are placed vertically one to the bottom from another.
101
     * The instance can be shared by multiple widgets.
107
     * The instance can be shared by multiple widgets.
108
     * If child widget constraint is an Number value,
109
     * then its integer value is takes as a weight in which the remaining height of the parent widget is split.
102
     * @param alignment the alignment
110
     * @param alignment the alignment
103
     * @param gap the gap between widgets
111
     * @param gap the gap between widgets
104
     * @return the vertical flow layout
112
     * @return the vertical flow layout
Lines 110-115 Link Here
110
    /**
118
    /**
111
     * Creates a horizontal flow layout with default style where widgets are placed horizontally one to the right from another.
119
     * Creates a horizontal flow layout with default style where widgets are placed horizontally one to the right from another.
112
     * The instance can be shared by multiple widgets.
120
     * The instance can be shared by multiple widgets.
121
     * If child widget constraint is an Number value,
122
     * then its integer value is takes as a weight in which the remaining width of the parent widget is split.
113
     * @return the horizontal flow layout
123
     * @return the horizontal flow layout
114
     * @deprecated use createHorizontalFlowLayout method instead
124
     * @deprecated use createHorizontalFlowLayout method instead
115
     */
125
     */
Lines 121-126 Link Here
121
    /**
131
    /**
122
     * Creates a horizontal flow layout with a specific style where widgets are placed horizontally one to the right from another.
132
     * Creates a horizontal flow layout with a specific style where widgets are placed horizontally one to the right from another.
123
     * The instance can be shared by multiple widgets.
133
     * The instance can be shared by multiple widgets.
134
     * If child widget constraint is an Number value,
135
     * then its integer value is takes as a weight in which the remaining width of the parent widget is split.
124
     * @param alignment the alignment
136
     * @param alignment the alignment
125
     * @param gap the gap between widgets
137
     * @param gap the gap between widgets
126
     * @return the horizontal flow layout
138
     * @return the horizontal flow layout
Lines 134-139 Link Here
134
    /**
146
    /**
135
     * Creates a horizontal flow layout with default style where widgets are placed horizontally one to the right from another.
147
     * Creates a horizontal flow layout with default style where widgets are placed horizontally one to the right from another.
136
     * The instance can be shared by multiple widgets.
148
     * The instance can be shared by multiple widgets.
149
     * If child widget constraint is an Number value,
150
     * then its integer value is takes as a weight in which the remaining width of the parent widget is split.
137
     * @return the horizontal flow layout
151
     * @return the horizontal flow layout
138
     */
152
     */
139
    public static Layout createHorizontalFlowLayout () {
153
    public static Layout createHorizontalFlowLayout () {
Lines 143-148 Link Here
143
    /**
157
    /**
144
     * Creates a horizontal flow layout with a specific style where widgets are placed horizontally one to the right from another.
158
     * Creates a horizontal flow layout with a specific style where widgets are placed horizontally one to the right from another.
145
     * The instance can be shared by multiple widgets.
159
     * The instance can be shared by multiple widgets.
160
     * If child widget constraint is an Number value,
161
     * then its integer value is takes as a weight in which the remaining width of the parent widget is split.
146
     * @param alignment the alignment
162
     * @param alignment the alignment
147
     * @param gap the gap between widgets
163
     * @param gap the gap between widgets
148
     * @return the horizontal flow layout
164
     * @return the horizontal flow layout
(-)graph/lib/src/org/netbeans/api/visual/widget/doc-files/documentation.html (+3 lines)
Lines 633-638 Link Here
633
<p>
633
<p>
634
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 <code>childWidget.getPreferredBounds</code> for resolving boundary. The layout will use the widest/highest boundaries for a cell dimension.
634
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 <code>childWidget.getPreferredBounds</code> for resolving boundary. The layout will use the widest/highest boundaries for a cell dimension.
635
635
636
<p>
637
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 <code>test.layout.WeightFlowLayoutTest</code> for example.
638
636
<h3><a name="CardLayout">CardLayout</a></h3>
639
<h3><a name="CardLayout">CardLayout</a></h3>
637
640
638
<p>
641
<p>
(-)graph/lib/src/org/netbeans/modules/visual/layout/FlowLayout.java (-21 / +75 lines)
Lines 23-29 Link Here
23
import org.netbeans.api.visual.layout.LayoutFactory;
23
import org.netbeans.api.visual.layout.LayoutFactory;
24
24
25
import java.awt.*;
25
import java.awt.*;
26
import java.util.Collection;
26
import java.util.*;
27
27
28
/**
28
/**
29
 * @author David Kaspar
29
 * @author David Kaspar
Lines 122-160 Link Here
122
    }
122
    }
123
123
124
    public boolean requiresJustification (Widget widget) {
124
    public boolean requiresJustification (Widget widget) {
125
        return alignment == LayoutFactory.SerialAlignment.JUSTIFY;
125
        return true;
126
    }
126
    }
127
127
128
    public void justify (Widget widget) {
128
    public void justify (Widget widget) {
129
        if (alignment != LayoutFactory.SerialAlignment.JUSTIFY)
129
        Rectangle parentBounds = widget.getClientArea ();
130
            return;
130
        int totalWeight = 0;
131
        int totalGap = 0;
132
        java.util.List<Widget> children = widget.getChildren ();
133
        for (int a = 0; a < children.size (); a ++) {
134
            Widget child = children.get (a);
135
            if (! child.isVisible ())
136
                continue;
137
            totalWeight += resolveWeight (widget, child);
138
139
            if (a > 0)
140
                totalGap -= gap;
141
            if (verticalOrientation) {
142
                totalGap -= child.getBounds ().height;
143
            } else
144
                totalGap -= child.getBounds ().width;
145
        }
146
        totalGap += verticalOrientation ? parentBounds.height : parentBounds.width;
147
        if (totalGap < 0)
148
            totalWeight = totalGap = 0;
149
150
        int gapAdd = 0;
151
        int weightAdd = 0;
131
        for (Widget child : widget.getChildren ()) {
152
        for (Widget child : widget.getChildren ()) {
132
            Rectangle bounds = widget.getClientArea ();
153
            if (! child.isVisible ())
154
                continue;
133
            Point location = child.getLocation ();
155
            Point location = child.getLocation ();
134
            Rectangle childBounds = child.getBounds ();
156
            Rectangle childBounds = child.getBounds ();
135
157
136
            if (verticalOrientation) {
158
            if (verticalOrientation) {
137
                int parentX1 = bounds.x;
159
                if (alignment == LayoutFactory.SerialAlignment.JUSTIFY) {
138
                int parentX2 = parentX1 + bounds.width;
160
                    int parentX1 = parentBounds.x;
139
                int childX1 = location.x + childBounds.x;
161
                    int parentX2 = parentX1 + parentBounds.width;
140
                int childX2 = childX1 + childBounds.width;
162
                    int childX1 = location.x + childBounds.x;
141
163
                    int childX2 = childX1 + childBounds.width;
142
                childBounds.x = Math.min (parentX1, childX1);
164
143
                childBounds.width = Math.max (parentX2, childX2) - childBounds.x;
165
                    childBounds.x = Math.min (parentX1, childX1);
144
                childBounds.x -= location.x;
166
                    childBounds.width = Math.max (parentX2, childX2) - childBounds.x;
167
                    childBounds.x -= location.x;
168
                }
169
170
                if (totalWeight > 0) {
171
                    location.y += gapAdd;
172
                    int weight = resolveWeight (widget, child);
173
                    int gap = (weightAdd + weight) * totalGap / totalWeight - gapAdd;
174
                    childBounds.height += gap;
175
                    gapAdd += gap;
176
                    weightAdd += weight;
177
                }
145
            } else {
178
            } else {
146
                int parentY1 = bounds.y;
179
                if (alignment == LayoutFactory.SerialAlignment.JUSTIFY) {
147
                int parentY2 = parentY1 + bounds.height;
180
                    int parentY1 = parentBounds.y;
148
                int childY1 = location.y + childBounds.y;
181
                    int parentY2 = parentY1 + parentBounds.height;
149
                int childY2 = childY1 + childBounds.height;
182
                    int childY1 = location.y + childBounds.y;
150
183
                    int childY2 = childY1 + childBounds.height;
151
                childBounds.y = Math.min (parentY1, childY1);
184
152
                childBounds.height = Math.max (parentY2, childY2) - childBounds.y;
185
                    childBounds.y = Math.min (parentY1, childY1);
153
                childBounds.y -= location.y;
186
                    childBounds.height = Math.max (parentY2, childY2) - childBounds.y;
187
                    childBounds.y -= location.y;
188
                }
189
190
                if (totalWeight > 0) {
191
                    location.x += gapAdd;
192
                    int weight = resolveWeight (widget, child);
193
                    int gap = (weightAdd + weight) * totalGap / totalWeight;
194
                    childBounds.width += gap;
195
                    gapAdd += gap;
196
                    weightAdd += weight;
197
                }
154
            }
198
            }
155
199
156
            child.resolveBounds (location, childBounds);
200
            child.resolveBounds (location, childBounds);
157
        }
201
        }
202
    }
203
204
    private static int resolveWeight (Widget widget, Widget child) {
205
        Object o = widget.getChildConstraint (child);
206
        if (o instanceof Number) {
207
            int weight = ((Number) o).intValue ();
208
            if (weight > 0)
209
                return weight;
210
        }
211
        return 0;
158
    }
212
    }
159
213
160
}
214
}

Return to bug 105390