History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/javax/swing/BoxLayout.java (1 of 18352 files). Show all

Unified · Split

java/pkg/javax/swing/BoxLayout.java+538−0
@@ -0,0 +1,538 @@
1+/*
2+ * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+
27+package javax.swing;
28+
29+import java.awt.*;
30+import java.beans.ConstructorProperties;
31+import java.io.Serializable;
32+import java.io.PrintStream;
33+
34+/**
35+ * A layout manager that allows multiple components to be laid out either
36+ * vertically or horizontally. The components will not wrap so, for
37+ * example, a vertical arrangement of components will stay vertically
38+ * arranged when the frame is resized.
39+ * <TABLE ALIGN="RIGHT" BORDER="0" SUMMARY="layout">
40+ * <TR>
41+ * <TD ALIGN="CENTER">
42+ * <P ALIGN="CENTER"><IMG SRC="doc-files/BoxLayout-1.gif"
43+ * alt="The following text describes this graphic."
44+ * WIDTH="191" HEIGHT="201" ALIGN="BOTTOM" BORDER="0">
45+ * </TD>
46+ * </TR>
47+ * </TABLE>
48+ * <p>
49+ * Nesting multiple panels with different combinations of horizontal and
50+ * vertical gives an effect similar to GridBagLayout, without the
51+ * complexity. The diagram shows two panels arranged horizontally, each
52+ * of which contains 3 components arranged vertically.
53+ *
54+ * <p> The BoxLayout manager is constructed with an axis parameter that
55+ * specifies the type of layout that will be done. There are four choices:
56+ *
57+ * <blockquote><b><tt>X_AXIS</tt></b> - Components are laid out horizontally
58+ * from left to right.</blockquote>
59+ *
60+ * <blockquote><b><tt>Y_AXIS</tt></b> - Components are laid out vertically
61+ * from top to bottom.</blockquote>
62+ *
63+ * <blockquote><b><tt>LINE_AXIS</tt></b> - Components are laid out the way
64+ * words are laid out in a line, based on the container's
65+ * <tt>ComponentOrientation</tt> property. If the container's
66+ * <tt>ComponentOrientation</tt> is horizontal then components are laid out
67+ * horizontally, otherwise they are laid out vertically. For horizontal
68+ * orientations, if the container's <tt>ComponentOrientation</tt> is left to
69+ * right then components are laid out left to right, otherwise they are laid
70+ * out right to left. For vertical orientations components are always laid out
71+ * from top to bottom.</blockquote>
72+ *
73+ * <blockquote><b><tt>PAGE_AXIS</tt></b> - Components are laid out the way
74+ * text lines are laid out on a page, based on the container's
75+ * <tt>ComponentOrientation</tt> property. If the container's
76+ * <tt>ComponentOrientation</tt> is horizontal then components are laid out
77+ * vertically, otherwise they are laid out horizontally. For horizontal
78+ * orientations, if the container's <tt>ComponentOrientation</tt> is left to
79+ * right then components are laid out left to right, otherwise they are laid
80+ * out right to left.&nbsp; For vertical orientations components are always
81+ * laid out from top to bottom.</blockquote>
82+ * <p>
83+ * For all directions, components are arranged in the same order as they were
84+ * added to the container.
85+ * <p>
86+ * BoxLayout attempts to arrange components
87+ * at their preferred widths (for horizontal layout)
88+ * or heights (for vertical layout).
89+ * For a horizontal layout,
90+ * if not all the components are the same height,
91+ * BoxLayout attempts to make all the components
92+ * as high as the highest component.
93+ * If that's not possible for a particular component,
94+ * then BoxLayout aligns that component vertically,
95+ * according to the component's Y alignment.
96+ * By default, a component has a Y alignment of 0.5,
97+ * which means that the vertical center of the component
98+ * should have the same Y coordinate as
99+ * the vertical centers of other components with 0.5 Y alignment.
100+ * <p>
101+ * Similarly, for a vertical layout,
102+ * BoxLayout attempts to make all components in the column
103+ * as wide as the widest component.
104+ * If that fails, it aligns them horizontally
105+ * according to their X alignments. For <code>PAGE_AXIS</code> layout,
106+ * horizontal alignment is done based on the leading edge of the component.
107+ * In other words, an X alignment value of 0.0 means the left edge of a
108+ * component if the container's <code>ComponentOrientation</code> is left to
109+ * right and it means the right edge of the component otherwise.
110+ * <p>
111+ * Instead of using BoxLayout directly, many programs use the Box class.
112+ * The Box class is a lightweight container that uses a BoxLayout.
113+ * It also provides handy methods to help you use BoxLayout well.
114+ * Adding components to multiple nested boxes is a powerful way to get
115+ * the arrangement you want.
116+ * <p>
117+ * For further information and examples see
118+ * <a
119+ href="http://java.sun.com/docs/books/tutorial/uiswing/layout/box.html">How to Use BoxLayout</a>,
120+ * a section in <em>The Java Tutorial.</em>
121+ * <p>
122+ * <strong>Warning:</strong>
123+ * Serialized objects of this class will not be compatible with
124+ * future Swing releases. The current serialization support is
125+ * appropriate for short term storage or RMI between applications running
126+ * the same version of Swing. As of 1.4, support for long term storage
127+ * of all JavaBeans<sup><font size="-2">TM</font></sup>
128+ * has been added to the <code>java.beans</code> package.
129+ * Please see {@link java.beans.XMLEncoder}.
130+ *
131+ * @see Box
132+ * @see java.awt.ComponentOrientation
133+ * @see JComponent#getAlignmentX
134+ * @see JComponent#getAlignmentY
135+ *
136+ * @author Timothy Prinzing
137+ */
138+public class BoxLayout implements LayoutManager2, Serializable {
139+
140+ /**
141+ * Specifies that components should be laid out left to right.
142+ */
143+ public static final int X_AXIS = 0;
144+
145+ /**
146+ * Specifies that components should be laid out top to bottom.
147+ */
148+ public static final int Y_AXIS = 1;
149+
150+ /**
151+ * Specifies that components should be laid out in the direction of
152+ * a line of text as determined by the target container's
153+ * <code>ComponentOrientation</code> property.
154+ */
155+ public static final int LINE_AXIS = 2;
156+
157+ /**
158+ * Specifies that components should be laid out in the direction that
159+ * lines flow across a page as determined by the target container's
160+ * <code>ComponentOrientation</code> property.
161+ */
162+ public static final int PAGE_AXIS = 3;
163+
164+ /**
165+ * Creates a layout manager that will lay out components along the
166+ * given axis.
167+ *
168+ * @param target the container that needs to be laid out
169+ * @param axis the axis to lay out components along. Can be one of:
170+ * <code>BoxLayout.X_AXIS</code>,
171+ * <code>BoxLayout.Y_AXIS</code>,
172+ * <code>BoxLayout.LINE_AXIS</code> or
173+ * <code>BoxLayout.PAGE_AXIS</code>
174+ *
175+ * @exception AWTError if the value of <code>axis</code> is invalid
176+ */
177+ @ConstructorProperties({"target", "axis"})
178+ public BoxLayout(Container target, int axis) {
179+ if (axis != X_AXIS && axis != Y_AXIS &&
180+ axis != LINE_AXIS && axis != PAGE_AXIS) {
181+ throw new AWTError("Invalid axis");
182+ }
183+ this.axis = axis;
184+ this.target = target;
185+ }
186+
187+ /**
188+ * Constructs a BoxLayout that
189+ * produces debugging messages.
190+ *
191+ * @param target the container that needs to be laid out
192+ * @param axis the axis to lay out components along. Can be one of:
193+ * <code>BoxLayout.X_AXIS</code>,
194+ * <code>BoxLayout.Y_AXIS</code>,
195+ * <code>BoxLayout.LINE_AXIS</code> or
196+ * <code>BoxLayout.PAGE_AXIS</code>
197+ *
198+ * @param dbg the stream to which debugging messages should be sent,
199+ * null if none
200+ */
201+ BoxLayout(Container target, int axis, PrintStream dbg) {
202+ this(target, axis);
203+ this.dbg = dbg;
204+ }
205+
206+ /**
207+ * Returns the container that uses this layout manager.
208+ *
209+ * @return the container that uses this layout manager
210+ *
211+ * @since 1.6
212+ */
213+ public final Container getTarget() {
214+ return this.target;
215+ }
216+
217+ /**
218+ * Returns the axis that was used to lay out components.
219+ * Returns one of:
220+ * <code>BoxLayout.X_AXIS</code>,
221+ * <code>BoxLayout.Y_AXIS</code>,
222+ * <code>BoxLayout.LINE_AXIS</code> or
223+ * <code>BoxLayout.PAGE_AXIS</code>
224+ *
225+ * @return the axis that was used to lay out components
226+ *
227+ * @since 1.6
228+ */
229+ public final int getAxis() {
230+ return this.axis;
231+ }
232+
233+ /**
234+ * Indicates that a child has changed its layout related information,
235+ * and thus any cached calculations should be flushed.
236+ * <p>
237+ * This method is called by AWT when the invalidate method is called
238+ * on the Container. Since the invalidate method may be called
239+ * asynchronously to the event thread, this method may be called
240+ * asynchronously.
241+ *
242+ * @param target the affected container
243+ *
244+ * @exception AWTError if the target isn't the container specified to the
245+ * BoxLayout constructor
246+ */
247+ public synchronized void invalidateLayout(Container target) {
248+ checkContainer(target);
249+ xChildren = null;
250+ yChildren = null;
251+ xTotal = null;
252+ yTotal = null;
253+ }
254+
255+ /**
256+ * Not used by this class.
257+ *
258+ * @param name the name of the component
259+ * @param comp the component
260+ */
261+ public void addLayoutComponent(String name, Component comp) {
262+ invalidateLayout(comp.getParent());
263+ }
264+
265+ /**
266+ * Not used by this class.
267+ *
268+ * @param comp the component
269+ */
270+ public void removeLayoutComponent(Component comp) {
271+ invalidateLayout(comp.getParent());
272+ }
273+
274+ /**
275+ * Not used by this class.
276+ *
277+ * @param comp the component
278+ * @param constraints constraints
279+ */
280+ public void addLayoutComponent(Component comp, Object constraints) {
281+ invalidateLayout(comp.getParent());
282+ }
283+
284+ /**
285+ * Returns the preferred dimensions for this layout, given the components
286+ * in the specified target container.
287+ *
288+ * @param target the container that needs to be laid out
289+ * @return the dimensions >= 0 && <= Integer.MAX_VALUE
290+ * @exception AWTError if the target isn't the container specified to the
291+ * BoxLayout constructor
292+ * @see Container
293+ * @see #minimumLayoutSize
294+ * @see #maximumLayoutSize
295+ */
296+ public Dimension preferredLayoutSize(Container target) {
297+ Dimension size;
298+ synchronized(this) {
299+ checkContainer(target);
300+ checkRequests();
301+ size = new Dimension(xTotal.preferred, yTotal.preferred);
302+ }
303+
304+ Insets insets = target.getInsets();
305+ size.width = (int) Math.min((long) size.width + (long) insets.left + (long) insets.right, Integer.MAX_VALUE);
306+ size.height = (int) Math.min((long) size.height + (long) insets.top + (long) insets.bottom, Integer.MAX_VALUE);
307+ return size;
308+ }
309+
310+ /**
311+ * Returns the minimum dimensions needed to lay out the components
312+ * contained in the specified target container.
313+ *
314+ * @param target the container that needs to be laid out
315+ * @return the dimensions >= 0 && <= Integer.MAX_VALUE
316+ * @exception AWTError if the target isn't the container specified to the
317+ * BoxLayout constructor
318+ * @see #preferredLayoutSize
319+ * @see #maximumLayoutSize
320+ */
321+ public Dimension minimumLayoutSize(Container target) {
322+ Dimension size;
323+ synchronized(this) {
324+ checkContainer(target);
325+ checkRequests();
326+ size = new Dimension(xTotal.minimum, yTotal.minimum);
327+ }
328+
329+ Insets insets = target.getInsets();
330+ size.width = (int) Math.min((long) size.width + (long) insets.left + (long) insets.right, Integer.MAX_VALUE);
331+ size.height = (int) Math.min((long) size.height + (long) insets.top + (long) insets.bottom, Integer.MAX_VALUE);
332+ return size;
333+ }
334+
335+ /**
336+ * Returns the maximum dimensions the target container can use
337+ * to lay out the components it contains.
338+ *
339+ * @param target the container that needs to be laid out
340+ * @return the dimenions >= 0 && <= Integer.MAX_VALUE
341+ * @exception AWTError if the target isn't the container specified to the
342+ * BoxLayout constructor
343+ * @see #preferredLayoutSize
344+ * @see #minimumLayoutSize
345+ */
346+ public Dimension maximumLayoutSize(Container target) {
347+ Dimension size;
348+ synchronized(this) {
349+ checkContainer(target);
350+ checkRequests();
351+ size = new Dimension(xTotal.maximum, yTotal.maximum);
352+ }
353+
354+ Insets insets = target.getInsets();
355+ size.width = (int) Math.min((long) size.width + (long) insets.left + (long) insets.right, Integer.MAX_VALUE);
356+ size.height = (int) Math.min((long) size.height + (long) insets.top + (long) insets.bottom, Integer.MAX_VALUE);
357+ return size;
358+ }
359+
360+ /**
361+ * Returns the alignment along the X axis for the container.
362+ * If the box is horizontal, the default
363+ * alignment will be returned. Otherwise, the alignment needed
364+ * to place the children along the X axis will be returned.
365+ *
366+ * @param target the container
367+ * @return the alignment >= 0.0f && <= 1.0f
368+ * @exception AWTError if the target isn't the container specified to the
369+ * BoxLayout constructor
370+ */
371+ public synchronized float getLayoutAlignmentX(Container target) {
372+ checkContainer(target);
373+ checkRequests();
374+ return xTotal.alignment;
375+ }
376+
377+ /**
378+ * Returns the alignment along the Y axis for the container.
379+ * If the box is vertical, the default
380+ * alignment will be returned. Otherwise, the alignment needed
381+ * to place the children along the Y axis will be returned.
382+ *
383+ * @param target the container
384+ * @return the alignment >= 0.0f && <= 1.0f
385+ * @exception AWTError if the target isn't the container specified to the
386+ * BoxLayout constructor
387+ */
388+ public synchronized float getLayoutAlignmentY(Container target) {
389+ checkContainer(target);
390+ checkRequests();
391+ return yTotal.alignment;
392+ }
393+
394+ /**
395+ * Called by the AWT <!-- XXX CHECK! --> when the specified container
396+ * needs to be laid out.
397+ *
398+ * @param target the container to lay out
399+ *
400+ * @exception AWTError if the target isn't the container specified to the
401+ * BoxLayout constructor
402+ */
403+ public void layoutContainer(Container target) {
404+ checkContainer(target);
405+ int nChildren = target.getComponentCount();
406+ int[] xOffsets = new int[nChildren];
407+ int[] xSpans = new int[nChildren];
408+ int[] yOffsets = new int[nChildren];
409+ int[] ySpans = new int[nChildren];
410+
411+ Dimension alloc = target.getSize();
412+ Insets in = target.getInsets();
413+ alloc.width -= in.left + in.right;
414+ alloc.height -= in.top + in.bottom;
415+
416+ // Resolve axis to an absolute value (either X_AXIS or Y_AXIS)
417+ ComponentOrientation o = target.getComponentOrientation();
418+ int absoluteAxis = resolveAxis( axis, o );
419+ boolean ltr = (absoluteAxis != axis) ? o.isLeftToRight() : true;
420+
421+
422+ // determine the child placements
423+ synchronized(this) {
424+ checkRequests();
425+
426+ if (absoluteAxis == X_AXIS) {
427+ SizeRequirements.calculateTiledPositions(alloc.width, xTotal,
428+ xChildren, xOffsets,
429+ xSpans, ltr);
430+ SizeRequirements.calculateAlignedPositions(alloc.height, yTotal,
431+ yChildren, yOffsets,
432+ ySpans);
433+ } else {
434+ SizeRequirements.calculateAlignedPositions(alloc.width, xTotal,
435+ xChildren, xOffsets,
436+ xSpans, ltr);
437+ SizeRequirements.calculateTiledPositions(alloc.height, yTotal,
438+ yChildren, yOffsets,
439+ ySpans);
440+ }
441+ }
442+
443+ // flush changes to the container
444+ for (int i = 0; i < nChildren; i++) {
445+ Component c = target.getComponent(i);
446+ c.setBounds((int) Math.min((long) in.left + (long) xOffsets[i], Integer.MAX_VALUE),
447+ (int) Math.min((long) in.top + (long) yOffsets[i], Integer.MAX_VALUE),
448+ xSpans[i], ySpans[i]);
449+
450+ }
451+ if (dbg != null) {
452+ for (int i = 0; i < nChildren; i++) {
453+ Component c = target.getComponent(i);
454+ dbg.println(c.toString());
455+ dbg.println("X: " + xChildren[i]);
456+ dbg.println("Y: " + yChildren[i]);
457+ }
458+ }
459+
460+ }
461+
462+ void checkContainer(Container target) {
463+ if (this.target != target) {
464+ throw new AWTError("BoxLayout can't be shared");
465+ }
466+ }
467+
468+ void checkRequests() {
469+ if (xChildren == null || yChildren == null) {
470+ // The requests have been invalidated... recalculate
471+ // the request information.
472+ int n = target.getComponentCount();
473+ xChildren = new SizeRequirements[n];
474+ yChildren = new SizeRequirements[n];
475+ for (int i = 0; i < n; i++) {
476+ Component c = target.getComponent(i);
477+ if (!c.isVisible()) {
478+ xChildren[i] = new SizeRequirements(0,0,0, c.getAlignmentX());
479+ yChildren[i] = new SizeRequirements(0,0,0, c.getAlignmentY());
480+ continue;
481+ }
482+ Dimension min = c.getMinimumSize();
483+ Dimension typ = c.getPreferredSize();
484+ Dimension max = c.getMaximumSize();
485+ xChildren[i] = new SizeRequirements(min.width, typ.width,
486+ max.width,
487+ c.getAlignmentX());
488+ yChildren[i] = new SizeRequirements(min.height, typ.height,
489+ max.height,
490+ c.getAlignmentY());
491+ }
492+
493+ // Resolve axis to an absolute value (either X_AXIS or Y_AXIS)
494+ int absoluteAxis = resolveAxis(axis,target.getComponentOrientation());
495+
496+ if (absoluteAxis == X_AXIS) {
497+ xTotal = SizeRequirements.getTiledSizeRequirements(xChildren);
498+ yTotal = SizeRequirements.getAlignedSizeRequirements(yChildren);
499+ } else {
500+ xTotal = SizeRequirements.getAlignedSizeRequirements(xChildren);
501+ yTotal = SizeRequirements.getTiledSizeRequirements(yChildren);
502+ }
503+ }
504+ }
505+
506+ /**
507+ * Given one of the 4 axis values, resolve it to an absolute axis.
508+ * The relative axis values, PAGE_AXIS and LINE_AXIS are converted
509+ * to their absolute couterpart given the target's ComponentOrientation
510+ * value. The absolute axes, X_AXIS and Y_AXIS are returned unmodified.
511+ *
512+ * @param axis the axis to resolve
513+ * @param o the ComponentOrientation to resolve against
514+ * @return the resolved axis
515+ */
516+ private int resolveAxis( int axis, ComponentOrientation o ) {
517+ int absoluteAxis;
518+ if( axis == LINE_AXIS ) {
519+ absoluteAxis = o.isHorizontal() ? X_AXIS : Y_AXIS;
520+ } else if( axis == PAGE_AXIS ) {
521+ absoluteAxis = o.isHorizontal() ? Y_AXIS : X_AXIS;
522+ } else {
523+ absoluteAxis = axis;
524+ }
525+ return absoluteAxis;
526+ }
527+
528+
529+ private int axis;
530+ private Container target;
531+
532+ private transient SizeRequirements[] xChildren;
533+ private transient SizeRequirements[] yChildren;
534+ private transient SizeRequirements xTotal;
535+ private transient SizeRequirements yTotal;
536+
537+ private transient PrintStream dbg;
538+}