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