1 /* GridBagLayout - Layout manager for components according to GridBagConstraints
2 Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
41 import java
.io
.Serializable
;
42 import java
.util
.ArrayList
;
43 import java
.util
.HashMap
;
44 import java
.util
.Hashtable
;
47 * @author Michael Koch (konqueror@gmx.de)
48 * @author Jeroen Frijters (jeroen@frijters.net)
50 public class GridBagLayout
51 implements Serializable
, LayoutManager2
53 private static final long serialVersionUID
= 8838754796412211005L;
55 protected static final int MINSIZE
= 1;
56 protected static final int PREFERREDSIZE
= 2;
57 protected static final int MAXGRIDSIZE
= 512;
59 // comptable remembers the original contraints given to us.
60 // internalcomptable is used to keep track of modified constraint values
61 // that we calculate, particularly when we are given RELATIVE and
62 // REMAINDER constraints.
63 // Constraints kept in comptable are never modified, and constraints
64 // kept in internalcomptable can be modified internally only.
65 protected Hashtable comptable
;
66 private Hashtable internalcomptable
;
67 protected GridBagLayoutInfo layoutInfo
;
68 protected GridBagConstraints defaultConstraints
;
70 public double[] columnWeights
;
71 public int[] columnWidths
;
72 public double[] rowWeights
;
73 public int[] rowHeights
;
75 public GridBagLayout ()
77 this.comptable
= new Hashtable();
78 this.internalcomptable
= new Hashtable();
79 this.defaultConstraints
= new GridBagConstraints();
83 * Helper method to calc the sum of a range of elements in an int array.
85 private int sumIntArray (int[] array
, int upto
)
89 for (int i
= 0; i
< upto
; i
++)
96 * Helper method to calc the sum of all elements in an int array.
98 private int sumIntArray (int[] array
)
100 return sumIntArray(array
, array
.length
);
104 * Helper method to calc the sum of all elements in an double array.
106 private double sumDoubleArray (double[] array
)
110 for (int i
= 0; i
< array
.length
; i
++)
116 public void addLayoutComponent (String name
, Component component
)
121 public void removeLayoutComponent (Component component
)
126 public void addLayoutComponent (Component component
, Object constraints
)
128 if (constraints
== null)
131 if (!(constraints
instanceof GridBagConstraints
))
132 throw new IllegalArgumentException();
134 setConstraints (component
, (GridBagConstraints
) constraints
);
137 public Dimension
preferredLayoutSize (Container parent
)
140 return new Dimension (0, 0);
142 GridBagLayoutInfo li
= getLayoutInfo (parent
, PREFERREDSIZE
);
143 return getMinSize (parent
, li
);
146 public Dimension
minimumLayoutSize (Container parent
)
149 return new Dimension (0, 0);
151 GridBagLayoutInfo li
= getLayoutInfo (parent
, MINSIZE
);
152 return getMinSize (parent
, li
);
155 public Dimension
maximumLayoutSize (Container target
)
157 return new Dimension (Integer
.MAX_VALUE
, Integer
.MAX_VALUE
);
160 public void layoutContainer (Container parent
)
162 arrangeGrid (parent
);
165 public float getLayoutAlignmentX (Container target
)
167 return Component
.CENTER_ALIGNMENT
;
170 public float getLayoutAlignmentY (Container target
)
172 return Component
.CENTER_ALIGNMENT
;
175 public void invalidateLayout (Container target
)
177 this.layoutInfo
= null;
180 public void setConstraints (Component component
,
181 GridBagConstraints constraints
)
183 GridBagConstraints clone
= (GridBagConstraints
) constraints
.clone();
186 clone
.gridx
= GridBagConstraints
.RELATIVE
;
189 clone
.gridy
= GridBagConstraints
.RELATIVE
;
191 if (clone
.gridwidth
== 0)
192 clone
.gridwidth
= GridBagConstraints
.REMAINDER
;
193 else if (clone
.gridwidth
< 0
194 && clone
.gridwidth
!= GridBagConstraints
.REMAINDER
195 && clone
.gridwidth
!= GridBagConstraints
.RELATIVE
)
198 if (clone
.gridheight
== 0)
199 clone
.gridheight
= GridBagConstraints
.REMAINDER
;
200 else if (clone
.gridheight
< 0
201 && clone
.gridheight
!= GridBagConstraints
.REMAINDER
202 && clone
.gridheight
!= GridBagConstraints
.RELATIVE
)
203 clone
.gridheight
= 1;
205 comptable
.put (component
, clone
);
208 public GridBagConstraints
getConstraints (Component component
)
210 return (GridBagConstraints
) (lookupConstraints (component
).clone());
213 protected GridBagConstraints
lookupConstraints (Component component
)
215 GridBagConstraints result
= (GridBagConstraints
) comptable
.get (component
);
219 setConstraints (component
, defaultConstraints
);
220 result
= (GridBagConstraints
) comptable
.get (component
);
226 private GridBagConstraints
lookupInternalConstraints (Component component
)
228 GridBagConstraints result
=
229 (GridBagConstraints
) internalcomptable
.get (component
);
233 result
= (GridBagConstraints
) lookupConstraints(component
).clone();
234 internalcomptable
.put (component
, result
);
243 public Point
getLayoutOrigin ()
245 if (layoutInfo
== null)
246 return new Point (0, 0);
248 return new Point (layoutInfo
.pos_x
, layoutInfo
.pos_y
);
254 public int[][] getLayoutDimensions ()
256 int[][] result
= new int [2][];
257 if (layoutInfo
== null)
259 result
[0] = new int[0];
260 result
[1] = new int[0];
265 result
[0] = new int [layoutInfo
.cols
];
266 System
.arraycopy (layoutInfo
.colWidths
, 0, result
[0], 0, layoutInfo
.cols
);
267 result
[1] = new int [layoutInfo
.rows
];
268 System
.arraycopy (layoutInfo
.rowHeights
, 0, result
[1], 0, layoutInfo
.rows
);
272 public double[][] getLayoutWeights ()
274 double[][] result
= new double [2][];
275 if (layoutInfo
== null)
277 result
[0] = new double[0];
278 result
[1] = new double[0];
283 result
[0] = new double [layoutInfo
.cols
];
284 System
.arraycopy (layoutInfo
.colWeights
, 0, result
[0], 0, layoutInfo
.cols
);
285 result
[1] = new double [layoutInfo
.rows
];
286 System
.arraycopy (layoutInfo
.rowWeights
, 0, result
[1], 0, layoutInfo
.rows
);
293 public Point
location (int x
, int y
)
295 if (layoutInfo
== null)
296 return new Point (0, 0);
300 int pixel_x
= layoutInfo
.pos_x
;
301 int pixel_y
= layoutInfo
.pos_y
;
303 for (col
= 0; col
< layoutInfo
.cols
; col
++)
305 int w
= layoutInfo
.colWidths
[col
];
312 for (row
= 0; row
< layoutInfo
.rows
; row
++)
314 int h
= layoutInfo
.rowHeights
[row
];
321 return new Point (col
, row
);
327 protected void AdjustForGravity (GridBagConstraints gbc
, Rectangle rect
)
330 throw new Error ("Not implemented");
336 protected void ArrangeGrid (Container parent
)
338 Component
[] components
= parent
.getComponents();
340 if (components
.length
== 0)
343 GridBagLayoutInfo info
= getLayoutInfo (parent
, PREFERREDSIZE
);
344 if (info
.cols
== 0 && info
.rows
== 0)
349 //dumpLayoutInfo (layoutInfo);
351 for(int i
= 0; i
< components
.length
; i
++)
353 Component component
= components
[i
];
355 // If component is not visible we dont have to care about it.
356 if (!component
.isVisible())
359 GridBagConstraints constraints
=
360 lookupInternalConstraints(component
);
362 int cellx
= sumIntArray(layoutInfo
.colWidths
, constraints
.gridx
);
363 int celly
= sumIntArray(layoutInfo
.rowHeights
, constraints
.gridy
);
364 int cellw
= sumIntArray(layoutInfo
.colWidths
,
365 constraints
.gridx
+ constraints
.gridwidth
) - cellx
;
366 int cellh
= sumIntArray(layoutInfo
.rowHeights
,
367 constraints
.gridy
+ constraints
.gridheight
) - celly
;
369 Insets insets
= constraints
.insets
;
372 cellx
+= insets
.left
;
374 cellw
-= insets
.left
+ insets
.right
;
375 cellh
-= insets
.top
+ insets
.bottom
;
378 Dimension dim
= component
.getPreferredSize();
380 // Note: Documentation says that padding is added on both sides, but
381 // visual inspection shows that the Sun implementation only adds it
382 // once, so we do the same.
383 dim
.width
+= constraints
.ipadx
;
384 dim
.height
+= constraints
.ipady
;
386 switch(constraints
.fill
)
388 case GridBagConstraints
.HORIZONTAL
:
391 case GridBagConstraints
.VERTICAL
:
394 case GridBagConstraints
.BOTH
:
403 switch(constraints
.anchor
)
405 case GridBagConstraints
.NORTH
:
406 x
= cellx
+ (cellw
- dim
.width
) / 2;
409 case GridBagConstraints
.SOUTH
:
410 x
= cellx
+ (cellw
- dim
.width
) / 2;
411 y
= celly
+ cellh
- dim
.height
;
413 case GridBagConstraints
.WEST
:
415 y
= celly
+ (cellh
- dim
.height
) / 2;
417 case GridBagConstraints
.EAST
:
418 x
= cellx
+ cellw
- dim
.width
;
419 y
= celly
+ (cellh
- dim
.height
) / 2;
421 case GridBagConstraints
.NORTHEAST
:
422 x
= cellx
+ cellw
- dim
.width
;
425 case GridBagConstraints
.NORTHWEST
:
429 case GridBagConstraints
.SOUTHEAST
:
430 x
= cellx
+ cellw
- dim
.width
;
431 y
= celly
+ cellh
- dim
.height
;
433 case GridBagConstraints
.SOUTHWEST
:
435 y
= celly
+ cellh
- dim
.height
;
438 x
= cellx
+ (cellw
- dim
.width
) / 2;
439 y
= celly
+ (cellh
- dim
.height
) / 2;
443 component
.setBounds(layoutInfo
.pos_x
+ x
, layoutInfo
.pos_y
+ y
, dim
.width
, dim
.height
);
447 //dumpLayoutInfo (layoutInfo);
453 protected GridBagLayoutInfo
GetLayoutInfo (Container parent
, int sizeflag
)
455 if (sizeflag
!= MINSIZE
&& sizeflag
!= PREFERREDSIZE
)
456 throw new IllegalArgumentException();
458 Dimension parentDim
= parent
.getSize ();
459 Insets parentInsets
= parent
.getInsets ();
460 parentDim
.width
-= parentInsets
.left
+ parentInsets
.right
;
461 parentDim
.height
-= parentInsets
.top
+ parentInsets
.bottom
;
467 // Guaranteed to contain the last component added to the given row
468 // or column, whose gridwidth/height is not REMAINDER.
469 HashMap lastInRow
= new HashMap();
470 HashMap lastInCol
= new HashMap();
472 Component
[] components
= parent
.getComponents();
474 // Components sorted by gridwidths/heights,
475 // smallest to largest, with REMAINDER and RELATIVE at the end.
476 // These are useful when determining sizes and weights.
477 ArrayList sortedByWidth
= new ArrayList(components
.length
);
478 ArrayList sortedByHeight
= new ArrayList(components
.length
);
480 // STEP 1: first we figure out how many rows/columns
481 for (int i
= 0; i
< components
.length
; i
++)
483 Component component
= components
[i
];
485 // If component is not visible we dont have to care about it.
486 if (!component
.isVisible())
489 // When looking up the constraint for the first time, check the
490 // original unmodified constraint. After the first time, always
491 // refer to the internal modified constraint.
492 GridBagConstraints originalConstraints
= lookupConstraints (component
);
493 GridBagConstraints constraints
= (GridBagConstraints
) originalConstraints
.clone();
494 internalcomptable
.put(component
, constraints
);
498 // 1. gridy == RELATIVE, gridx == RELATIVE
500 // use y as the row number; check for the next
501 // available slot at row y
503 // 2. only gridx == RELATIVE
505 // check for the next available slot at row gridy
507 // 3. only gridy == RELATIVE
509 // check for the next available slot at column gridx
511 // 4. neither gridx or gridy == RELATIVE
513 // nothing to check; just add it
517 if(constraints
.gridx
== GridBagConstraints
.RELATIVE
)
519 if (constraints
.gridy
== GridBagConstraints
.RELATIVE
)
520 constraints
.gridy
= current_y
;
524 // Check the component that occupies the right-most spot in this
525 // row. We want to add this component after it.
526 // If this row is empty, add to the 0 position.
527 if (!lastInRow
.containsKey(new Integer(constraints
.gridy
)))
531 Component lastComponent
= (Component
) lastInRow
.get(new Integer(constraints
.gridy
));
532 GridBagConstraints lastConstraints
= lookupInternalConstraints(lastComponent
);
533 x
= lastConstraints
.gridx
+ Math
.max(1, lastConstraints
.gridwidth
);
536 // Determine if this component will fit in the slot vertically.
537 // If not, bump it over to where it does fit.
538 for (int y
= constraints
.gridy
+ 1; y
< constraints
.gridy
+ Math
.max(1, constraints
.gridheight
); y
++)
540 if (lastInRow
.containsKey(new Integer(y
)))
542 Component lastComponent
= (Component
) lastInRow
.get(new Integer(y
));
543 GridBagConstraints lastConstraints
= lookupInternalConstraints(lastComponent
);
545 lastConstraints
.gridx
+ Math
.max(1, lastConstraints
.gridwidth
));
549 constraints
.gridx
= x
;
552 else if(constraints
.gridy
== GridBagConstraints
.RELATIVE
)
555 // Check the component that occupies the bottom-most spot in
556 // this column. We want to add this component below it.
557 // If this column is empty, add to the 0 position.
558 if (!lastInCol
.containsKey(new Integer(constraints
.gridx
)))
562 Component lastComponent
= (Component
)lastInCol
.get(new Integer(constraints
.gridx
));
563 GridBagConstraints lastConstraints
= lookupInternalConstraints(lastComponent
);
564 y
= lastConstraints
.gridy
+ Math
.max(1, lastConstraints
.gridheight
);
567 // Determine if this component will fit in the slot horizontally.
568 // If not, bump it down to where it does fit.
569 for (int x
= constraints
.gridx
+ 1; x
< constraints
.gridx
+ Math
.max(1, constraints
.gridwidth
); x
++)
571 if (lastInCol
.containsKey(new Integer(x
)))
573 Component lastComponent
= (Component
) lastInCol
.get(new Integer(x
));
574 GridBagConstraints lastConstraints
= lookupInternalConstraints(lastComponent
);
576 lastConstraints
.gridy
+ Math
.max(1, lastConstraints
.gridheight
));
580 constraints
.gridy
= y
;
582 // case 4: do nothing
584 max_x
= Math
.max(max_x
,
585 constraints
.gridx
+ Math
.max(1, constraints
.gridwidth
));
586 max_y
= Math
.max(max_y
,
587 constraints
.gridy
+ Math
.max(1, constraints
.gridheight
));
589 sortBySpan(component
, constraints
.gridwidth
, sortedByWidth
, true);
590 sortBySpan(component
, constraints
.gridheight
, sortedByHeight
, false);
592 // Update our reference points for RELATIVE gridx and gridy.
593 if(constraints
.gridwidth
== GridBagConstraints
.REMAINDER
)
595 current_y
= constraints
.gridy
+ Math
.max(1, constraints
.gridheight
);
597 else if (constraints
.gridwidth
!= GridBagConstraints
.REMAINDER
)
599 for (int y
= constraints
.gridy
; y
< constraints
.gridy
+ Math
.max(1, constraints
.gridheight
); y
++)
601 if(lastInRow
.containsKey(new Integer(y
)))
603 Component lastComponent
= (Component
) lastInRow
.get(new Integer(y
));
604 GridBagConstraints lastConstraints
= lookupInternalConstraints(lastComponent
);
605 if (constraints
.gridx
> lastConstraints
.gridx
)
607 lastInRow
.put(new Integer(y
), component
);
612 lastInRow
.put(new Integer(y
), component
);
616 for (int x
= constraints
.gridx
; x
< constraints
.gridx
+ Math
.max(1, constraints
.gridwidth
); x
++)
618 if(lastInCol
.containsKey(new Integer(x
)))
620 Component lastComponent
= (Component
) lastInCol
.get(new Integer(x
));
621 GridBagConstraints lastConstraints
= lookupInternalConstraints(lastComponent
);
622 if (constraints
.gridy
> lastConstraints
.gridy
)
624 lastInCol
.put(new Integer(x
), component
);
629 lastInCol
.put(new Integer(x
), component
);
635 GridBagLayoutInfo info
= new GridBagLayoutInfo(max_x
, max_y
);
637 // Check if column widths and row heights are overridden.
639 for (int x
= 0; x
< max_x
; x
++)
641 if(columnWidths
!= null && columnWidths
.length
> x
)
642 info
.colWidths
[x
] = columnWidths
[x
];
643 if(columnWeights
!= null && columnWeights
.length
> x
)
644 info
.colWeights
[x
] = columnWeights
[x
];
647 for (int y
= 0; y
< max_y
; y
++)
649 if(rowHeights
!= null && rowHeights
.length
> y
)
650 info
.rowHeights
[y
] = rowHeights
[y
];
651 if(rowWeights
!= null && rowWeights
.length
> y
)
652 info
.rowWeights
[y
] = rowWeights
[y
];
655 // STEP 2: Fix up any cells with width/height as REMAINDER/RELATIVE.
656 for (int i
= 0; i
< components
.length
; i
++)
658 Component component
= components
[i
];
660 // If component is not visible we dont have to care about it.
661 if (!component
.isVisible())
664 GridBagConstraints constraints
= lookupInternalConstraints (component
);
666 if(constraints
.gridwidth
== GridBagConstraints
.REMAINDER
|| constraints
.gridwidth
== GridBagConstraints
.RELATIVE
)
668 if(constraints
.gridwidth
== GridBagConstraints
.REMAINDER
)
670 for (int y
= constraints
.gridy
; y
< constraints
.gridy
+ Math
.max(1, constraints
.gridheight
); y
++)
672 if (lastInRow
.containsKey(new Integer(y
)))
674 Component lastComponent
= (Component
) lastInRow
.get(new Integer(y
));
675 GridBagConstraints lastConstraints
= lookupInternalConstraints(lastComponent
);
677 if (lastConstraints
.gridwidth
== GridBagConstraints
.RELATIVE
)
679 constraints
.gridx
= max_x
- 1;
684 constraints
.gridx
= Math
.max (constraints
.gridx
,
685 lastConstraints
.gridx
+ Math
.max (1, lastConstraints
.gridwidth
));
689 constraints
.gridwidth
= max_x
- constraints
.gridx
;
691 else if (constraints
.gridwidth
== GridBagConstraints
.RELATIVE
)
693 constraints
.gridwidth
= max_x
- constraints
.gridx
- 1;
697 sortedByWidth
.remove(sortedByWidth
.indexOf(component
));
698 sortBySpan(component
, constraints
.gridwidth
, sortedByWidth
, true);
701 if(constraints
.gridheight
== GridBagConstraints
.REMAINDER
|| constraints
.gridheight
== GridBagConstraints
.RELATIVE
)
703 if(constraints
.gridheight
== GridBagConstraints
.REMAINDER
)
705 for (int x
= constraints
.gridx
; x
< constraints
.gridx
+ Math
.max(1, constraints
.gridwidth
); x
++)
707 if (lastInCol
.containsKey(new Integer(x
)))
709 Component lastComponent
= (Component
) lastInRow
.get(new Integer(x
));
710 GridBagConstraints lastConstraints
= lookupInternalConstraints(lastComponent
);
712 if (lastConstraints
.gridheight
== GridBagConstraints
.RELATIVE
)
714 constraints
.gridy
= max_y
- 1;
719 constraints
.gridy
= Math
.max (constraints
.gridy
,
720 lastConstraints
.gridy
+ Math
.max (1, lastConstraints
.gridheight
));
724 constraints
.gridheight
= max_y
- constraints
.gridy
;
726 else if (constraints
.gridheight
== GridBagConstraints
.RELATIVE
)
728 constraints
.gridheight
= max_y
- constraints
.gridy
- 1;
732 sortedByHeight
.remove(sortedByHeight
.indexOf(component
));
733 sortBySpan(component
, constraints
.gridheight
, sortedByHeight
, false);
737 // STEP 3: Determine sizes and weights for columns.
738 for (int i
= 0; i
< sortedByWidth
.size(); i
++)
740 Component component
= (Component
) sortedByWidth
.get(i
);
742 // If component is not visible we dont have to care about it.
743 if (!component
.isVisible())
746 GridBagConstraints constraints
= lookupInternalConstraints (component
);
748 int width
= (sizeflag
== PREFERREDSIZE
) ?
749 component
.getPreferredSize().width
:
750 component
.getMinimumSize().width
;
752 if(constraints
.insets
!= null)
753 width
+= constraints
.insets
.left
+ constraints
.insets
.right
;
755 width
+= constraints
.ipadx
;
757 distributeSizeAndWeight(width
,
760 constraints
.gridwidth
,
765 // STEP 4: Determine sizes and weights for rows.
766 for (int i
= 0; i
< sortedByHeight
.size(); i
++)
768 Component component
= (Component
) sortedByHeight
.get(i
);
770 // If component is not visible we dont have to care about it.
771 if (!component
.isVisible())
774 GridBagConstraints constraints
= lookupInternalConstraints (component
);
776 int height
= (sizeflag
== PREFERREDSIZE
) ?
777 component
.getPreferredSize().height
:
778 component
.getMinimumSize().height
;
780 if(constraints
.insets
!= null)
781 height
+= constraints
.insets
.top
+ constraints
.insets
.bottom
;
783 height
+= constraints
.ipady
;
785 distributeSizeAndWeight(height
,
788 constraints
.gridheight
,
793 // Adjust cell sizes iff parent size not zero.
794 if (parentDim
.width
> 0 && parentDim
.height
> 0)
796 calcCellSizes (info
.colWidths
, info
.colWeights
, parentDim
.width
);
797 calcCellSizes (info
.rowHeights
, info
.rowWeights
, parentDim
.height
);
800 int totalWidth
= sumIntArray(info
.colWidths
);
801 int totalHeight
= sumIntArray(info
.rowHeights
);
803 // Make sure pos_x and pos_y are never negative.
804 if (totalWidth
>= parentDim
.width
)
805 info
.pos_x
= parentInsets
.left
;
807 info
.pos_x
= parentInsets
.left
+ (parentDim
.width
- totalWidth
) / 2;
809 if (totalHeight
>= parentDim
.height
)
810 info
.pos_y
= parentInsets
.top
;
812 info
.pos_y
= parentInsets
.top
+ (parentDim
.height
- totalHeight
) / 2;
815 //dumpLayoutInfo (info);
823 protected Dimension
GetMinSize (Container parent
, GridBagLayoutInfo info
)
825 if (parent
== null || info
== null)
826 return new Dimension (0, 0);
828 Insets insets
= parent
.getInsets();
829 int width
= sumIntArray (info
.colWidths
) + insets
.left
+ insets
.right
;
830 int height
= sumIntArray (info
.rowHeights
) + insets
.top
+ insets
.bottom
;
831 return new Dimension (width
, height
);
837 protected Dimension
getMinSize (Container parent
, GridBagLayoutInfo info
)
839 return GetMinSize (parent
, info
);
843 * Helper method used by GetLayoutInfo to keep components sorted, either
844 * by gridwidth or gridheight.
846 * @param component Component to add to the sorted list.
847 * @param span Either the component's gridwidth or gridheight.
848 * @param list <code>ArrayList</code> of components, sorted by
850 * @param sortByWidth Flag indicating sorting index. If true, sort by
851 * width. Otherwise, sort by height.
852 * FIXME: Use a better sorting algorithm.
854 private void sortBySpan (Component component
, int span
, ArrayList list
, boolean sortByWidth
)
856 if (span
== GridBagConstraints
.REMAINDER
857 || span
== GridBagConstraints
.RELATIVE
)
859 // Put all RELATIVE and REMAINDER components at the end.
867 GridBagConstraints gbc
= lookupInternalConstraints((Component
) list
.get(i
));
868 int otherspan
= sortByWidth ?
871 while (otherspan
!= GridBagConstraints
.REMAINDER
872 && otherspan
!= GridBagConstraints
.RELATIVE
873 && span
>= otherspan
)
878 gbc
= lookupInternalConstraints((Component
) list
.get(i
));
879 otherspan
= sortByWidth ?
887 list
.add(i
, component
);
892 * Helper method used by GetLayoutInfo to distribute a component's size
895 * @param size Preferred size of component, with inset and padding
897 * @param weight Weight of component.
898 * @param start Starting position of component. Either
899 * constraints.gridx or gridy.
900 * @param span Span of component. either contraints.gridwidth or
902 * @param sizes Sizes of rows or columns.
903 * @param weights Weights of rows or columns.
905 private void distributeSizeAndWeight (int size
, double weight
,
907 int[] sizes
, double[] weights
)
911 sizes
[start
] = Math
.max(sizes
[start
], size
);
912 weights
[start
] = Math
.max(weights
[start
], weight
);
916 int numOccupied
= span
;
917 int lastOccupied
= -1;
919 for(int i
= start
; i
< start
+ span
; i
++)
930 // A component needs to occupy at least one row.
932 sizes
[start
+ span
- 1] = size
;
934 sizes
[lastOccupied
] += size
;
936 calcCellWeights(weight
, weights
, start
, span
);
941 * Helper method used by GetLayoutInfo to calculate weight distribution.
942 * @param weight Weight of component.
943 * @param weights Weights of rows/columns.
944 * @param start Starting position of component in grid (gridx/gridy).
945 * @param span Span of component (gridwidth/gridheight).
947 private void calcCellWeights (double weight
, double[] weights
, int start
, int span
)
949 double totalWeight
= 0.0;
950 for(int k
= start
; k
< start
+ span
; k
++)
951 totalWeight
+= weights
[k
];
953 if(weight
> totalWeight
)
955 if (totalWeight
== 0.0)
957 weights
[start
+ span
- 1] += weight
;
961 double diff
= weight
- totalWeight
;
962 double remaining
= diff
;
964 for(int k
= start
; k
< start
+ span
; k
++)
966 double extraWeight
= diff
* weights
[k
] / totalWeight
;
967 weights
[k
] += extraWeight
;
968 remaining
-= extraWeight
;
971 if (remaining
> 0.0 && weights
[start
+ span
- 1] != 0.0)
973 weights
[start
+ span
- 1] += remaining
;
980 * Helper method used by GetLayoutInfo to distribute extra space
981 * based on weight distribution.
983 * @param sizes Sizes of rows/columns.
984 * @param weights Weights of rows/columns.
985 * @param range Dimension of container.
987 private void calcCellSizes (int[] sizes
, double[] weights
, int range
)
989 int totalSize
= sumIntArray (sizes
);
990 double totalWeight
= sumDoubleArray (weights
);
992 int diff
= range
- totalSize
;
997 for (int i
= 0; i
< sizes
.length
; i
++)
999 int newsize
= (int) (sizes
[i
] + (((double) diff
) * weights
[i
] / totalWeight
));
1006 private void dumpLayoutInfo (GridBagLayoutInfo info
)
1008 System
.out
.println ("GridBagLayoutInfo:");
1009 System
.out
.println ("cols: " + info
.cols
+ ", rows: " + info
.rows
);
1010 System
.out
.print ("colWidths: ");
1011 dumpArray(info
.colWidths
);
1012 System
.out
.print ("rowHeights: ");
1013 dumpArray(info
.rowHeights
);
1014 System
.out
.print ("colWeights: ");
1015 dumpArray(info
.colWeights
);
1016 System
.out
.print ("rowWeights: ");
1017 dumpArray(info
.rowWeights
);
1020 private void dumpArray(int[] array
)
1023 for(int i
= 0; i
< array
.length
; i
++)
1025 System
.out
.print(sep
);
1026 System
.out
.print(array
[i
]);
1029 System
.out
.println();
1032 private void dumpArray(double[] array
)
1035 for(int i
= 0; i
< array
.length
; i
++)
1037 System
.out
.print(sep
);
1038 System
.out
.print(array
[i
]);
1041 System
.out
.println();
1047 protected void arrangeGrid (Container parent
)
1049 ArrangeGrid (parent
);
1055 protected GridBagLayoutInfo
getLayoutInfo (Container parent
, int sizeflag
)
1057 return GetLayoutInfo (parent
, sizeflag
);
1063 protected void adjustForGravity (GridBagConstraints gbc
, Rectangle rect
)
1065 AdjustForGravity (gbc
, rect
);