Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/java/awt/CardLayout.java
38829 views
1
/*
2
* Copyright (c) 1995, 2013, 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
package java.awt;
27
28
import java.util.Hashtable;
29
import java.util.Vector;
30
import java.util.Enumeration;
31
32
import java.io.Serializable;
33
import java.io.ObjectInputStream;
34
import java.io.ObjectOutputStream;
35
import java.io.ObjectStreamField;
36
import java.io.IOException;
37
38
/**
39
* A <code>CardLayout</code> object is a layout manager for a
40
* container. It treats each component in the container as a card.
41
* Only one card is visible at a time, and the container acts as
42
* a stack of cards. The first component added to a
43
* <code>CardLayout</code> object is the visible component when the
44
* container is first displayed.
45
* <p>
46
* The ordering of cards is determined by the container's own internal
47
* ordering of its component objects. <code>CardLayout</code>
48
* defines a set of methods that allow an application to flip
49
* through these cards sequentially, or to show a specified card.
50
* The {@link CardLayout#addLayoutComponent}
51
* method can be used to associate a string identifier with a given card
52
* for fast random access.
53
*
54
* @author Arthur van Hoff
55
* @see java.awt.Container
56
* @since JDK1.0
57
*/
58
59
public class CardLayout implements LayoutManager2,
60
Serializable {
61
62
private static final long serialVersionUID = -4328196481005934313L;
63
64
/*
65
* This creates a Vector to store associated
66
* pairs of components and their names.
67
* @see java.util.Vector
68
*/
69
Vector<Card> vector = new Vector<>();
70
71
/*
72
* A pair of Component and String that represents its name.
73
*/
74
class Card implements Serializable {
75
static final long serialVersionUID = 6640330810709497518L;
76
public String name;
77
public Component comp;
78
public Card(String cardName, Component cardComponent) {
79
name = cardName;
80
comp = cardComponent;
81
}
82
}
83
84
/*
85
* Index of Component currently displayed by CardLayout.
86
*/
87
int currentCard = 0;
88
89
90
/*
91
* A cards horizontal Layout gap (inset). It specifies
92
* the space between the left and right edges of a
93
* container and the current component.
94
* This should be a non negative Integer.
95
* @see getHgap()
96
* @see setHgap()
97
*/
98
int hgap;
99
100
/*
101
* A cards vertical Layout gap (inset). It specifies
102
* the space between the top and bottom edges of a
103
* container and the current component.
104
* This should be a non negative Integer.
105
* @see getVgap()
106
* @see setVgap()
107
*/
108
int vgap;
109
110
/**
111
* @serialField tab Hashtable
112
* deprectated, for forward compatibility only
113
* @serialField hgap int
114
* @serialField vgap int
115
* @serialField vector Vector
116
* @serialField currentCard int
117
*/
118
private static final ObjectStreamField[] serialPersistentFields = {
119
new ObjectStreamField("tab", Hashtable.class),
120
new ObjectStreamField("hgap", Integer.TYPE),
121
new ObjectStreamField("vgap", Integer.TYPE),
122
new ObjectStreamField("vector", Vector.class),
123
new ObjectStreamField("currentCard", Integer.TYPE)
124
};
125
126
/**
127
* Creates a new card layout with gaps of size zero.
128
*/
129
public CardLayout() {
130
this(0, 0);
131
}
132
133
/**
134
* Creates a new card layout with the specified horizontal and
135
* vertical gaps. The horizontal gaps are placed at the left and
136
* right edges. The vertical gaps are placed at the top and bottom
137
* edges.
138
* @param hgap the horizontal gap.
139
* @param vgap the vertical gap.
140
*/
141
public CardLayout(int hgap, int vgap) {
142
this.hgap = hgap;
143
this.vgap = vgap;
144
}
145
146
/**
147
* Gets the horizontal gap between components.
148
* @return the horizontal gap between components.
149
* @see java.awt.CardLayout#setHgap(int)
150
* @see java.awt.CardLayout#getVgap()
151
* @since JDK1.1
152
*/
153
public int getHgap() {
154
return hgap;
155
}
156
157
/**
158
* Sets the horizontal gap between components.
159
* @param hgap the horizontal gap between components.
160
* @see java.awt.CardLayout#getHgap()
161
* @see java.awt.CardLayout#setVgap(int)
162
* @since JDK1.1
163
*/
164
public void setHgap(int hgap) {
165
this.hgap = hgap;
166
}
167
168
/**
169
* Gets the vertical gap between components.
170
* @return the vertical gap between components.
171
* @see java.awt.CardLayout#setVgap(int)
172
* @see java.awt.CardLayout#getHgap()
173
*/
174
public int getVgap() {
175
return vgap;
176
}
177
178
/**
179
* Sets the vertical gap between components.
180
* @param vgap the vertical gap between components.
181
* @see java.awt.CardLayout#getVgap()
182
* @see java.awt.CardLayout#setHgap(int)
183
* @since JDK1.1
184
*/
185
public void setVgap(int vgap) {
186
this.vgap = vgap;
187
}
188
189
/**
190
* Adds the specified component to this card layout's internal
191
* table of names. The object specified by <code>constraints</code>
192
* must be a string. The card layout stores this string as a key-value
193
* pair that can be used for random access to a particular card.
194
* By calling the <code>show</code> method, an application can
195
* display the component with the specified name.
196
* @param comp the component to be added.
197
* @param constraints a tag that identifies a particular
198
* card in the layout.
199
* @see java.awt.CardLayout#show(java.awt.Container, java.lang.String)
200
* @exception IllegalArgumentException if the constraint is not a string.
201
*/
202
public void addLayoutComponent(Component comp, Object constraints) {
203
synchronized (comp.getTreeLock()) {
204
if (constraints == null){
205
constraints = "";
206
}
207
if (constraints instanceof String) {
208
addLayoutComponent((String)constraints, comp);
209
} else {
210
throw new IllegalArgumentException("cannot add to layout: constraint must be a string");
211
}
212
}
213
}
214
215
/**
216
* @deprecated replaced by
217
* <code>addLayoutComponent(Component, Object)</code>.
218
*/
219
@Deprecated
220
public void addLayoutComponent(String name, Component comp) {
221
synchronized (comp.getTreeLock()) {
222
if (!vector.isEmpty()) {
223
comp.setVisible(false);
224
}
225
for (int i=0; i < vector.size(); i++) {
226
if (((Card)vector.get(i)).name.equals(name)) {
227
((Card)vector.get(i)).comp = comp;
228
return;
229
}
230
}
231
vector.add(new Card(name, comp));
232
}
233
}
234
235
/**
236
* Removes the specified component from the layout.
237
* If the card was visible on top, the next card underneath it is shown.
238
* @param comp the component to be removed.
239
* @see java.awt.Container#remove(java.awt.Component)
240
* @see java.awt.Container#removeAll()
241
*/
242
public void removeLayoutComponent(Component comp) {
243
synchronized (comp.getTreeLock()) {
244
for (int i = 0; i < vector.size(); i++) {
245
if (((Card)vector.get(i)).comp == comp) {
246
// if we remove current component we should show next one
247
if (comp.isVisible() && (comp.getParent() != null)) {
248
next(comp.getParent());
249
}
250
251
vector.remove(i);
252
253
// correct currentCard if this is necessary
254
if (currentCard > i) {
255
currentCard--;
256
}
257
break;
258
}
259
}
260
}
261
}
262
263
/**
264
* Determines the preferred size of the container argument using
265
* this card layout.
266
* @param parent the parent container in which to do the layout
267
* @return the preferred dimensions to lay out the subcomponents
268
* of the specified container
269
* @see java.awt.Container#getPreferredSize
270
* @see java.awt.CardLayout#minimumLayoutSize
271
*/
272
public Dimension preferredLayoutSize(Container parent) {
273
synchronized (parent.getTreeLock()) {
274
Insets insets = parent.getInsets();
275
int ncomponents = parent.getComponentCount();
276
int w = 0;
277
int h = 0;
278
279
for (int i = 0 ; i < ncomponents ; i++) {
280
Component comp = parent.getComponent(i);
281
Dimension d = comp.getPreferredSize();
282
if (d.width > w) {
283
w = d.width;
284
}
285
if (d.height > h) {
286
h = d.height;
287
}
288
}
289
return new Dimension(insets.left + insets.right + w + hgap*2,
290
insets.top + insets.bottom + h + vgap*2);
291
}
292
}
293
294
/**
295
* Calculates the minimum size for the specified panel.
296
* @param parent the parent container in which to do the layout
297
* @return the minimum dimensions required to lay out the
298
* subcomponents of the specified container
299
* @see java.awt.Container#doLayout
300
* @see java.awt.CardLayout#preferredLayoutSize
301
*/
302
public Dimension minimumLayoutSize(Container parent) {
303
synchronized (parent.getTreeLock()) {
304
Insets insets = parent.getInsets();
305
int ncomponents = parent.getComponentCount();
306
int w = 0;
307
int h = 0;
308
309
for (int i = 0 ; i < ncomponents ; i++) {
310
Component comp = parent.getComponent(i);
311
Dimension d = comp.getMinimumSize();
312
if (d.width > w) {
313
w = d.width;
314
}
315
if (d.height > h) {
316
h = d.height;
317
}
318
}
319
return new Dimension(insets.left + insets.right + w + hgap*2,
320
insets.top + insets.bottom + h + vgap*2);
321
}
322
}
323
324
/**
325
* Returns the maximum dimensions for this layout given the components
326
* in the specified target container.
327
* @param target the component which needs to be laid out
328
* @see Container
329
* @see #minimumLayoutSize
330
* @see #preferredLayoutSize
331
*/
332
public Dimension maximumLayoutSize(Container target) {
333
return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
334
}
335
336
/**
337
* Returns the alignment along the x axis. This specifies how
338
* the component would like to be aligned relative to other
339
* components. The value should be a number between 0 and 1
340
* where 0 represents alignment along the origin, 1 is aligned
341
* the furthest away from the origin, 0.5 is centered, etc.
342
*/
343
public float getLayoutAlignmentX(Container parent) {
344
return 0.5f;
345
}
346
347
/**
348
* Returns the alignment along the y axis. This specifies how
349
* the component would like to be aligned relative to other
350
* components. The value should be a number between 0 and 1
351
* where 0 represents alignment along the origin, 1 is aligned
352
* the furthest away from the origin, 0.5 is centered, etc.
353
*/
354
public float getLayoutAlignmentY(Container parent) {
355
return 0.5f;
356
}
357
358
/**
359
* Invalidates the layout, indicating that if the layout manager
360
* has cached information it should be discarded.
361
*/
362
public void invalidateLayout(Container target) {
363
}
364
365
/**
366
* Lays out the specified container using this card layout.
367
* <p>
368
* Each component in the <code>parent</code> container is reshaped
369
* to be the size of the container, minus space for surrounding
370
* insets, horizontal gaps, and vertical gaps.
371
*
372
* @param parent the parent container in which to do the layout
373
* @see java.awt.Container#doLayout
374
*/
375
public void layoutContainer(Container parent) {
376
synchronized (parent.getTreeLock()) {
377
Insets insets = parent.getInsets();
378
int ncomponents = parent.getComponentCount();
379
Component comp = null;
380
boolean currentFound = false;
381
382
for (int i = 0 ; i < ncomponents ; i++) {
383
comp = parent.getComponent(i);
384
comp.setBounds(hgap + insets.left, vgap + insets.top,
385
parent.width - (hgap*2 + insets.left + insets.right),
386
parent.height - (vgap*2 + insets.top + insets.bottom));
387
if (comp.isVisible()) {
388
currentFound = true;
389
}
390
}
391
392
if (!currentFound && ncomponents > 0) {
393
parent.getComponent(0).setVisible(true);
394
}
395
}
396
}
397
398
/**
399
* Make sure that the Container really has a CardLayout installed.
400
* Otherwise havoc can ensue!
401
*/
402
void checkLayout(Container parent) {
403
if (parent.getLayout() != this) {
404
throw new IllegalArgumentException("wrong parent for CardLayout");
405
}
406
}
407
408
/**
409
* Flips to the first card of the container.
410
* @param parent the parent container in which to do the layout
411
* @see java.awt.CardLayout#last
412
*/
413
public void first(Container parent) {
414
synchronized (parent.getTreeLock()) {
415
checkLayout(parent);
416
int ncomponents = parent.getComponentCount();
417
for (int i = 0 ; i < ncomponents ; i++) {
418
Component comp = parent.getComponent(i);
419
if (comp.isVisible()) {
420
comp.setVisible(false);
421
break;
422
}
423
}
424
if (ncomponents > 0) {
425
currentCard = 0;
426
parent.getComponent(0).setVisible(true);
427
parent.validate();
428
}
429
}
430
}
431
432
/**
433
* Flips to the next card of the specified container. If the
434
* currently visible card is the last one, this method flips to the
435
* first card in the layout.
436
* @param parent the parent container in which to do the layout
437
* @see java.awt.CardLayout#previous
438
*/
439
public void next(Container parent) {
440
synchronized (parent.getTreeLock()) {
441
checkLayout(parent);
442
int ncomponents = parent.getComponentCount();
443
for (int i = 0 ; i < ncomponents ; i++) {
444
Component comp = parent.getComponent(i);
445
if (comp.isVisible()) {
446
comp.setVisible(false);
447
currentCard = (i + 1) % ncomponents;
448
comp = parent.getComponent(currentCard);
449
comp.setVisible(true);
450
parent.validate();
451
return;
452
}
453
}
454
showDefaultComponent(parent);
455
}
456
}
457
458
/**
459
* Flips to the previous card of the specified container. If the
460
* currently visible card is the first one, this method flips to the
461
* last card in the layout.
462
* @param parent the parent container in which to do the layout
463
* @see java.awt.CardLayout#next
464
*/
465
public void previous(Container parent) {
466
synchronized (parent.getTreeLock()) {
467
checkLayout(parent);
468
int ncomponents = parent.getComponentCount();
469
for (int i = 0 ; i < ncomponents ; i++) {
470
Component comp = parent.getComponent(i);
471
if (comp.isVisible()) {
472
comp.setVisible(false);
473
currentCard = ((i > 0) ? i-1 : ncomponents-1);
474
comp = parent.getComponent(currentCard);
475
comp.setVisible(true);
476
parent.validate();
477
return;
478
}
479
}
480
showDefaultComponent(parent);
481
}
482
}
483
484
void showDefaultComponent(Container parent) {
485
if (parent.getComponentCount() > 0) {
486
currentCard = 0;
487
parent.getComponent(0).setVisible(true);
488
parent.validate();
489
}
490
}
491
492
/**
493
* Flips to the last card of the container.
494
* @param parent the parent container in which to do the layout
495
* @see java.awt.CardLayout#first
496
*/
497
public void last(Container parent) {
498
synchronized (parent.getTreeLock()) {
499
checkLayout(parent);
500
int ncomponents = parent.getComponentCount();
501
for (int i = 0 ; i < ncomponents ; i++) {
502
Component comp = parent.getComponent(i);
503
if (comp.isVisible()) {
504
comp.setVisible(false);
505
break;
506
}
507
}
508
if (ncomponents > 0) {
509
currentCard = ncomponents - 1;
510
parent.getComponent(currentCard).setVisible(true);
511
parent.validate();
512
}
513
}
514
}
515
516
/**
517
* Flips to the component that was added to this layout with the
518
* specified <code>name</code>, using <code>addLayoutComponent</code>.
519
* If no such component exists, then nothing happens.
520
* @param parent the parent container in which to do the layout
521
* @param name the component name
522
* @see java.awt.CardLayout#addLayoutComponent(java.awt.Component, java.lang.Object)
523
*/
524
public void show(Container parent, String name) {
525
synchronized (parent.getTreeLock()) {
526
checkLayout(parent);
527
Component next = null;
528
int ncomponents = vector.size();
529
for (int i = 0; i < ncomponents; i++) {
530
Card card = (Card)vector.get(i);
531
if (card.name.equals(name)) {
532
next = card.comp;
533
currentCard = i;
534
break;
535
}
536
}
537
if ((next != null) && !next.isVisible()) {
538
ncomponents = parent.getComponentCount();
539
for (int i = 0; i < ncomponents; i++) {
540
Component comp = parent.getComponent(i);
541
if (comp.isVisible()) {
542
comp.setVisible(false);
543
break;
544
}
545
}
546
next.setVisible(true);
547
parent.validate();
548
}
549
}
550
}
551
552
/**
553
* Returns a string representation of the state of this card layout.
554
* @return a string representation of this card layout.
555
*/
556
public String toString() {
557
return getClass().getName() + "[hgap=" + hgap + ",vgap=" + vgap + "]";
558
}
559
560
/**
561
* Reads serializable fields from stream.
562
*/
563
private void readObject(ObjectInputStream s)
564
throws ClassNotFoundException, IOException
565
{
566
ObjectInputStream.GetField f = s.readFields();
567
568
hgap = f.get("hgap", 0);
569
vgap = f.get("vgap", 0);
570
571
if (f.defaulted("vector")) {
572
// pre-1.4 stream
573
Hashtable<String, Component> tab = (Hashtable)f.get("tab", null);
574
vector = new Vector<>();
575
if (tab != null && !tab.isEmpty()) {
576
for (Enumeration<String> e = tab.keys() ; e.hasMoreElements() ; ) {
577
String key = (String)e.nextElement();
578
Component comp = (Component)tab.get(key);
579
vector.add(new Card(key, comp));
580
if (comp.isVisible()) {
581
currentCard = vector.size() - 1;
582
}
583
}
584
}
585
} else {
586
vector = (Vector)f.get("vector", null);
587
currentCard = f.get("currentCard", 0);
588
}
589
}
590
591
/**
592
* Writes serializable fields to stream.
593
*/
594
private void writeObject(ObjectOutputStream s)
595
throws IOException
596
{
597
Hashtable<String, Component> tab = new Hashtable<>();
598
int ncomponents = vector.size();
599
for (int i = 0; i < ncomponents; i++) {
600
Card card = (Card)vector.get(i);
601
tab.put(card.name, card.comp);
602
}
603
604
ObjectOutputStream.PutField f = s.putFields();
605
f.put("hgap", hgap);
606
f.put("vgap", vgap);
607
f.put("vector", vector);
608
f.put("currentCard", currentCard);
609
f.put("tab", tab);
610
s.writeFields();
611
}
612
}
613
614