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