Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/share/classes/sun/swing/plaf/synth/DefaultSynthStyle.java
41161 views
1
/*
2
* Copyright (c) 2002, 2016, 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
package sun.swing.plaf.synth;
26
27
import javax.swing.plaf.synth.*;
28
import java.awt.*;
29
import java.util.*;
30
import javax.swing.*;
31
import javax.swing.plaf.*;
32
33
/**
34
* Default implementation of SynthStyle. Has setters for the various
35
* SynthStyle methods. Many of the properties can be specified for all states,
36
* using SynthStyle directly, or a specific state using one of the StateInfo
37
* methods.
38
* <p>
39
* Beyond the constructor a subclass should override the <code>addTo</code>
40
* and <code>clone</code> methods, these are used when the Styles are being
41
* merged into a resulting style.
42
*
43
* @author Scott Violet
44
*/
45
public class DefaultSynthStyle extends SynthStyle implements Cloneable {
46
47
private static final Object PENDING = new Object();
48
49
/**
50
* Should the component be opaque?
51
*/
52
private boolean opaque;
53
/**
54
* Insets.
55
*/
56
private Insets insets;
57
/**
58
* Information specific to ComponentState.
59
*/
60
private StateInfo[] states;
61
/**
62
* User specific data.
63
*/
64
private Map<Object, Object> data;
65
66
/**
67
* Font to use if there is no matching StateInfo, or the StateInfo doesn't
68
* define one.
69
*/
70
private Font font;
71
72
/**
73
* SynthGraphics, may be null.
74
*/
75
private SynthGraphicsUtils synthGraphics;
76
77
/**
78
* Painter to use if the StateInfo doesn't have one.
79
*/
80
private SynthPainter painter;
81
82
83
/**
84
* Nullary constructor, intended for subclassers.
85
*/
86
public DefaultSynthStyle() {
87
}
88
89
/**
90
* Creates a new DefaultSynthStyle that is a copy of the passed in
91
* style. Any StateInfo's of the passed in style are clonsed as well.
92
*
93
* @param style Style to duplicate
94
*/
95
public DefaultSynthStyle(DefaultSynthStyle style) {
96
opaque = style.opaque;
97
if (style.insets != null) {
98
insets = new Insets(style.insets.top, style.insets.left,
99
style.insets.bottom, style.insets.right);
100
}
101
if (style.states != null) {
102
states = new StateInfo[style.states.length];
103
for (int counter = style.states.length - 1; counter >= 0;
104
counter--) {
105
states[counter] = (StateInfo)style.states[counter].clone();
106
}
107
}
108
if (style.data != null) {
109
data = new HashMap<>();
110
data.putAll(style.data);
111
}
112
font = style.font;
113
synthGraphics = style.synthGraphics;
114
painter = style.painter;
115
}
116
117
/**
118
* Creates a new DefaultSynthStyle.
119
*
120
* @param insets Insets for the Style
121
* @param opaque Whether or not the background is completely painted in
122
* an opaque color
123
* @param states StateInfos describing properties per state
124
* @param data Style specific data.
125
*/
126
public DefaultSynthStyle(Insets insets, boolean opaque,
127
StateInfo[] states, Map<Object, Object> data) {
128
this.insets = insets;
129
this.opaque = opaque;
130
this.states = states;
131
this.data = data;
132
}
133
134
public Color getColor(SynthContext context, ColorType type) {
135
return getColor(context.getComponent(), context.getRegion(),
136
context.getComponentState(), type);
137
}
138
139
public Color getColor(JComponent c, Region id, int state,
140
ColorType type) {
141
// For the enabled state, prefer the widget's colors
142
if (!id.isSubregion() && state == SynthConstants.ENABLED) {
143
if (type == ColorType.BACKGROUND) {
144
return c.getBackground();
145
}
146
else if (type == ColorType.FOREGROUND) {
147
return c.getForeground();
148
}
149
else if (type == ColorType.TEXT_FOREGROUND) {
150
// If getForeground returns a non-UIResource it means the
151
// developer has explicitly set the foreground, use it over
152
// that of TEXT_FOREGROUND as that is typically the expected
153
// behavior.
154
Color color = c.getForeground();
155
if (!(color instanceof UIResource)) {
156
return color;
157
}
158
}
159
}
160
// Then use what we've locally defined
161
Color color = getColorForState(c, id, state, type);
162
if (color == null) {
163
// No color, fallback to that of the widget.
164
if (type == ColorType.BACKGROUND ||
165
type == ColorType.TEXT_BACKGROUND) {
166
return c.getBackground();
167
}
168
else if (type == ColorType.FOREGROUND ||
169
type == ColorType.TEXT_FOREGROUND) {
170
return c.getForeground();
171
}
172
}
173
return color;
174
}
175
176
protected Color getColorForState(SynthContext context, ColorType type) {
177
return getColorForState(context.getComponent(), context.getRegion(),
178
context.getComponentState(), type);
179
}
180
181
/**
182
* Returns the color for the specified state.
183
*
184
* @param c JComponent the style is associated with
185
* @param id Region identifier
186
* @param state State of the region.
187
* @param type Type of color being requested.
188
* @return Color to render with
189
*/
190
protected Color getColorForState(JComponent c, Region id, int state,
191
ColorType type) {
192
// Use the best state.
193
StateInfo si = getStateInfo(state);
194
Color color;
195
if (si != null && (color = si.getColor(type)) != null) {
196
return color;
197
}
198
if (si == null || si.getComponentState() != 0) {
199
si = getStateInfo(0);
200
if (si != null) {
201
return si.getColor(type);
202
}
203
}
204
return null;
205
}
206
207
/**
208
* Sets the font that is used if there is no matching StateInfo, or
209
* it does not define a font.
210
*
211
* @param font Font to use for rendering
212
*/
213
public void setFont(Font font) {
214
this.font = font;
215
}
216
217
public Font getFont(SynthContext state) {
218
return getFont(state.getComponent(), state.getRegion(),
219
state.getComponentState());
220
}
221
222
public Font getFont(JComponent c, Region id, int state) {
223
if (!id.isSubregion() && state == SynthConstants.ENABLED) {
224
return c.getFont();
225
}
226
Font cFont = c.getFont();
227
if (cFont != null && !(cFont instanceof UIResource)) {
228
return cFont;
229
}
230
return getFontForState(c, id, state);
231
}
232
233
/**
234
* Returns the font for the specified state. This should NOT callback
235
* to the JComponent.
236
*
237
* @param c JComponent the style is associated with
238
* @param id Region identifier
239
* @param state State of the region.
240
* @return Font to render with
241
*/
242
protected Font getFontForState(JComponent c, Region id, int state) {
243
if (c == null) {
244
return this.font;
245
}
246
// First pass, look for the best match
247
StateInfo si = getStateInfo(state);
248
Font font;
249
if (si != null && (font = si.getFont()) != null) {
250
return font;
251
}
252
if (si == null || si.getComponentState() != 0) {
253
si = getStateInfo(0);
254
if (si != null && (font = si.getFont()) != null) {
255
return font;
256
}
257
}
258
// Fallback font.
259
return this.font;
260
}
261
262
protected Font getFontForState(SynthContext context) {
263
return getFontForState(context.getComponent(), context.getRegion(),
264
context.getComponentState());
265
}
266
267
/**
268
* Sets the SynthGraphicsUtils that will be used for rendering.
269
*
270
* @param graphics SynthGraphics
271
*/
272
public void setGraphicsUtils(SynthGraphicsUtils graphics) {
273
this.synthGraphics = graphics;
274
}
275
276
/**
277
* Returns a SynthGraphicsUtils.
278
*
279
* @param context SynthContext identifying requestor
280
* @return SynthGraphicsUtils
281
*/
282
public SynthGraphicsUtils getGraphicsUtils(SynthContext context) {
283
if (synthGraphics == null) {
284
return super.getGraphicsUtils(context);
285
}
286
return synthGraphics;
287
}
288
289
/**
290
* Sets the insets.
291
*
292
* @param insets the new insets.
293
*/
294
public void setInsets(Insets insets) {
295
this.insets = insets;
296
}
297
298
/**
299
* Returns the Insets. If <code>to</code> is non-null the resulting
300
* insets will be placed in it, otherwise a new Insets object will be
301
* created and returned.
302
*
303
* @param state SynthContext identifying requestor
304
* @param to Where to place Insets
305
* @return Insets.
306
*/
307
public Insets getInsets(SynthContext state, Insets to) {
308
if (to == null) {
309
to = new Insets(0, 0, 0, 0);
310
}
311
if (insets != null) {
312
to.left = insets.left;
313
to.right = insets.right;
314
to.top = insets.top;
315
to.bottom = insets.bottom;
316
}
317
else {
318
to.left = to.right = to.top = to.bottom = 0;
319
}
320
return to;
321
}
322
323
/**
324
* Sets the Painter to use for the border.
325
*
326
* @param painter Painter for the Border.
327
*/
328
public void setPainter(SynthPainter painter) {
329
this.painter = painter;
330
}
331
332
/**
333
* Returns the Painter for the passed in Component. This may return null.
334
*
335
* @param ss SynthContext identifying requestor
336
* @return Painter for the border
337
*/
338
public SynthPainter getPainter(SynthContext ss) {
339
return painter;
340
}
341
342
/**
343
* Sets whether or not the JComponent should be opaque.
344
*
345
* @param opaque Whether or not the JComponent should be opaque.
346
*/
347
public void setOpaque(boolean opaque) {
348
this.opaque = opaque;
349
}
350
351
/**
352
* Returns the value to initialize the opacity property of the Component
353
* to. A Style should NOT assume the opacity will remain this value, the
354
* developer may reset it or override it.
355
*
356
* @param ss SynthContext identifying requestor
357
* @return opaque Whether or not the JComponent is opaque.
358
*/
359
public boolean isOpaque(SynthContext ss) {
360
return opaque;
361
}
362
363
/**
364
* Sets style specific values. This does NOT copy the data, it
365
* assigns it directly to this Style.
366
*
367
* @param data Style specific values
368
*/
369
public void setData(Map<Object, Object> data) {
370
this.data = data;
371
}
372
373
/**
374
* Returns the style specific data.
375
*
376
* @return Style specific data.
377
*/
378
public Map<Object, Object> getData() {
379
return data;
380
}
381
382
/**
383
* Getter for a region specific style property.
384
*
385
* @param state SynthContext identifying requestor
386
* @param key Property being requested.
387
* @return Value of the named property
388
*/
389
public Object get(SynthContext state, Object key) {
390
// Look for the best match
391
StateInfo si = getStateInfo(state.getComponentState());
392
if (si != null && si.getData() != null && getKeyFromData(si.getData(), key) != null) {
393
return getKeyFromData(si.getData(), key);
394
}
395
si = getStateInfo(0);
396
if (si != null && si.getData() != null && getKeyFromData(si.getData(), key) != null) {
397
return getKeyFromData(si.getData(), key);
398
}
399
if(getKeyFromData(data, key) != null)
400
return getKeyFromData(data, key);
401
return getDefaultValue(state, key);
402
}
403
404
405
private Object getKeyFromData(Map<Object, Object> stateData, Object key) {
406
Object value = null;
407
if (stateData != null) {
408
409
synchronized(stateData) {
410
value = stateData.get(key);
411
}
412
while (value == PENDING) {
413
synchronized(stateData) {
414
try {
415
stateData.wait();
416
} catch (InterruptedException ie) {}
417
value = stateData.get(key);
418
}
419
}
420
if (value instanceof UIDefaults.LazyValue) {
421
synchronized(stateData) {
422
stateData.put(key, PENDING);
423
}
424
value = ((UIDefaults.LazyValue)value).createValue(null);
425
synchronized(stateData) {
426
stateData.put(key, value);
427
stateData.notifyAll();
428
}
429
}
430
}
431
return value;
432
}
433
434
/**
435
* Returns the default value for a particular property. This is only
436
* invoked if this style doesn't define a property for <code>key</code>.
437
*
438
* @param context SynthContext identifying requestor
439
* @param key Property being requested.
440
* @return Value of the named property
441
*/
442
public Object getDefaultValue(SynthContext context, Object key) {
443
return super.get(context, key);
444
}
445
446
/**
447
* Creates a clone of this style.
448
*
449
* @return Clone of this style
450
*/
451
public Object clone() {
452
DefaultSynthStyle style;
453
try {
454
style = (DefaultSynthStyle)super.clone();
455
} catch (CloneNotSupportedException cnse) {
456
return null;
457
}
458
if (states != null) {
459
style.states = new StateInfo[states.length];
460
for (int counter = states.length - 1; counter >= 0; counter--) {
461
style.states[counter] = (StateInfo)states[counter].clone();
462
}
463
}
464
if (data != null) {
465
style.data = new HashMap<>();
466
style.data.putAll(data);
467
}
468
return style;
469
}
470
471
/**
472
* Merges the contents of this Style with that of the passed in Style,
473
* returning the resulting merged syle. Properties of this
474
* <code>DefaultSynthStyle</code> will take precedence over those of the
475
* passed in <code>DefaultSynthStyle</code>. For example, if this
476
* style specifics a non-null font, the returned style will have its
477
* font so to that regardless of the <code>style</code>'s font.
478
*
479
* @param style Style to add our styles to
480
* @return Merged style.
481
*/
482
public DefaultSynthStyle addTo(DefaultSynthStyle style) {
483
if (insets != null) {
484
style.insets = this.insets;
485
}
486
if (font != null) {
487
style.font = this.font;
488
}
489
if (painter != null) {
490
style.painter = this.painter;
491
}
492
if (synthGraphics != null) {
493
style.synthGraphics = this.synthGraphics;
494
}
495
style.opaque = opaque;
496
if (states != null) {
497
if (style.states == null) {
498
style.states = new StateInfo[states.length];
499
for (int counter = states.length - 1; counter >= 0; counter--){
500
if (states[counter] != null) {
501
style.states[counter] = (StateInfo)states[counter].
502
clone();
503
}
504
}
505
}
506
else {
507
// Find the number of new states in unique, merging any
508
// matching states as we go. Also, move any merge styles
509
// to the end to give them precedence.
510
int unique = 0;
511
// Number of StateInfos that match.
512
int matchCount = 0;
513
int maxOStyles = style.states.length;
514
for (int thisCounter = states.length - 1; thisCounter >= 0;
515
thisCounter--) {
516
int state = states[thisCounter].getComponentState();
517
boolean found = false;
518
519
for (int oCounter = maxOStyles - 1 - matchCount;
520
oCounter >= 0; oCounter--) {
521
if (state == style.states[oCounter].
522
getComponentState()) {
523
style.states[oCounter] = states[thisCounter].
524
addTo(style.states[oCounter]);
525
// Move StateInfo to end, giving it precedence.
526
StateInfo tmp = style.states[maxOStyles - 1 -
527
matchCount];
528
style.states[maxOStyles - 1 - matchCount] =
529
style.states[oCounter];
530
style.states[oCounter] = tmp;
531
matchCount++;
532
found = true;
533
break;
534
}
535
}
536
if (!found) {
537
unique++;
538
}
539
}
540
if (unique != 0) {
541
// There are states that exist in this Style that
542
// don't exist in the other style, recreate the array
543
// and add them.
544
StateInfo[] newStates = new StateInfo[
545
unique + maxOStyles];
546
int newIndex = maxOStyles;
547
548
System.arraycopy(style.states, 0, newStates, 0,maxOStyles);
549
for (int thisCounter = states.length - 1; thisCounter >= 0;
550
thisCounter--) {
551
int state = states[thisCounter].getComponentState();
552
boolean found = false;
553
554
for (int oCounter = maxOStyles - 1; oCounter >= 0;
555
oCounter--) {
556
if (state == style.states[oCounter].
557
getComponentState()) {
558
found = true;
559
break;
560
}
561
}
562
if (!found) {
563
newStates[newIndex++] = (StateInfo)states[
564
thisCounter].clone();
565
}
566
}
567
style.states = newStates;
568
}
569
}
570
}
571
if (data != null) {
572
if (style.data == null) {
573
style.data = new HashMap<>();
574
}
575
style.data.putAll(data);
576
}
577
return style;
578
}
579
580
/**
581
* Sets the array of StateInfo's which are used to specify properties
582
* specific to a particular style.
583
*
584
* @param states StateInfos
585
*/
586
public void setStateInfo(StateInfo[] states) {
587
this.states = states;
588
}
589
590
/**
591
* Returns the array of StateInfo's that that are used to specify
592
* properties specific to a particular style.
593
*
594
* @return Array of StateInfos.
595
*/
596
public StateInfo[] getStateInfo() {
597
return states;
598
}
599
600
/**
601
* Returns the best matching StateInfo for a particular state.
602
*
603
* @param state Component state.
604
* @return Best matching StateInfo, or null
605
*/
606
public StateInfo getStateInfo(int state) {
607
// Use the StateInfo with the most bits that matches that of state.
608
// If there is none, than fallback to
609
// the StateInfo with a state of 0, indicating it'll match anything.
610
611
// Consider if we have 3 StateInfos a, b and c with states:
612
// SELECTED, SELECTED | ENABLED, 0
613
//
614
// Input Return Value
615
// ----- ------------
616
// SELECTED a
617
// SELECTED | ENABLED b
618
// MOUSE_OVER c
619
// SELECTED | ENABLED | FOCUSED b
620
// ENABLED c
621
622
if (states != null) {
623
int bestCount = 0;
624
int bestIndex = -1;
625
int wildIndex = -1;
626
627
if (state == 0) {
628
for (int counter = states.length - 1; counter >= 0;counter--) {
629
if (states[counter].getComponentState() == 0) {
630
return states[counter];
631
}
632
}
633
return null;
634
}
635
for (int counter = states.length - 1; counter >= 0; counter--) {
636
int oState = states[counter].getComponentState();
637
638
if (oState == 0) {
639
if (wildIndex == -1) {
640
wildIndex = counter;
641
}
642
}
643
else if ((state & oState) == oState) {
644
// This is key, we need to make sure all bits of the
645
// StateInfo match, otherwise a StateInfo with
646
// SELECTED | ENABLED would match ENABLED, which we
647
// don't want.
648
int bitCount = Integer.bitCount(oState);
649
if (bitCount > bestCount) {
650
bestIndex = counter;
651
bestCount = bitCount;
652
}
653
}
654
}
655
if (bestIndex != -1) {
656
return states[bestIndex];
657
}
658
if (wildIndex != -1) {
659
return states[wildIndex];
660
}
661
}
662
return null;
663
}
664
665
666
public String toString() {
667
StringBuilder sb = new StringBuilder();
668
669
sb.append(super.toString()).append(',');
670
671
sb.append("data=").append(data).append(',');
672
673
sb.append("font=").append(font).append(',');
674
675
sb.append("insets=").append(insets).append(',');
676
677
sb.append("synthGraphics=").append(synthGraphics).append(',');
678
679
sb.append("painter=").append(painter).append(',');
680
681
StateInfo[] states = getStateInfo();
682
if (states != null) {
683
sb.append("states[");
684
for (StateInfo state : states) {
685
sb.append(state.toString()).append(',');
686
}
687
sb.append(']').append(',');
688
}
689
690
// remove last newline
691
sb.deleteCharAt(sb.length() - 1);
692
693
return sb.toString();
694
}
695
696
697
/**
698
* StateInfo represents Style information specific to the state of
699
* a component.
700
*/
701
public static class StateInfo {
702
private Map<Object, Object> data;
703
private Font font;
704
private Color[] colors;
705
private int state;
706
707
/**
708
* Creates a new StateInfo.
709
*/
710
public StateInfo() {
711
}
712
713
/**
714
* Creates a new StateInfo with the specified properties
715
*
716
* @param state Component state(s) that this StateInfo should be used
717
* for
718
* @param font Font for this state
719
* @param colors Colors for this state
720
*/
721
public StateInfo(int state, Font font, Color[] colors) {
722
this.state = state;
723
this.font = font;
724
this.colors = colors;
725
}
726
727
/**
728
* Creates a new StateInfo that is a copy of the passed in
729
* StateInfo.
730
*
731
* @param info StateInfo to copy.
732
*/
733
public StateInfo(StateInfo info) {
734
this.state = info.state;
735
this.font = info.font;
736
if(info.data != null) {
737
if(data == null) {
738
data = new HashMap<>();
739
}
740
data.putAll(info.data);
741
}
742
if (info.colors != null) {
743
this.colors = new Color[info.colors.length];
744
System.arraycopy(info.colors, 0, colors, 0,info.colors.length);
745
}
746
}
747
748
public Map<Object, Object> getData() {
749
return data;
750
}
751
752
public void setData(Map<Object, Object> data) {
753
this.data = data;
754
}
755
756
/**
757
* Sets the font for this state.
758
*
759
* @param font Font to use for rendering
760
*/
761
public void setFont(Font font) {
762
this.font = font;
763
}
764
765
/**
766
* Returns the font for this state.
767
*
768
* @return Returns the font to use for rendering this state
769
*/
770
public Font getFont() {
771
return font;
772
}
773
774
/**
775
* Sets the array of colors to use for rendering this state. This
776
* is indexed by <code>ColorType.getID()</code>.
777
*
778
* @param colors Array of colors
779
*/
780
public void setColors(Color[] colors) {
781
this.colors = colors;
782
}
783
784
/**
785
* Returns the array of colors to use for rendering this state. This
786
* is indexed by <code>ColorType.getID()</code>.
787
*
788
* @return Array of colors
789
*/
790
public Color[] getColors() {
791
return colors;
792
}
793
794
/**
795
* Returns the Color to used for the specified ColorType.
796
*
797
* @return Color.
798
*/
799
public Color getColor(ColorType type) {
800
if (colors != null) {
801
int id = type.getID();
802
803
if (id < colors.length) {
804
return colors[id];
805
}
806
}
807
return null;
808
}
809
810
/**
811
* Merges the contents of this StateInfo with that of the passed in
812
* StateInfo, returning the resulting merged StateInfo. Properties of
813
* this <code>StateInfo</code> will take precedence over those of the
814
* passed in <code>StateInfo</code>. For example, if this
815
* StateInfo specifics a non-null font, the returned StateInfo will
816
* have its font so to that regardless of the <code>StateInfo</code>'s
817
* font.
818
*
819
* @param info StateInfo to add our styles to
820
* @return Merged StateInfo.
821
*/
822
public StateInfo addTo(StateInfo info) {
823
if (font != null) {
824
info.font = font;
825
}
826
if(data != null) {
827
if(info.data == null) {
828
info.data = new HashMap<>();
829
}
830
info.data.putAll(data);
831
}
832
if (colors != null) {
833
if (info.colors == null) {
834
info.colors = new Color[colors.length];
835
System.arraycopy(colors, 0, info.colors, 0,
836
colors.length);
837
}
838
else {
839
if (info.colors.length < colors.length) {
840
Color[] old = info.colors;
841
842
info.colors = new Color[colors.length];
843
System.arraycopy(old, 0, info.colors, 0, old.length);
844
}
845
for (int counter = colors.length - 1; counter >= 0;
846
counter--) {
847
if (colors[counter] != null) {
848
info.colors[counter] = colors[counter];
849
}
850
}
851
}
852
}
853
return info;
854
}
855
856
/**
857
* Sets the state this StateInfo corresponds to.
858
*
859
* @see SynthConstants
860
* @param state info.
861
*/
862
public void setComponentState(int state) {
863
this.state = state;
864
}
865
866
/**
867
* Returns the state this StateInfo corresponds to.
868
*
869
* @see SynthConstants
870
* @return state info.
871
*/
872
public int getComponentState() {
873
return state;
874
}
875
876
/**
877
* Creates and returns a copy of this StateInfo.
878
*
879
* @return Copy of this StateInfo.
880
*/
881
public Object clone() {
882
return new StateInfo(this);
883
}
884
885
public String toString() {
886
StringBuilder sb = new StringBuilder();
887
888
sb.append(super.toString()).append(',');
889
890
sb.append("state=").append(Integer.toString(state)).append(',');
891
892
sb.append("font=").append(font).append(',');
893
894
if (colors != null) {
895
sb.append("colors=").append(Arrays.asList(colors)).
896
append(',');
897
}
898
return sb.toString();
899
}
900
}
901
}
902
903