1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.cosylab.gui.components;
21
22 import java.awt.BorderLayout;
23 import java.awt.Color;
24 import java.awt.Dimension;
25 import java.awt.event.MouseAdapter;
26 import java.awt.event.MouseEvent;
27 import java.awt.event.ComponentAdapter;
28
29
30 import java.awt.Container;
31 import java.awt.event.ComponentEvent;
32
33 import javax.swing.JFrame;
34 import javax.swing.JLabel;
35 import javax.swing.SwingUtilities;
36
37
38 import com.cosylab.gui.components.ledder.BitDescriptor;
39 import com.cosylab.gui.components.ledder.BitmaskField;
40 import com.cosylab.gui.components.ledder.Led;
41 import com.cosylab.gui.components.util.ColorHelper;
42
43
44
45 public class Ledder extends javax.swing.JPanel{
46
47 private static final long serialVersionUID = 1L;
48
49
50
51 private int columns=0;
52 private BitmaskField bitmask;
53 private boolean isEditable=false;
54 private Led[] leds=null;
55 private boolean reverseLedsOrder=false;
56 private static JLabel maskNotSet;
57 public Ledder(){
58 super();
59 setBackground(ColorHelper.getCosyControl());
60 addComponentListener(new ResizeListener());
61
62 maskNotSet = new JLabel(" < Ledder is empty, mask is 0 >");
63 maskNotSet.setHorizontalAlignment(JLabel.CENTER);
64
65 }
66
67 public static void main(String[] args) {
68 final Ledder ledder = new Ledder();
69 final long mask= Integer.MAX_VALUE;
70
71
72 BitDescriptor bd= new BitDescriptor() {
73
74 public Color getColorWhenOff(int index) {
75 return Color.YELLOW;
76 }
77
78 public Color getColorWhenOn(int index) {
79 return Color.BLACK;
80 }
81
82 public String getDescription(int index) {
83 return "D"+index;
84 }
85
86 };
87 ledder.setEditable(true);
88 ledder.setBits(2);
89 ledder.setMask(mask);
90 ledder.setModel(bd);
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105 JFrame f = new JFrame();
106 f.setSize(new Dimension(200,200));
107
108
109 f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
110 Container con = f.getContentPane();
111 con.add(ledder);
112 f.setVisible(true);
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127 }
128
129
130 private final class ResizeListener extends ComponentAdapter {
131
132
133
134
135 public final void componentResized(ComponentEvent e) {
136
137
138 if(Ledder.this.isMaskSet())
139 Ledder.this.updateLayout();
140 else{
141 Ledder.this.updateNoMaskLayout();
142
143 }
144 }
145 }
146
147
148
149 private BitmaskField getBitmask() {
150 if (bitmask == null) {
151 bitmask = new BitmaskField();
152 }
153
154 return bitmask;
155 }
156
157
158
159
160
161 public boolean isEditable(){
162 return isEditable;
163 }
164
165
166
167
168
169 public void setEditable(boolean editable){
170 isEditable=editable;
171
172 SwingUtilities.invokeLater(new Runnable(){
173 public void run(){
174 if(leds != null){
175 for(int i=0; i<leds.length;i++){
176 leds[i].setEditable(isEditable);
177 }
178 }
179 }
180 });
181
182 }
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198 public long getBits() {
199 return getBitmask().getBits();
200 }
201
202 public long getBitCount(){
203 return getBitmask().getBitCount();
204 }
205
206
207
208
209 public long getMask() {
210 return getBitmask().getMask();
211 }
212
213
214
215
216 public Dimension getMinimumSize() {
217 return getLayout().minimumLayoutSize(this);
218 }
219
220
221
222
223 public BitDescriptor getModel() {
224 return getBitmask().getBitDescriptor();
225 }
226
227
228
229
230 public synchronized void setBits(long value) {
231 long oldBits = getBits();
232 getBitmask().setBits(value);
233 firePropertyChange("bits", oldBits, value);
234 updateLeds();
235 }
236
237
238 private void _updateLeds(){
239
240 long l = getBitmask().getCompactValue();
241 if(leds != null){
242 for(int i=0; i<leds.length; i++) {
243 leds[i].setOn( (l & 1) == 1);
244 l >>= 1;
245 }
246 }
247 }
248
249 private void updateLeds(){
250 SwingUtilities.invokeLater(new Runnable(){
251 public void run(){
252 _updateLeds();
253
254 }});
255 }
256
257
258
259
260
261 public void setMask(long value) {
262 long currentValue = getBitmask().getMask();
263
264 if (currentValue == value) {
265 return;
266 }
267
268 else if(value== 0){
269 updateNoMaskLayout();
270 getBitmask().setMask(value);
271 firePropertyChange("mask", currentValue, value);
272
273 }
274 else{
275
276 getBitmask().setMask(value);
277 firePropertyChange("mask", currentValue, value);
278 setLeds();
279
280 setEditable(isEditable);
281 updateLayout();
282 }
283 }
284
285
286
287
288 public void setModel(BitDescriptor model) {
289
290 getBitmask().setBitDescriptor(model);
291 setLeds();
292
293 }
294
295
296
297
298
299
300
301
302
303 public void setColumns(int col) {
304 columns=col;
305 }
306
307 public int getColumns() {
308 return columns;
309 }
310
311 private boolean isMaskSet() {
312 return getMask()>0;
313 }
314
315 public boolean isReverseLedsOrder() {
316 return reverseLedsOrder;
317 }
318
319 public void setReverseLedsOrder(boolean b) {
320 if(b == reverseLedsOrder) {
321 return;
322 }
323
324 boolean oldValue = reverseLedsOrder;
325 reverseLedsOrder = b;
326 firePropertyChange("reverseLedsOrder", oldValue, b);
327 setLeds();
328 }
329
330
331 private void updateLayout(){
332 SwingUtilities.invokeLater(new Runnable(){
333 public void run(){
334
335 _updateLayout();
336 _updateLeds();
337 }});
338
339 }
340
341 private void _updateLayout(){
342
343 if(getColumns()> 0){
344 if(leds != null){
345 setLayout(new java.awt.GridLayout(0,columns));
346 }
347 }
348
349 else{
350 if(leds != null){
351 int maxw = 0;
352 int maxh = 0;
353 for (int i = 0; i < leds.length; i++) {
354
355 Dimension d = leds[i].getPreferredSize();
356 maxw = Math.max(maxw, d.width);
357 maxh = Math.max(maxh, d.height);
358 }
359 int nCols = (int)Math.ceil(1.0*getWidth() / maxw);
360 nCols = Math.max(1, nCols);
361 int nRows = leds.length / nCols +1;
362 setLayout(new java.awt.GridLayout(nRows, nCols));
363
364 repaint();
365 doLayout();
366 }
367 }
368 }
369
370
371 private void _updateNoMaskLayout(){
372
373 removeAll();
374 setLayout(new BorderLayout());
375 add(maskNotSet);
376 doLayout();
377 repaint();
378
379
380 }
381
382 private void updateNoMaskLayout(){
383 SwingUtilities.invokeLater(new Runnable(){
384 public void run(){
385 _updateNoMaskLayout();
386 }
387 });
388 }
389
390 private void checkBits(int ledindex){
391 long bits = getBits();
392 boolean isLedAllreadyOn=false;
393 for(int i=0;i<ledindex;i++){
394 bits =bits >> 1;
395 }
396 if(bits%2==1){
397 isLedAllreadyOn = true;
398 }
399
400 if(isLedAllreadyOn==leds[ledindex].isOn()){
401
402 }else {
403
404
405
406 long addValueToBits=1;
407 long oldValue=getBits();
408 for (int i=0;i<ledindex;i++){
409 addValueToBits*=2;
410 }
411 if(isLedAllreadyOn){
412 getBitmask().setBits(getBits()-addValueToBits);
413 }else{
414 getBitmask().setBits(getBits()+addValueToBits);
415 }
416 firePropertyChange("bits",oldValue,getBits());
417 }
418
419 }
420
421 private void _updateBits(){
422
423 if(isEditable){
424 for(int i=0;i<leds.length;i++){
425 checkBits(i);
426 }
427 }
428
429 }
430
431
432
433 private void updateBits() {
434
435 SwingUtilities.invokeLater(new Runnable() {
436 public void run() {
437 _updateBits();
438 }
439 });
440 }
441
442 private void setLeds(){
443 SwingUtilities.invokeLater(new Runnable(){
444 public void run(){
445 _setLeds();
446 }
447 });
448 }
449
450 private void _setLeds(){
451 BitDescriptor lm = getModel();
452 int ledCount = getBitmask().getBitCount();
453 leds = new Led[ledCount];
454
455
456 for(int i=0; i<ledCount; i++){
457 leds[i]=new Led(
458 lm.getDescription(i),
459 lm.getColorWhenOn(i),
460 lm.getColorWhenOff(i));
461 leds[i].setEditable(isEditable);
462
463 leds[i].addMouseListener(new MouseAdapter(){
464 public void mouseClicked(MouseEvent e){
465 if(SwingUtilities.isLeftMouseButton(e)){
466 updateBits();
467 }
468 }});
469 }
470 Led[] l= leds;
471
472 if(getComponents() != null)
473 removeAll();
474
475
476 if(!isReverseLedsOrder()) {
477 for(int i=0; i<l.length; i++){
478 add(l[i]);
479 }
480 }else{
481 for (int i = l.length-1; i >= 0; i--)
482 add(l[i]);
483 }
484
485
486 repaint();
487 updateLayout();
488 }
489 }
490