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/sun/swing/plaf/synth/DefaultSynthStyle.java
38918 views
1
/*
2
* Copyright (c) 2002, 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
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 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 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.
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 context 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 data) {
370
this.data = data;
371
}
372
373
/**
374
* Returns the style specific data.
375
*
376
* @return Style specific data.
377
*/
378
public Map 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 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 state 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
649
// This comes from BigInteger.bitCnt
650
int bitCount = oState;
651
bitCount -= (0xaaaaaaaa & bitCount) >>> 1;
652
bitCount = (bitCount & 0x33333333) + ((bitCount >>> 2) &
653
0x33333333);
654
bitCount = bitCount + (bitCount >>> 4) & 0x0f0f0f0f;
655
bitCount += bitCount >>> 8;
656
bitCount += bitCount >>> 16;
657
bitCount = bitCount & 0xff;
658
if (bitCount > bestCount) {
659
bestIndex = counter;
660
bestCount = bitCount;
661
}
662
}
663
}
664
if (bestIndex != -1) {
665
return states[bestIndex];
666
}
667
if (wildIndex != -1) {
668
return states[wildIndex];
669
}
670
}
671
return null;
672
}
673
674
675
public String toString() {
676
StringBuffer buf = new StringBuffer();
677
678
buf.append(super.toString()).append(',');
679
680
buf.append("data=").append(data).append(',');
681
682
buf.append("font=").append(font).append(',');
683
684
buf.append("insets=").append(insets).append(',');
685
686
buf.append("synthGraphics=").append(synthGraphics).append(',');
687
688
buf.append("painter=").append(painter).append(',');
689
690
StateInfo[] states = getStateInfo();
691
if (states != null) {
692
buf.append("states[");
693
for (StateInfo state : states) {
694
buf.append(state.toString()).append(',');
695
}
696
buf.append(']').append(',');
697
}
698
699
// remove last newline
700
buf.deleteCharAt(buf.length() - 1);
701
702
return buf.toString();
703
}
704
705
706
/**
707
* StateInfo represents Style information specific to the state of
708
* a component.
709
*/
710
public static class StateInfo {
711
private Map data;
712
private Font font;
713
private Color[] colors;
714
private int state;
715
716
/**
717
* Creates a new StateInfo.
718
*/
719
public StateInfo() {
720
}
721
722
/**
723
* Creates a new StateInfo with the specified properties
724
*
725
* @param state Component state(s) that this StateInfo should be used
726
* for
727
* @param painter Painter responsible for rendering
728
* @param bgPainter Painter responsible for rendering the background
729
* @param font Font for this state
730
* @param colors Colors for this state
731
*/
732
public StateInfo(int state, Font font, Color[] colors) {
733
this.state = state;
734
this.font = font;
735
this.colors = colors;
736
}
737
738
/**
739
* Creates a new StateInfo that is a copy of the passed in
740
* StateInfo.
741
*
742
* @param info StateInfo to copy.
743
*/
744
public StateInfo(StateInfo info) {
745
this.state = info.state;
746
this.font = info.font;
747
if(info.data != null) {
748
if(data == null) {
749
data = new HashMap();
750
}
751
data.putAll(info.data);
752
}
753
if (info.colors != null) {
754
this.colors = new Color[info.colors.length];
755
System.arraycopy(info.colors, 0, colors, 0,info.colors.length);
756
}
757
}
758
759
public Map getData() {
760
return data;
761
}
762
763
public void setData(Map data) {
764
this.data = data;
765
}
766
767
/**
768
* Sets the font for this state.
769
*
770
* @param font Font to use for rendering
771
*/
772
public void setFont(Font font) {
773
this.font = font;
774
}
775
776
/**
777
* Returns the font for this state.
778
*
779
* @return Returns the font to use for rendering this state
780
*/
781
public Font getFont() {
782
return font;
783
}
784
785
/**
786
* Sets the array of colors to use for rendering this state. This
787
* is indexed by <code>ColorType.getID()</code>.
788
*
789
* @param colors Array of colors
790
*/
791
public void setColors(Color[] colors) {
792
this.colors = colors;
793
}
794
795
/**
796
* Returns the array of colors to use for rendering this state. This
797
* is indexed by <code>ColorType.getID()</code>.
798
*
799
* @return Array of colors
800
*/
801
public Color[] getColors() {
802
return colors;
803
}
804
805
/**
806
* Returns the Color to used for the specified ColorType.
807
*
808
* @return Color.
809
*/
810
public Color getColor(ColorType type) {
811
if (colors != null) {
812
int id = type.getID();
813
814
if (id < colors.length) {
815
return colors[id];
816
}
817
}
818
return null;
819
}
820
821
/**
822
* Merges the contents of this StateInfo with that of the passed in
823
* StateInfo, returning the resulting merged StateInfo. Properties of
824
* this <code>StateInfo</code> will take precedence over those of the
825
* passed in <code>StateInfo</code>. For example, if this
826
* StateInfo specifics a non-null font, the returned StateInfo will
827
* have its font so to that regardless of the <code>StateInfo</code>'s
828
* font.
829
*
830
* @param info StateInfo to add our styles to
831
* @return Merged StateInfo.
832
*/
833
public StateInfo addTo(StateInfo info) {
834
if (font != null) {
835
info.font = font;
836
}
837
if(data != null) {
838
if(info.data == null) {
839
info.data = new HashMap();
840
}
841
info.data.putAll(data);
842
}
843
if (colors != null) {
844
if (info.colors == null) {
845
info.colors = new Color[colors.length];
846
System.arraycopy(colors, 0, info.colors, 0,
847
colors.length);
848
}
849
else {
850
if (info.colors.length < colors.length) {
851
Color[] old = info.colors;
852
853
info.colors = new Color[colors.length];
854
System.arraycopy(old, 0, info.colors, 0, old.length);
855
}
856
for (int counter = colors.length - 1; counter >= 0;
857
counter--) {
858
if (colors[counter] != null) {
859
info.colors[counter] = colors[counter];
860
}
861
}
862
}
863
}
864
return info;
865
}
866
867
/**
868
* Sets the state this StateInfo corresponds to.
869
*
870
* @see SynthConstants
871
* @param state info.
872
*/
873
public void setComponentState(int state) {
874
this.state = state;
875
}
876
877
/**
878
* Returns the state this StateInfo corresponds to.
879
*
880
* @see SynthConstants
881
* @return state info.
882
*/
883
public int getComponentState() {
884
return state;
885
}
886
887
/**
888
* Returns the number of states that are similar between the
889
* ComponentState this StateInfo represents and val.
890
*/
891
private int getMatchCount(int val) {
892
// This comes from BigInteger.bitCnt
893
val &= state;
894
val -= (0xaaaaaaaa & val) >>> 1;
895
val = (val & 0x33333333) + ((val >>> 2) & 0x33333333);
896
val = val + (val >>> 4) & 0x0f0f0f0f;
897
val += val >>> 8;
898
val += val >>> 16;
899
return val & 0xff;
900
}
901
902
/**
903
* Creates and returns a copy of this StateInfo.
904
*
905
* @return Copy of this StateInfo.
906
*/
907
public Object clone() {
908
return new StateInfo(this);
909
}
910
911
public String toString() {
912
StringBuffer buf = new StringBuffer();
913
914
buf.append(super.toString()).append(',');
915
916
buf.append("state=").append(Integer.toString(state)).append(',');
917
918
buf.append("font=").append(font).append(',');
919
920
if (colors != null) {
921
buf.append("colors=").append(Arrays.asList(colors)).
922
append(',');
923
}
924
return buf.toString();
925
}
926
}
927
}
928
929