|
KeyboardMap |
|
1 /* 2 * KeyboardMap.java 3 * 4 * Copyright (c) 2000-2001, The University of Sheffield. 5 * 6 * This file is part of GATE (see http://gate.ac.uk/), and is free 7 * software, licenced under the GNU Library General Public License, 8 * Version 2, June1991. 9 * 10 * A copy of this licence is included in the distribution in the file 11 * licence.html, and is also available at http://gate.ac.uk/gate/licence.html. 12 * 13 * Valentin Tablan, October 2000 14 * 15 * $Id: KeyboardMap.java,v 1.3 2001/05/09 11:08:28 valyt Exp $ 16 */ 17 package guk.im; 18 19 import java.awt.*; 20 import java.awt.event.*; 21 import java.util.*; 22 import javax.swing.*; 23 import javax.swing.border.*; 24 import javax.swing.plaf.LabelUI; 25 26 import guk.*; 27 28 /** 29 * A virtual keyboard map. It uses its own thread do udate the display. 30 * 31 */ 32 public class KeyboardMap implements Runnable{ 33 34 /** 35 * Builds the keyboard map. Uses a window provided by the context of the input 36 * method. 37 * 38 * @param im the input method 39 * @param handler the active Locale handler 40 * @param state the state of the handler. 41 */ 42 public KeyboardMap(GateIM im, LocaleHandler handler, State state){ 43 this.im = im; 44 this.handler = handler; 45 this.state = state; 46 jobs = Collections.synchronizedList(new ArrayList()); 47 myThread = new Thread(Thread.currentThread().getThreadGroup(), 48 this); 49 myThread.start(); 50 } 51 52 /** 53 * The run method for the thread responsible for updating the display. 54 */ 55 public void run(){ 56 //do all the initialisations 57 this.window = im.getContext().createInputMethodWindow(null, true); 58 if(window instanceof Frame) ((Frame)window).setTitle( 59 handler.locale.getDisplayName() + 60 " keyboard map"); 61 window.setVisible(false); 62 window.addWindowListener(new WindowAdapter(){ 63 64 }); 65 window.setLayout(new GridLayout(1,1)); 66 GridBagLayout layout = new GridBagLayout(); 67 contentPane = new JPanel(layout); 68 contentPane.setDoubleBuffered(true); 69 window.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 //read keycaps 82 Map keyCap = handler.getKeyCap(); 83 Iterator keyIter = keyCap.keySet().iterator(); 84 Key currentKey; 85 JLabel currentLabel; 86 //LabelUI uLabelUI = new BasicUnicodeLabelUI(GateIM.getFontSet()); 87 while(keyIter.hasNext()){ 88 currentKey = (Key)keyIter.next(); 89 currentLabel = new JLabel(); 90 //currentLabel.setUI(uLabelUI); 91 currentLabel.setFont(GateIM.getKeyboardFont()); 92 currentLabel.setForeground(Color.black); 93 currentLabel.setText((String)keyCap.get(currentKey)); 94 labelForKey.put(currentKey, currentLabel); 95 } 96 //build the guis 97 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 = '£'; else ch = '3'; 123 sKey = "3"; 124 currentKey = new Key(ch, currentModifiers); 125 currentGui = new KeyGUI(sKey, '3', '£',(JLabel)labelForKey.get(currentKey)); 126 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 = '¬'; else ch = '`'; 163 sKey = "`"; 164 currentKey = new Key(ch, currentModifiers); 165 currentGui = new KeyGUI(sKey, '`', '¬',(JLabel)labelForKey.get(currentKey)); 166 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 //add the components to the window 236 GridBagConstraints constraints = new GridBagConstraints(); 237 constraints.fill = constraints.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 //second line 255 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 //line 3 274 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 //line 4 292 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 //line 5 310 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 //initialisations done 324 //wait for jobs to do 325 infinite:while(true){ 326 synchronized(jobs){ 327 try{ 328 if(!jobs.isEmpty()){ 329 //do the jobs in the job list 330 while(!jobs.isEmpty()){ 331 Object job = jobs.remove(0); 332 //do job 333 if(job instanceof String){ 334 //job is a command 335 String sJob = (String)job; 336 //should we die? :( 337 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 //job is an key event 345 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 '¬':{ 503 key += '`'; 504 break; 505 } 506 case '!':{ 507 key += '1'; 508 break; 509 } 510 case '\"':{ 511 key += '2'; 512 break; 513 } 514 case '£':{ 515 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 }//switch 591 } 592 someGui = (KeyGUI)GUIforString.get(key); 593 if(someGui != null){ 594 someGui.pressKey(); 595 } 596 }//default 597 }//switch 598 }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 752 case '¬':{ 753 key += '`'; 754 break; 755 } 756 case '!':{ 757 key += '1'; 758 break; 759 } 760 case '\"':{ 761 key += '2'; 762 break; 763 } 764 case '£':{ 765 key += '3'; 766 break; 767 } 768 case '$':{ 769 key += '4'; 770 break; 771 } 772 case '%':{ 773 key += '5'; 774 break; 775 } 776 case '^':{ 777 key += '6'; 778 break; 779 } 780 case '&':{ 781 key += '7'; 782 break; 783 } 784 case '*':{ 785 key += '8'; 786 break; 787 } 788 case '(':{ 789 key += '9'; 790 break; 791 } 792 case ')':{ 793 key += '0'; 794 break; 795 } 796 case '_':{ 797 key += '-'; 798 break; 799 } 800 case '+':{ 801 key += '='; 802 break; 803 } 804 case '{':{ 805 key += '['; 806 break; 807 } 808 case '}':{ 809 key += ']'; 810 break; 811 } 812 case ':':{ 813 key += ';'; 814 break; 815 } 816 case '@':{ 817 key += '\''; 818 break; 819 } 820 case '~':{ 821 key += '#'; 822 break; 823 } 824 case '|':{ 825 key += '\\'; 826 break; 827 } 828 case '<':{ 829 key += ','; 830 break; 831 } 832 case '>':{ 833 key += '.'; 834 break; 835 } 836 case '?':{ 837 key += '/'; 838 break; 839 } 840 }//switch 841 } 842 someGui = (KeyGUI)GUIforString.get(key); 843 if(someGui != null){ 844 someGui.releaseKey(); 845 } 846 }//default 847 }//switch 848 } 849 //update the state so the rebuildGui will update the highlights 850 // state = im.currentState; 851 // update(); 852 } 853 } 854 } 855 }catch(Exception e){} 856 jobs.notifyAll(); 857 }//synchronized(jobs); 858 //no more jobs, take a nap :) 859 try{ 860 myThread.sleep(150); 861 }catch(InterruptedException ie){ 862 ie.printStackTrace(); 863 } 864 }//infinite: while(true) 865 866 } 867 868 /** 869 * Adds a job to the job list of the thread. 870 * A job is either a {@link java.lang.String} or an {@link java.awt.event.InputEvent} 871 * The string can be one of 872 * <ul> 873 * <li>SHOW: shows the keyboard map window 874 * <li>UPDATE updates the keyboard map window 875 * <li>HIDE: hides the keyboard map window 876 * <li>DIE: releases all the memory and terminates the thread 877 * </ul> 878 * 879 * The input events refer to pressed keys and are treated accordingly. 880 * 881 * @param job 882 */ 883 public void addJob(Object job){ 884 synchronized(jobs){ 885 jobs.add(job); 886 jobs.notifyAll(); 887 } 888 } 889 890 /** 891 * Updates the keyboard map for a new Locale or a new state of the current locale handler. 892 * Currently the state changes are ignored. 893 * This method delegates its job to the thread which will do the actual 894 * update. 895 * @param newHandler 896 * @param newState 897 */ 898 public void update(LocaleHandler newHandler, State newState){ 899 //did anything changed? 900 if(newHandler == handler && newState == state) return; 901 this.newHandler = newHandler; 902 this.newState = newState; 903 addJob("UPDATE"); 904 } 905 906 /** 907 * Does th actual update. 908 */ 909 protected void update(){ 910 //did the locale changed? 911 if(newHandler != handler){ 912 handler = newHandler; 913 state = newState; 914 if(window instanceof Frame) ((Frame)window).setTitle( 915 handler.locale.getDisplayLanguage() + " (" + 916 handler.locale.getVariant() + ") keyboard map"); 917 //read keycaps 918 labelForKey.clear(); 919 Map keyCap = handler.getKeyCap(); 920 Iterator keyIter = keyCap.keySet().iterator(); 921 Key currentKey; 922 JLabel currentLabel; 923 //LabelUI uLabelUI = new BasicUnicodeLabelUI(GateIM.getFontSet()); 924 while(keyIter.hasNext()){ 925 currentKey = (Key)keyIter.next(); 926 currentLabel = new JLabel(); 927 currentLabel.setFont(GateIM.getKeyboardFont()); 928 //currentLabel.setUI(uLabelUI); 929 currentLabel.setText((String)keyCap.get(currentKey)); 930 labelForKey.put(currentKey, currentLabel); 931 } 932 updateLabels(); 933 } 934 //did the state changed? 935 if(newState != state){ 936 //highlight the allowed keys 937 state = newState; 938 //un-highlight the highlighted keys 939 Iterator keysIter = highlightedKeys.iterator(); 940 while(keysIter.hasNext()) ((KeyGUI)keysIter.next()).unHighlight(); 941 highlightedKeys.clear(); 942 943 //if not initial state highlight the allowed keys 944 if(state != handler.getInitialState()){ 945 keysIter = state.transitionFunction.keySet().iterator(); 946 KeyGUI someGui; 947 while(keysIter.hasNext()){ 948 someGui = guiForKey((Key)keysIter.next()); 949 if(someGui != null){ 950 someGui.highlight(); 951 highlightedKeys.add(someGui); 952 } 953 } 954 } 955 } 956 } 957 958 /** 959 * Updates the virtual keyboard to reflect the current state. 960 */ 961 protected void updateLabels(){ 962 //update the labels 963 Component[] components = contentPane.getComponents(); 964 for(int i = 0; i <components.length; i++){ 965 if(components[i] instanceof KeyGUI) ((KeyGUI)components[i]).updateLabel(); 966 } 967 fixShape(); 968 } 969 970 /** */ 971 protected void fixShape(){ 972 //get the current sizes 973 int [][] sizes = ((GridBagLayout)contentPane.getLayout()).getLayoutDimensions(); 974 //override the minimum sizes 975 ((GridBagLayout)contentPane.getLayout()).columnWidths = sizes[0]; 976 ((GridBagLayout)contentPane.getLayout()).rowHeights = sizes[1]; 977 window.pack(); 978 contentPane.repaint(100); 979 } 980 /** 981 * Gets the gui that corresponds to a Key object. 982 * 983 * @param key 984 */ 985 protected KeyGUI guiForKey(Key key){ 986 char ch = key.keyChar; 987 boolean shiftOn = false; 988 if(Character.isUpperCase(ch)){ 989 ch = Character.toLowerCase(ch); 990 shiftOn = true; 991 } 992 boolean ctrlOn = (key.modifiers & KeyEvent.CTRL_MASK) > 0; 993 boolean altOn = (key.modifiers & KeyEvent.ALT_MASK) > 0; 994 if(shift == shiftOn && 995 ctrl == ctrlOn && 996 alt == altOn){ 997 return (KeyGUI)GUIforString.get("" + ch); 998 } 999 return null; 1000 } 1001 /** 1002 * Is the Shift key pressed? 1003 * 1004 * @param shift 1005 */ 1006 public void setShift(boolean shift){ 1007 this.shift = shift; 1008 } 1009 1010 /** 1011 * Is the Alt key pressed? 1012 * 1013 * @param alt 1014 */ 1015 public void setAlt(boolean alt){ 1016 this.alt = alt; 1017 } 1018 1019 /** 1020 * Is the Ctrl key pressed? 1021 * 1022 * @param ctrl 1023 */ 1024 public void setCtrl(boolean ctrl){ 1025 this.ctrl = ctrl; 1026 } 1027 1028//variables 1029 1030 //the current LocaleHandler 1031 /** 1032 * the active locale handler 1033 */ 1034 LocaleHandler handler; 1035 //thenew handler that will become current on the next update 1036 /** 1037 * The new active locale handler. This member is useful during the period when the active locale handler has changed but the keyboard map is not updated yet. The keyboard map will be updated as soon as the tasks that were added to the job list before the locale change are consumed. 1038 */ 1039 LocaleHandler newHandler; 1040 1041 //the current state of the current locale handler 1042 /** 1043 * The current state of the current locale handler. 1044 */ 1045 State state; 1046 //the new state that will become current on the next update 1047 /** 1048 * The current state of the new current locale handler. 1049 * 1050 * @see #newHandler 1051 */ 1052 State newState; 1053 /** 1054 * The window used for displaying the keyboard map 1055 */ 1056 Window window; 1057 /** 1058 * The content pane that holds all the KeyGUIs. 1059 * 1060 * @see guk.im.KeyboardMap.KeyGUI 1061 */ 1062 JPanel contentPane; 1063 1064 /** 1065 * The keys curently highlighted 1066 */ 1067 java.util.List highlightedKeys = new ArrayList(); 1068 1069 /** */ 1070 boolean shift = false, ctrl = false, alt = false, capslock = false; 1071 /** maps from String(the English lowercase representation of the key) to 1072 * KeyGUI 1073 */ 1074 Map GUIforString; 1075 //maps from Key to JLabel for the key that have keyCap defined 1076 /** 1077 * Maps from Key to JLabel for the keys that have keyCap defined 1078 * . 1079 */ 1080 Map labelForKey; 1081 1082 /** 1083 * The input method. 1084 */ 1085 GateIM im; 1086 1087 /** 1088 * The thread that does the updating. 1089 */ 1090 Thread myThread; 1091 1092 /** 1093 * The job list. 1094 */ 1095 java.util.List jobs; 1096//classes 1097 public class KeyGUI extends JPanel { 1098 /** */ 1099 Box leftBox; 1100 /** */ 1101 JLabel leftUpLabel = new JLabel(); 1102 /** */ 1103 JLabel leftDownLabel = new JLabel(); 1104 /** */ 1105 Component centerLabel; 1106 /** */ 1107 char low, up; 1108 /** */ 1109 Border normalBorder, highlightedBorder; 1110 1111 /** 1112 * Constructs a new KeyGUI. 1113 * 1114 * @param key the String key used in the map that holds the GUIs used for 1115 * keys 1116 * @param englishLow the English char on the key 1117 * @param englishUp the English char on the key when used with the Shift 1118 * key. 1119 * @param center the center label (the Unicode character on the key) 1120 */ 1121 public KeyGUI(String key, char englishLow, char englishUp, 1122 JLabel center) { 1123 this.setBackground(Color.lightGray); 1124 low = englishLow; 1125 up = englishUp; 1126 leftBox = Box.createVerticalBox(); 1127 Dimension dim; 1128 if(englishUp > (char)0){ 1129 leftUpLabel.setFont(leftUpLabel.getFont().deriveFont((float)10)); 1130 leftUpLabel.setText("" + englishUp); 1131 leftBox.add(leftUpLabel); 1132 }else{ 1133 leftBox.add(placeHolder); 1134 } 1135 if(englishLow > (char)0){ 1136 leftDownLabel.setFont(leftDownLabel.getFont().deriveFont((float)10)); 1137 leftDownLabel.setText("" + englishLow); 1138 leftBox.add(leftDownLabel); 1139 }else{ 1140 leftBox.add(placeHolder); 1141 } 1142 leftBox.add(Box.createVerticalGlue()); 1143 if(center == null) centerLabel = placeHolder; 1144 else centerLabel = center; 1145 this.setLayout(new BoxLayout(this,BoxLayout.X_AXIS)); 1146 this.add(leftBox); 1147 this.add(Box.createHorizontalGlue()); 1148 this.add(centerLabel); 1149 normalBorder = new CompoundBorder(new BevelBorder(BevelBorder.RAISED), 1150 new EmptyBorder(2,3,2,3)); 1151 highlightedBorder = new CompoundBorder(new BevelBorder(BevelBorder.RAISED), 1152 new MatteBorder(2,3,2,3, Color.green)); 1153 1154 this.setBorder(normalBorder); 1155 addMouseListener(new MouseAdapter(){ 1156 /** * 1157 * @param e 1158 */ 1159 public void mouseClicked(MouseEvent e){ 1160 int modifiers = 0; 1161 if(ctrl) modifiers |= KeyEvent.CTRL_MASK; 1162 if(alt) modifiers |= KeyEvent.ALT_MASK; 1163 char ch; 1164 if(shift) ch = up; 1165 else ch = low; 1166 if(ch != 0){ 1167 im.dispatchEvent(new KeyEvent(window, KeyEvent.KEY_TYPED, 1168 System.currentTimeMillis(), 1169 modifiers, KeyEvent.VK_UNDEFINED, ch)); 1170 } 1171 } 1172 /** */ 1173 public void mousePressed(MouseEvent e){ 1174 char ch; 1175 if(shift) ch = up; 1176 else ch = low; 1177 if(ch != 0){ 1178 pressKey(); 1179 //repaint(100); 1180 } 1181 } 1182 /** */ 1183 public void mouseReleased(MouseEvent e){ 1184 char ch; 1185 if(shift) ch = up; 1186 else ch = low; 1187 if(ch != 0){ 1188 releaseKey(); 1189 //repaint(100); 1190 } 1191 } 1192 }); 1193 } 1194 1195 /** */ 1196 public void updateLabel(){ 1197 if(low == (char)0 || up == (char)0)return; 1198 remove(centerLabel); 1199 Key key; 1200 int modifiers = 0; 1201 if(ctrl) modifiers |= InputEvent.CTRL_MASK; 1202 if(alt) modifiers |= InputEvent.ALT_MASK; 1203 if(shift) key = new Key(up, modifiers); 1204 else key = new Key(low, modifiers); 1205 centerLabel = (JLabel)labelForKey.get(key); 1206 if(centerLabel == null) centerLabel = placeHolder; 1207 this.add(centerLabel); 1208// this.invalidate(); 1209 } 1210 1211 /** 1212 * Displays this key as pressed 1213 */ 1214 public void pressKey(){ 1215 this.setBackground(Color.darkGray); 1216 } 1217 1218 /** 1219 * Displays ths key as released. 1220 */ 1221 public void releaseKey(){ 1222 this.setBackground(Color.lightGray); 1223 } 1224 1225 /** 1226 * Renders this KeyGUI as highlighted 1227 */ 1228 public void highlight(){ 1229 setBorder(highlightedBorder); 1230 } 1231 1232 /** 1233 * Renders this KeyGUI normaly (not highlighted) 1234 */ 1235 public void unHighlight(){ 1236 setBorder(normalBorder); 1237 } 1238 1239 }//public class KeyGUI extends JPanel 1240 1241 1242 1243 /** 1244 * Empty component used for the key that are not bound to a Unicode character. 1245 */ 1246 static Component placeHolder = Box.createRigidArea(new Dimension(12, 12)); 1247}//class KeyboardMap 1248
|
KeyboardMap |
|