1
17 package guk.im;
18
19 import java.awt.*;
20 import java.awt.event.*;
21 import java.util.*;
22
23 import javax.swing.*;
24 import javax.swing.border.*;
25
26
30 public class KeyboardMap implements Runnable{
31
32
40 public KeyboardMap(GateIM im, LocaleHandler handler, State state){
41 this.im = im;
42 this.handler = handler;
43 this.state = state;
44 jobs = Collections.synchronizedList(new ArrayList());
45 myThread = new Thread(Thread.currentThread().getThreadGroup(),
46 this);
47 myThread.start();
48 }
49
50
53 public void run(){
54 this.window = im.getContext().createInputMethodJFrame(null, true);
56 window.setTitle(handler.locale.getDisplayName() + " keyboard map");
57 window.setVisible(false);
58 window.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
59 window.addComponentListener(new ComponentAdapter(){
60 public void componentHidden(ComponentEvent e){
61 window.dispose();
62 }
63 });
64
65 window.getContentPane().setLayout(new GridLayout(1,1));
66 GridBagLayout layout = new GridBagLayout();
67 contentPane = new JPanel(layout);
68 contentPane.setDoubleBuffered(true);
69 window.getContentPane().add(contentPane, BorderLayout.CENTER);
70
71 labelForKey = new HashMap();
72 GUIforString = new HashMap();
73
74 double [] wheights = new double[45];
75 for(int i = 0; i < wheights.length; i++) wheights[i] = 0.001;
76 layout.columnWeights = wheights;
77 wheights = new double[5];
78 for(int i = 0; i < wheights.length; i++) wheights[i] = 0.001;
79 layout.rowWeights = wheights;
80
81 Map keyCap = handler.getKeyCap();
83 Iterator keyIter = keyCap.keySet().iterator();
84 Key currentKey;
85 JLabel currentLabel;
86 while(keyIter.hasNext()){
88 currentKey = (Key)keyIter.next();
89 currentLabel = new JLabel();
90 currentLabel.setFont(GateIM.getKeyboardFont());
92 currentLabel.setForeground(Color.black);
93 currentLabel.setText((String)keyCap.get(currentKey));
94 labelForKey.put(currentKey, currentLabel);
95 }
96 GUIforString = new HashMap();
98 KeyGUI currentGui;
99 int currentModifiers = 0;
100 if(ctrl) currentModifiers |= InputEvent.CTRL_MASK;
101 if(alt) currentModifiers |= InputEvent.ALT_MASK;
102 char ch;
103 String sKey;
104 for(ch = 'a'; ch <= 'z'; ch++){
105 sKey = "" + ch;
106 if(shift) currentKey = new Key(Character.toUpperCase(ch), currentModifiers);
107 else currentKey = new Key(ch, currentModifiers);
108 currentGui = new KeyGUI(sKey, ch, Character.toUpperCase(ch),
109 (JLabel)labelForKey.get(currentKey));
110 GUIforString.put(sKey, currentGui);
111 }
112 if(shift) ch = '!'; else ch = '1';
113 sKey = "1";
114 currentKey = new Key(ch, currentModifiers);
115 currentGui = new KeyGUI(sKey, '1', '!',(JLabel)labelForKey.get(currentKey));
116 GUIforString.put(sKey, currentGui);
117 if(shift) ch = '\"'; else ch = '2';
118 sKey = "2";
119 currentKey = new Key(ch, currentModifiers);
120 currentGui = new KeyGUI(sKey, '2', '\"',(JLabel)labelForKey.get(currentKey));
121 GUIforString.put(sKey, currentGui);
122 if(shift) ch = '\u00a3'; else ch = '3'; sKey = "3";
124 currentKey = new Key(ch, currentModifiers);
125 currentGui = new KeyGUI(sKey, '3', '\u00a3',(JLabel)labelForKey.get(currentKey)); GUIforString.put(sKey, currentGui);
127 if(shift) ch = '$'; else ch = '4';
128 sKey = "4";
129 currentKey = new Key(ch, currentModifiers);
130 currentGui = new KeyGUI(sKey, '4', '$',(JLabel)labelForKey.get(currentKey));
131 GUIforString.put(sKey, currentGui);
132 if(shift) ch = '%'; else ch = '5';
133 sKey = "5";
134 currentKey = new Key(ch, currentModifiers);
135 currentGui = new KeyGUI(sKey, '5', '%',(JLabel)labelForKey.get(currentKey));
136 GUIforString.put(sKey, currentGui);
137 if(shift) ch = '^'; else ch = '6';
138 sKey = "6";
139 currentKey = new Key(ch, currentModifiers);
140 currentGui = new KeyGUI(sKey, '6', '^',(JLabel)labelForKey.get(currentKey));
141 GUIforString.put(sKey, currentGui);
142 if(shift) ch = '&'; else ch = '7';
143 sKey = "7";
144 currentKey = new Key(ch, currentModifiers);
145 currentGui = new KeyGUI(sKey, '7', '&',(JLabel)labelForKey.get(currentKey));
146 GUIforString.put(sKey, currentGui);
147 if(shift) ch = '*'; else ch = '8';
148 sKey = "8";
149 currentKey = new Key(ch, currentModifiers);
150 currentGui = new KeyGUI(sKey, '8', '*',(JLabel)labelForKey.get(currentKey));
151 GUIforString.put(sKey, currentGui);
152 if(shift) ch = '('; else ch = '9';
153 sKey = "9";
154 currentKey = new Key(ch, currentModifiers);
155 currentGui = new KeyGUI(sKey, '9', '(',(JLabel)labelForKey.get(currentKey));
156 GUIforString.put(sKey, currentGui);
157 if(shift) ch = ')'; else ch = '0';
158 sKey = "0";
159 currentKey = new Key(ch, currentModifiers);
160 currentGui = new KeyGUI(sKey, '0', ')',(JLabel)labelForKey.get(currentKey));
161 GUIforString.put(sKey, currentGui);
162 if(shift) ch = '\u00ac'; else ch = '`'; sKey = "`";
164 currentKey = new Key(ch, currentModifiers);
165 currentGui = new KeyGUI(sKey, '`', '\u00ac',(JLabel)labelForKey.get(currentKey)); GUIforString.put(sKey, currentGui);
167 if(shift) ch = '_'; else ch = '-';
168 sKey = "-";
169 currentKey = new Key(ch, currentModifiers);
170 currentGui = new KeyGUI(sKey, '-', '_',(JLabel)labelForKey.get(currentKey));
171 GUIforString.put(sKey, currentGui);
172 if(shift) ch = '+'; else ch = '=';
173 sKey = "=";
174 currentKey = new Key(ch, currentModifiers);
175 currentGui = new KeyGUI(sKey, '=', '+',(JLabel)labelForKey.get(currentKey));
176 GUIforString.put(sKey, currentGui);
177 if(shift) ch = '{'; else ch = '[';
178 sKey = "[";
179 currentKey = new Key(ch, currentModifiers);
180 currentGui = new KeyGUI(sKey, '[', '{',(JLabel)labelForKey.get(currentKey));
181 GUIforString.put(sKey, currentGui);
182 if(shift) ch = '}'; else ch = ']';
183 sKey = "]";
184 currentKey = new Key(ch, currentModifiers);
185 currentGui = new KeyGUI(sKey, ']', '}',(JLabel)labelForKey.get(currentKey));
186 GUIforString.put(sKey, currentGui);
187 if(shift) ch = ':'; else ch = ';';
188 sKey = ";";
189 currentKey = new Key(ch, currentModifiers);
190 currentGui = new KeyGUI(sKey, ';', ':',(JLabel)labelForKey.get(currentKey));
191 GUIforString.put(sKey, currentGui);
192 if(shift) ch = '@'; else ch = '\'';
193 sKey = "'";
194 currentKey = new Key(ch, currentModifiers);
195 currentGui = new KeyGUI(sKey, '\'', '@',(JLabel)labelForKey.get(currentKey));
196 GUIforString.put(sKey, currentGui);
197 if(shift) ch = '~'; else ch = '#';
198 sKey = "#";
199 currentKey = new Key(ch, currentModifiers);
200 currentGui = new KeyGUI(sKey, '#', '~',(JLabel)labelForKey.get(currentKey));
201 GUIforString.put(sKey, currentGui);
202 if(shift) ch = '|'; else ch = '\\';
203 sKey = "\\";
204 currentKey = new Key(ch, currentModifiers);
205 currentGui = new KeyGUI(sKey, '\\', '|',(JLabel)labelForKey.get(currentKey));
206 GUIforString.put(sKey, currentGui);
207 if(shift) ch = '<'; else ch = ',';
208 sKey = ",";
209 currentKey = new Key(ch, currentModifiers);
210 currentGui = new KeyGUI(sKey, ',', '<',(JLabel)labelForKey.get(currentKey));
211 GUIforString.put(sKey, currentGui);
212 if(shift) ch = '>'; else ch = '.';
213 sKey = ".";
214 currentKey = new Key(ch, currentModifiers);
215 currentGui = new KeyGUI(sKey, '.', '>',(JLabel)labelForKey.get(currentKey));
216 GUIforString.put(sKey, currentGui);
217 if(shift) ch = '?'; else ch = '/';
218 sKey = "/";
219 currentKey = new Key(ch, currentModifiers);
220 currentGui = new KeyGUI(sKey, '/', '?',(JLabel)labelForKey.get(currentKey));
221 GUIforString.put(sKey, currentGui);
222
223 GUIforString.put("BACK_SPACE", new KeyGUI("BACK_SPACE", (char)0,(char)0,new JLabel("BackSpace")));
224 GUIforString.put("TAB", new KeyGUI("TAB", (char)0,(char)0,new JLabel("Tab")));
225 GUIforString.put("CAPS_LOCK", new KeyGUI("CAPS_LOCK", (char)0,(char)0,new JLabel("Caps Lock")));
226 GUIforString.put("ENTER", new KeyGUI("ENTER", (char)0, (char)0,new JLabel("Enter")));
227 GUIforString.put("LSHIFT", new KeyGUI("LSHIFT", (char)0,(char)0,new JLabel("Shift")));
228 GUIforString.put("RSHIFT", new KeyGUI("RSHIFT", (char)0,(char)0,new JLabel("Shift")));
229 GUIforString.put("LCTRL", new KeyGUI("LCTRL", (char)0,(char)0,new JLabel("Ctrl")));
230 GUIforString.put("RCTRL", new KeyGUI("RCTRL", (char)0,(char)0,new JLabel("Ctrl")));
231 GUIforString.put("LALT", new KeyGUI("LALT", (char)0,(char)0,new JLabel("Alt")));
232 GUIforString.put("RALT", new KeyGUI("RALT", (char)0,(char)0,new JLabel("Alt")));
233 GUIforString.put("SPACE", new KeyGUI("SPACE", ' ', ' ',new JLabel(" ")));
234
235 GridBagConstraints constraints = new GridBagConstraints();
237 constraints.fill = GridBagConstraints.BOTH;
238 constraints.gridwidth = 3;
239 contentPane.add((Component)GUIforString.get("`"), constraints);
240 contentPane.add((Component)GUIforString.get("1"), constraints);
241 contentPane.add((Component)GUIforString.get("2"), constraints);
242 contentPane.add((Component)GUIforString.get("3"), constraints);
243 contentPane.add((Component)GUIforString.get("4"), constraints);
244 contentPane.add((Component)GUIforString.get("5"), constraints);
245 contentPane.add((Component)GUIforString.get("6"), constraints);
246 contentPane.add((Component)GUIforString.get("7"), constraints);
247 contentPane.add((Component)GUIforString.get("8"), constraints);
248 contentPane.add((Component)GUIforString.get("9"), constraints);
249 contentPane.add((Component)GUIforString.get("0"), constraints);
250 contentPane.add((Component)GUIforString.get("-"), constraints);
251 contentPane.add((Component)GUIforString.get("="), constraints);
252 constraints.gridwidth = 6;
253 contentPane.add((Component)GUIforString.get("BACK_SPACE"), constraints);
254 constraints.gridy = 1;
256 constraints.gridwidth = 5;
257 contentPane.add((Component)GUIforString.get("TAB"), constraints);
258 constraints.gridwidth = 3;
259 contentPane.add((Component)GUIforString.get(""+'q'), constraints);
260 contentPane.add((Component)GUIforString.get(""+'w'), constraints);
261 contentPane.add((Component)GUIforString.get(""+'e'), constraints);
262 contentPane.add((Component)GUIforString.get(""+'r'), constraints);
263 contentPane.add((Component)GUIforString.get(""+'t'), constraints);
264 contentPane.add((Component)GUIforString.get(""+'y'), constraints);
265 contentPane.add((Component)GUIforString.get(""+'u'), constraints);
266 contentPane.add((Component)GUIforString.get(""+'i'), constraints);
267 contentPane.add((Component)GUIforString.get(""+'o'), constraints);
268 contentPane.add((Component)GUIforString.get(""+'p'), constraints);
269 contentPane.add((Component)GUIforString.get(""+'['), constraints);
270 contentPane.add((Component)GUIforString.get(""+']'), constraints);
271 constraints.gridwidth = 4;
272 contentPane.add((Component)GUIforString.get(""+'\\'), constraints);
273 constraints.gridy = 2;
275 constraints.gridwidth = 6;
276 contentPane.add((Component)GUIforString.get("CAPS_LOCK"), constraints);
277 constraints.gridwidth = 3;
278 contentPane.add((Component)GUIforString.get("a"), constraints);
279 contentPane.add((Component)GUIforString.get(""+'s'), constraints);
280 contentPane.add((Component)GUIforString.get(""+'d'), constraints);
281 contentPane.add((Component)GUIforString.get(""+'f'), constraints);
282 contentPane.add((Component)GUIforString.get(""+'g'), constraints);
283 contentPane.add((Component)GUIforString.get(""+'h'), constraints);
284 contentPane.add((Component)GUIforString.get(""+'j'), constraints);
285 contentPane.add((Component)GUIforString.get(""+'k'), constraints);
286 contentPane.add((Component)GUIforString.get(""+'l'), constraints);
287 contentPane.add((Component)GUIforString.get(""+';'), constraints);
288 contentPane.add((Component)GUIforString.get("'"), constraints);
289 constraints.gridwidth = 6;
290 contentPane.add((Component)GUIforString.get("ENTER"), constraints);
291 constraints.gridy = 3;
293 constraints.gridwidth = 5;
294 contentPane.add((Component)GUIforString.get("LSHIFT"), constraints);
295 constraints.gridwidth = 3;
296 contentPane.add((Component)GUIforString.get(""+'z'), constraints);
297 contentPane.add((Component)GUIforString.get(""+'x'), constraints);
298 contentPane.add((Component)GUIforString.get(""+'c'), constraints);
299 contentPane.add((Component)GUIforString.get(""+'v'), constraints);
300 contentPane.add((Component)GUIforString.get(""+'b'), constraints);
301 contentPane.add((Component)GUIforString.get(""+'n'), constraints);
302 contentPane.add((Component)GUIforString.get(""+'m'), constraints);
303 contentPane.add((Component)GUIforString.get(""+','), constraints);
304 contentPane.add((Component)GUIforString.get(""+'.'), constraints);
305 contentPane.add((Component)GUIforString.get(""+'/'), constraints);
306 contentPane.add((Component)GUIforString.get(""+'#'), constraints);
307 constraints.gridwidth = 8;
308 contentPane.add((Component)GUIforString.get("RSHIFT"), constraints);
309 constraints.gridy = 4;
311 constraints.gridwidth = 5;
312 contentPane.add((Component)GUIforString.get("LCTRL"), constraints);
313 contentPane.add((Component)GUIforString.get("LALT"), constraints);
314 constraints.gridwidth = 25;
315 contentPane.add((Component)GUIforString.get("SPACE"), constraints);
316 constraints.gridwidth = 5;
317 contentPane.add((Component)GUIforString.get("RALT"), constraints);
318 contentPane.add((Component)GUIforString.get("RCTRL"), constraints);
319 window.pack();
320
321 if(im.mapVisible) window.setVisible(true);
322
323 infinite:while(true){
326 synchronized(jobs){
327 try{
328 if(!jobs.isEmpty()){
329 while(!jobs.isEmpty()){
331 Object job = jobs.remove(0);
332 if(job instanceof String){
334 String sJob = (String)job;
336 if(sJob.equalsIgnoreCase("DIE")) break infinite;
338 else if(sJob.equalsIgnoreCase("HIDE") && window.isShowing()){
339 window.setVisible(false);
340 }else if(sJob.equalsIgnoreCase("SHOW") && (!window.isShowing())){
341 window.setVisible(true);
342 }else if(sJob.equalsIgnoreCase("UPDATE")) update();
343 }else if(job instanceof KeyEvent){
344 int code;
346 KeyEvent kEvent = (KeyEvent)job;
347 KeyGUI someGui;
348 if(kEvent.getID() == KeyEvent.KEY_PRESSED){
349 code = kEvent.getKeyCode();
350 switch(code){
351 case KeyEvent.VK_SHIFT: {
352 if(!shift) {
353 shift = true;
354 ((KeyGUI)GUIforString.get("LSHIFT")).pressKey();
355 ((KeyGUI)GUIforString.get("RSHIFT")).pressKey();
356 updateLabels();
357 }
358 break;
359 }
360 case KeyEvent.VK_CONTROL:{
361 if(!ctrl){
362 ctrl = true;
363 ((KeyGUI)GUIforString.get("LCTRL")).pressKey();
364 ((KeyGUI)GUIforString.get("RCTRL")).pressKey();
365 updateLabels();
366 }
367 break;
368 }
369 case KeyEvent.VK_ALT:{
370 if(!alt){
371 alt = true;
372 ((KeyGUI)GUIforString.get("LALT")).pressKey();
373 ((KeyGUI)GUIforString.get("RALT")).pressKey();
374 updateLabels();
375 }
376 break;
377 }
378 case KeyEvent.VK_CAPS_LOCK:{
379 someGui = (KeyGUI)GUIforString.get("CAPS_LOCK");
380 someGui.pressKey();
381 break;
382 }
383 case KeyEvent.VK_BACK_SPACE:{
384 someGui = (KeyGUI)GUIforString.get("BACK_SPACE");
385 someGui.pressKey();
386 break;
387 }
388 case KeyEvent.VK_ENTER:{
389 someGui = (KeyGUI)GUIforString.get("ENTER");
390 someGui.pressKey();
391 break;
392 }
393 case KeyEvent.VK_TAB:{
394 someGui = (KeyGUI)GUIforString.get("TAB");
395 someGui.pressKey();
396 break;
397 }
398 case KeyEvent.VK_SPACE:{
399 someGui = (KeyGUI)GUIforString.get("SPACE");
400 someGui.pressKey();
401 break;
402 }
403 default:{
404 String key = "";
405 char keyCh = kEvent.getKeyChar();
406 if('a' <= keyCh && keyCh <= 'z'){
407 key += keyCh;
408 }else if('A' <= keyCh && keyCh <= 'Z'){
409 key += Character.toLowerCase(keyCh);
410 }else{
411 switch(keyCh){
412 case '`':{
413 key += keyCh;
414 break;
415 }
416 case '1':{
417 key += keyCh;
418 break;
419 }
420 case '2':{
421 key += keyCh;
422 break;
423 }
424 case '3':{
425 key += keyCh;
426 break;
427 }
428 case '4':{
429 key += keyCh;
430 break;
431 }
432 case '5':{
433 key += keyCh;
434 break;
435 }
436 case '6':{
437 key += keyCh;
438 break;
439 }
440 case '7':{
441 key += keyCh;
442 break;
443 }
444 case '8':{
445 key += keyCh;
446 break;
447 }
448 case '9':{
449 key += keyCh;
450 break;
451 }
452 case '0':{
453 key += keyCh;
454 break;
455 }
456 case '-':{
457 key += keyCh;
458 break;
459 }
460 case '=':{
461 key += keyCh;
462 break;
463 }
464 case '[':{
465 key += keyCh;
466 break;
467 }
468 case ']':{
469 key += keyCh;
470 break;
471 }
472 case ';':{
473 key += keyCh;
474 break;
475 }
476 case '\'':{
477 key += keyCh;
478 break;
479 }
480 case '#':{
481 key += keyCh;
482 break;
483 }
484 case '\\':{
485 key += keyCh;
486 break;
487 }
488 case ',':{
489 key += keyCh;
490 break;
491 }
492 case '.':{
493 key += keyCh;
494 break;
495 }
496 case '/':{
497 key += keyCh;
498 break;
499 }
500
501
502 case '\u00ac':{ key += '`';
504 break;
505 }
506 case '!':{
507 key += '1';
508 break;
509 }
510 case '\"':{
511 key += '2';
512 break;
513 }
514 case '\u00a3':{ key += '3';
516 break;
517 }
518 case '$':{
519 key += '4';
520 break;
521 }
522 case '%':{
523 key += '5';
524 break;
525 }
526 case '^':{
527 key += '6';
528 break;
529 }
530 case '&':{
531 key += '7';
532 break;
533 }
534 case '*':{
535 key += '8';
536 break;
537 }
538 case '(':{
539 key += '9';
540 break;
541 }
542 case ')':{
543 key += '0';
544 break;
545 }
546 case '_':{
547 key += '-';
548 break;
549 }
550 case '+':{
551 key += '=';
552 break;
553 }
554 case '{':{
555 key += '[';
556 break;
557 }
558 case '}':{
559 key += ']';
560 break;
561 }
562 case ':':{
563 key += ';';
564 break;
565 }
566 case '@':{
567 key += '\'';
568 break;
569 }
570 case '~':{
571 key += '#';
572 break;
573 }
574 case '|':{
575 key += '\\';
576 break;
577 }
578 case '<':{
579 key += ',';
580 break;
581 }
582 case '>':{
583 key += '.';
584 break;
585 }
586 case '?':{
587 key += '/';
588 break;
589 }
590 } }
592 someGui = (KeyGUI)GUIforString.get(key);
593 if(someGui != null){
594 someGui.pressKey();
595 }
596 } } }else if(kEvent.getID() == KeyEvent.KEY_RELEASED){
599 code = kEvent.getKeyCode();
600 switch(code){
601 case KeyEvent.VK_SHIFT: {
602 if(shift) {
603 shift = false;
604 ((KeyGUI)GUIforString.get("LSHIFT")).releaseKey();
605 ((KeyGUI)GUIforString.get("RSHIFT")).releaseKey();
606 updateLabels();
607 }
608 break;
609 }
610 case KeyEvent.VK_CONTROL:{
611 if(ctrl){
612 ctrl = false;
613 ((KeyGUI)GUIforString.get("LCTRL")).releaseKey();
614 ((KeyGUI)GUIforString.get("RCTRL")).releaseKey();
615 updateLabels();
616 }
617 break;
618 }
619 case KeyEvent.VK_ALT:{
620 if(alt){
621 alt = false;
622 ((KeyGUI)GUIforString.get("LALT")).releaseKey();
623 ((KeyGUI)GUIforString.get("RALT")).releaseKey();
624 updateLabels();
625 }
626 break;
627 }
628 case KeyEvent.VK_CAPS_LOCK:{
629 someGui = (KeyGUI)GUIforString.get("CAPS_LOCK");
630 someGui.releaseKey();
631 break;
632 }
633 case KeyEvent.VK_BACK_SPACE:{
634 someGui = (KeyGUI)GUIforString.get("BACK_SPACE");
635 someGui.releaseKey();
636 break;
637 }
638 case KeyEvent.VK_ENTER:{
639 someGui = (KeyGUI)GUIforString.get("ENTER");
640 someGui.releaseKey();
641 break;
642 }
643 case KeyEvent.VK_TAB:{
644 someGui = (KeyGUI)GUIforString.get("TAB");
645 someGui.releaseKey();
646 break;
647 }
648 case KeyEvent.VK_SPACE:{
649 someGui = (KeyGUI)GUIforString.get("SPACE");
650 someGui.releaseKey();
651 break;
652 }
653 default:{
654 String key = "";
655 char keyCh = kEvent.getKeyChar();
656 if('a' <= keyCh && keyCh <= 'z'){
657 key += keyCh;
658 }else if('A' <= keyCh && keyCh <= 'Z'){
659 key += Character.toLowerCase(keyCh);
660 }else{
661 switch(keyCh){
662 case '`':{
663 key += keyCh;
664 break;
665 }
666 case '1':{
667 key += keyCh;
668 break;
669 }
670 case '2':{
671 key += keyCh;
672 break;
673 }
674 case '3':{
675 key += keyCh;
676 break;
677 }
678 case '4':{
679 key += keyCh;
680 break;
681 }
682 case '5':{
683 key += keyCh;
684 break;
685 }
686 case '6':{
687 key += keyCh;
688 break;
689 }
690 case '7':{
691 key += keyCh;
692 break;
693 }
694 case '8':{
695 key += keyCh;
696 break;
697 }
698 case '9':{
699 key += keyCh;
700 break;
701 }
702 case '0':{
703 key += keyCh;
704 break;
705 }
706 case '-':{
707 key += keyCh;
708 break;
709 }
710 case '=':{
711 key += keyCh;
712 break;
713 }
714 case '[':{
715 key += keyCh;
716 break;
717 }
718 case ']':{
719 key += keyCh;
720 break;
721 }
722 case ';':{
723 key += keyCh;
724 break;
725 }
726 case '\'':{
727 key += keyCh;
728 break;
729 }
730 case '#':{
731 key += keyCh;
732 break;
733 }
734 case '\\':{
735 key += keyCh;
736 break;
737 }
738 case ',':{
739 key += keyCh;
740 break;
741 }
742 case '.':{
743 key += keyCh;
744 break;
745 }
746 case '/':{
747 key += keyCh;
748 break;
749 }
750
751 case '\u00ac':{ key += '`';
753 break;
754 }
755 case '!':{
756 key += '1';
757 break;
758 }
759 case '\"':{
760 key += '2';
761 break;
762 }
763 case '\u00a3':{ key += '3';
765 break;
766 }
767 case '$':{
768 key += '4';
769 break;
770 }
771 case '%':{
772 key += '5';
773 break;
774 }
775 case '^':{
776 key += '6';
777 break;
778 }
779 case '&':{
780 key += '7';
781 break;
782 }
783 case '*':{
784 key += '8';
785 break;
786 }
787 case '(':{
788 key += '9';
789 break;
790 }
791 case ')':{
792 key += '0';
793 break;
794 }
795 case '_':{
796 key += '-';
797 break;
798 }
799 case '+':{
800 key += '=';
801 break;
802 }
803 case '{':{
804 key += '[';
805 break;
806 }
807 case '}':{
808 key += ']';
809 break;
810 }
811 case ':':{
812 key += ';';
813 break;
814 }
815 case '@':{
816 key += '\'';
817 break;
818 }
819 case '~':{
820 key += '#';
821 break;
822 }
823 case '|':{
824 key += '\\';
825 break;
826 }
827 case '<':{
828 key += ',';
829 break;
830 }
831 case '>':{
832 key += '.';
833 break;
834 }
835 case '?':{
836 key += '/';
837 break;
838 }
839 } }
841 someGui = (KeyGUI)GUIforString.get(key);
842 if(someGui != null){
843 someGui.releaseKey();
844 }
845 } } }
848 }
852 }
853 }
854 }catch(Exception e){}
855 jobs.notifyAll();
856 } try{
859 Thread.sleep(150);
860 }catch(InterruptedException ie){
861 ie.printStackTrace();
862 }
863 }
865 }
866
867
882 public void addJob(Object job){
883 synchronized(jobs){
884 jobs.add(job);
885 jobs.notifyAll();
886 }
887 }
888
889
897 public void update(LocaleHandler newHandler, State newState){
898 if(newHandler == handler && newState == state) return;
900 this.newHandler = newHandler;
901 this.newState = newState;
902 addJob("UPDATE");
903 }
904
905
908 protected void update(){
909 if(newHandler != handler){
911 handler = newHandler;
912 state = newState;
913 window.setTitle(handler.locale.getDisplayLanguage() + " (" +
914 handler.locale.getVariant() + ") keyboard map");
915 labelForKey.clear();
917 Map keyCap = handler.getKeyCap();
918 Iterator keyIter = keyCap.keySet().iterator();
919 Key currentKey;
920 JLabel currentLabel;
921 while(keyIter.hasNext()){
923 currentKey = (Key)keyIter.next();
924 currentLabel = new JLabel();
925 currentLabel.setFont(GateIM.getKeyboardFont());
926 currentLabel.setText((String)keyCap.get(currentKey));
928 labelForKey.put(currentKey, currentLabel);
929 }
930 updateLabels();
931 }
932 if(newState != state){
934 state = newState;
936 Iterator keysIter = highlightedKeys.iterator();
938 while(keysIter.hasNext()) ((KeyGUI)keysIter.next()).unHighlight();
939 highlightedKeys.clear();
940
941 if(state != handler.getInitialState()){
943 keysIter = state.transitionFunction.keySet().iterator();
944 KeyGUI someGui;
945 while(keysIter.hasNext()){
946 someGui = guiForKey((Key)keysIter.next());
947 if(someGui != null){
948 someGui.highlight();
949 highlightedKeys.add(someGui);
950 }
951 }
952 }
953 }
954 }
955
956
959 protected void updateLabels(){
960 Component[] components = contentPane.getComponents();
962 for(int i = 0; i <components.length; i++){
963 if(components[i] instanceof KeyGUI) ((KeyGUI)components[i]).updateLabel();
964 }
965 fixShape();
966 }
967
968
969 protected void fixShape(){
970 int [][] sizes = ((GridBagLayout)contentPane.getLayout()).getLayoutDimensions();
972 ((GridBagLayout)contentPane.getLayout()).columnWidths = sizes[0];
974 ((GridBagLayout)contentPane.getLayout()).rowHeights = sizes[1];
975 window.pack();
976 contentPane.repaint(100);
977 }
978
983 protected KeyGUI guiForKey(Key key){
984 char ch = key.keyChar;
985 boolean shiftOn = false;
986 if(Character.isUpperCase(ch)){
987 ch = Character.toLowerCase(ch);
988 shiftOn = true;
989 }
990 boolean ctrlOn = (key.modifiers & KeyEvent.CTRL_MASK) > 0;
991 boolean altOn = (key.modifiers & KeyEvent.ALT_MASK) > 0;
992 if(shift == shiftOn &&
993 ctrl == ctrlOn &&
994 alt == altOn){
995 return (KeyGUI)GUIforString.get("" + ch);
996 }
997 return null;
998 }
999
1004 public void setShift(boolean shift){
1005 this.shift = shift;
1006 }
1007
1008
1013 public void setAlt(boolean alt){
1014 this.alt = alt;
1015 }
1016
1017
1022 public void setCtrl(boolean ctrl){
1023 this.ctrl = ctrl;
1024 }
1025
1026
1028
1032 LocaleHandler handler;
1033
1037 LocaleHandler newHandler;
1038
1039
1043 State state;
1044
1050 State newState;
1051
1054 JFrame window;
1055
1060 JPanel contentPane;
1061
1062
1065 java.util.List highlightedKeys = new ArrayList();
1066
1067
1068 boolean shift = false, ctrl = false, alt = false, capslock = false;
1069
1072 Map GUIforString;
1073
1078 Map labelForKey;
1079
1080
1083 GateIM im;
1084
1085
1088 Thread myThread;
1089
1090
1093 java.util.List jobs;
1094 public class KeyGUI extends JPanel {
1096
1097 Box leftBox;
1098
1099 JLabel leftUpLabel = new JLabel();
1100
1101 JLabel leftDownLabel = new JLabel();
1102
1103 Component centerLabel;
1104
1105 char low, up;
1106
1107 Border normalBorder, highlightedBorder;
1108
1109
1119 public KeyGUI(String key, char englishLow, char englishUp,
1120 JLabel center) {
1121 this.setBackground(Color.lightGray);
1122 low = englishLow;
1123 up = englishUp;
1124 leftBox = Box.createVerticalBox();
1125 Dimension dim;
1126 if(englishUp > (char)0){
1127 leftUpLabel.setFont(leftUpLabel.getFont().deriveFont((float)10));
1128 leftUpLabel.setText("" + englishUp);
1129 leftBox.add(leftUpLabel);
1130 }else{
1131 leftBox.add(placeHolder);
1132 }
1133 if(englishLow > (char)0){
1134 leftDownLabel.setFont(leftDownLabel.getFont().deriveFont((float)10));
1135 leftDownLabel.setText("" + englishLow);
1136 leftBox.add(leftDownLabel);
1137 }else{
1138 leftBox.add(placeHolder);
1139 }
1140 leftBox.add(Box.createVerticalGlue());
1141 if(center == null) centerLabel = placeHolder;
1142 else centerLabel = center;
1143 this.setLayout(new BoxLayout(this,BoxLayout.X_AXIS));
1144 this.add(leftBox);
1145 this.add(Box.createHorizontalGlue());
1146 this.add(centerLabel);
1147 normalBorder = new CompoundBorder(new BevelBorder(BevelBorder.RAISED),
1148 new EmptyBorder(2,3,2,3));
1149 highlightedBorder = new CompoundBorder(new BevelBorder(BevelBorder.RAISED),
1150 new MatteBorder(2,3,2,3, Color.green));
1151
1152 this.setBorder(normalBorder);
1153 addMouseListener(new MouseAdapter(){
1154
1157 public void mouseClicked(MouseEvent e){
1158 int modifiers = 0;
1159 if(ctrl) modifiers |= KeyEvent.CTRL_MASK;
1160 if(alt) modifiers |= KeyEvent.ALT_MASK;
1161 char ch;
1162 if(shift) ch = up;
1163 else ch = low;
1164 if(ch != 0){
1165 im.dispatchEvent(new KeyEvent(window, KeyEvent.KEY_TYPED,
1166 System.currentTimeMillis(),
1167 modifiers, KeyEvent.VK_UNDEFINED, ch));
1168 }
1169 }
1170
1171 public void mousePressed(MouseEvent e){
1172 char ch;
1173 if(shift) ch = up;
1174 else ch = low;
1175 if(ch != 0){
1176 pressKey();
1177 }
1179 }
1180
1181 public void mouseReleased(MouseEvent e){
1182 char ch;
1183 if(shift) ch = up;
1184 else ch = low;
1185 if(ch != 0){
1186 releaseKey();
1187 }
1189 }
1190 });
1191 }
1192
1193
1194 public void updateLabel(){
1195 if(low == (char)0 || up == (char)0)return;
1196 remove(centerLabel);
1197 Key key;
1198 int modifiers = 0;
1199 if(ctrl) modifiers |= InputEvent.CTRL_MASK;
1200 if(alt) modifiers |= InputEvent.ALT_MASK;
1201 if(shift) key = new Key(up, modifiers);
1202 else key = new Key(low, modifiers);
1203 centerLabel = (JLabel)labelForKey.get(key);
1204 if(centerLabel == null) centerLabel = placeHolder;
1205 this.add(centerLabel);
1206 }
1208
1209
1212 public void pressKey(){
1213 this.setBackground(Color.darkGray);
1214 }
1215
1216
1219 public void releaseKey(){
1220 this.setBackground(Color.lightGray);
1221 }
1222
1223
1226 public void highlight(){
1227 setBorder(highlightedBorder);
1228 }
1229
1230
1233 public void unHighlight(){
1234 setBorder(normalBorder);
1235 }
1236
1237 }
1239
1240
1241
1244 static Component placeHolder = Box.createRigidArea(new Dimension(12, 12));
1245}