1 17 package thinlet; 18 19 import java.awt.*; 20 import java.awt.datatransfer.*; 21 import java.awt.image.*; 22 import java.awt.event.*; 23 import java.lang.reflect.*; 24 import java.io.*; 25 import java.net.*; 26 import java.util.*; 27 28 31 public class Thinlet extends Container 32 implements Runnable , Serializable { 33 34 private transient Font font; 35 private transient Color c_bg; 36 private transient Color c_text; 37 private transient Color c_textbg; 38 private transient Color c_border; 39 private transient Color c_disable; 40 private transient Color c_hover; 41 private transient Color c_press; 42 private transient Color c_focus; 43 private transient Color c_select; 44 private transient Color c_ctrl = null; 45 private transient int block; 46 private transient Image hgradient, vgradient; 47 48 private transient Thread timer; 49 private transient long watchdelay; 50 private transient long watch; 51 private transient String clipboard; 52 private transient ResourceBundle resourcebundle; 54 private static ResourceBundle langResource = null; private static ResourceBundle langResourceDefault = null; private transient boolean allI18n = false; 58 private transient String findprefix = ""; 60 private transient long findtime; 61 62 private Object content = createImpl("desktop"); 63 private transient Object mouseinside; 64 private transient Object insidepart; 65 private transient Object mousepressed; 66 private transient Object pressedpart; 67 private transient int referencex, referencey; 68 private transient int mousex, mousey; 69 private transient Object focusowner; 70 private transient boolean focusinside; 71 private transient Object popupowner; 72 private transient Object tooltipowner; 73 75 private static final int DRAG_ENTERED = AWTEvent.RESERVED_ID_MAX + 1; 76 private static final int DRAG_EXITED = AWTEvent.RESERVED_ID_MAX + 2; 77 78 private static long WHEEL_MASK = 0; 79 private static int MOUSE_WHEEL = 0; 80 private static Method wheelrotation = null; 81 private static int evm = 0; 82 static { 83 try { 84 WHEEL_MASK = AWTEvent.class.getField("MOUSE_WHEEL_EVENT_MASK").getLong(null); 85 MOUSE_WHEEL = MouseEvent.class.getField("MOUSE_WHEEL").getInt(null); 86 } catch (Exception exc) { } 87 } 88 { 89 setFont(new Font("SansSerif", Font.PLAIN, 12)); 90 setColors(0xe6e6e6, 0x000000, 0xffffff, 92 0x909090, 0xb0b0b0, 0xededed, 0xb9b9b9, 0x89899a, 0xc5c5dd); 93 94 if (MOUSE_WHEEL != 0) { 96 try { 97 getClass().getMethod("setFocusTraversalKeysEnabled", new Class [] { Boolean.TYPE }). 98 invoke(this, new Object [] { Boolean.FALSE }); 99 } catch (Exception exc) { } 100 } 101 enableEvents(AWTEvent.COMPONENT_EVENT_MASK | 103 AWTEvent.FOCUS_EVENT_MASK | AWTEvent.KEY_EVENT_MASK | 104 AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK | WHEEL_MASK); 105 try { 108 if ((System.getProperty("java.vendor").indexOf("Insignia") != -1) && 109 System.getProperty("os.name").indexOf("Windows CE") == -1) { evm = -1; } 110 } catch (Exception exc) { } 111 } 112 113 136 public void setColors(int background, int text, int textbackground, 137 int border, int disable, int hover, int press, 138 int focus, int select) { 139 c_bg = new Color(background); c_text = new Color(text); 140 c_textbg = new Color(textbackground); c_border = new Color(border); 141 c_disable = new Color(disable); c_hover = new Color(hover); 142 c_press = new Color(press); c_focus = new Color(focus); 143 c_select = new Color(select); 144 hgradient = vgradient = null; 145 repaint(); 146 } 147 148 150 157 public void setFont(Font font) { 158 block = getFontMetrics(font).getHeight(); 159 super.setFont(font); 160 this.font = font; 161 hgradient = vgradient = null; 162 if (content != null) validate(content); 163 } 164 165 168 private void doLayout(Object component) { 169 String classname = getClass(component); 170 if ("combobox" == classname) { 171 if (getBoolean(component, "editable", true)) { 172 Image icon = getIcon(component, "icon", null); 173 layoutField(component, block, false, 174 (icon != null) ? icon.getWidth(this) : 0); 175 } else { 177 int selected = getInteger(component, "selected", -1); 178 if (selected != -1) { Object choice = getItem(component, selected); 180 set(component, "text", get(choice, "text")); 181 set(component, "icon", get(choice, "icon")); 182 } 183 } 184 } 185 else if (("textfield" == classname) || ("passwordfield" == classname)) { 186 layoutField(component, 0, ("passwordfield" == classname), 0); 187 } 188 else if ("textarea" == classname) { 189 String text = getString(component, "text", ""); 190 int start = getInteger(component, "start", 0); 191 if (start > text.length()) { setInteger(component, "start", start = text.length(), 0); } 192 int end = getInteger(component, "end", 0); 193 if (end > text.length()) { setInteger(component, "end", end = text.length(), 0); } 194 195 boolean wrap = getBoolean(component, "wrap", false); 196 char[] chars = null; 197 if (wrap) { 198 Rectangle bounds = getRectangle(component, "bounds"); 199 chars = getChars(component, text, true, bounds.width - 4, bounds.height); 200 if (chars == null) { chars = getChars(component, text, true, bounds.width - block - 4, 0); 202 } 203 } 204 else { 205 chars = getChars(component, text, false, 0, 0); 206 } 207 208 Font currentfont = (Font) get(component, "font"); 209 FontMetrics fm = getFontMetrics((currentfont != null) ? currentfont : font); 210 int width = 0, height = 0; 211 int caretx = 0; int carety = 0; 212 for (int i = 0, j = 0; j <= chars.length; j++) { 213 if ((j == chars.length) || (chars[j] == '\n')) { 214 width = Math.max(width, fm.charsWidth(chars, i, j - i)); 215 if ((end >= i) && (end <= j)) { 216 caretx = fm.charsWidth(chars, i, end - i); 217 carety = height; 218 } 219 height += fm.getHeight(); 220 i = j + 1; 221 } 222 } 223 layoutScroll(component, width + 2, height - fm.getLeading() + 2, 0, 0, 0, 0, 224 getBoolean(component, "border", true), 0); 225 scrollToVisible(component, caretx, carety, 2, fm.getAscent() + fm.getDescent() + 2); } 227 else if ("tabbedpane" == classname) { 228 Rectangle bounds = getRectangle(component, "bounds"); 230 String placement = getString(component, "placement", "top"); 231 boolean horizontal = ((placement == "top") || (placement == "bottom")); 232 boolean stacked = (placement == "stacked"); 233 234 int tabd = 0; Rectangle first = null; int tabsize = 0; for (Object tab = get(component, ":comp"); tab != null; tab = get(tab, ":next")) { 238 if ((tabd == 0) && ((first = getRectangle(tab, "bounds")) != null)) { 239 tabd = horizontal ? first.x : first.y; } 241 Dimension d = getSize(tab, stacked ? 8 : horizontal ? 12 : 9, 242 stacked ? 3 : horizontal ? 5 : 8); 243 setRectangle(tab, "bounds", horizontal ? tabd : 0, horizontal ? 0 : tabd, 244 stacked ? bounds.width : d.width, d.height); 245 if (stacked) { 246 tabd += d.height; 247 } else { 248 tabd += (horizontal ? d.width : d.height) - 3; 249 tabsize = Math.max(tabsize, horizontal ? d.height : d.width); 250 } 251 } 252 253 int cx = (placement == "left") ? (tabsize + 1) : 2; 255 int cy = (placement == "top") ? (tabsize + 1) : 2; 256 int cwidth = bounds.width - ((horizontal || stacked) ? 4 : (tabsize + 3)); 257 int cheight = bounds.height - (stacked ? (tabd + 3) : 258 (horizontal ? (tabsize + 3) : 4)); 259 for (Object tab = get(component, ":comp"); tab != null; tab = get(tab, ":next")) { 260 Rectangle r = getRectangle(tab, "bounds"); 261 if (!stacked) { 262 if (horizontal) { 263 if (placement == "bottom") { r.y = bounds.height - tabsize; } 264 r.height = tabsize; 265 } 266 else { 267 if (placement == "right") { r.x = bounds.width - tabsize; } 268 r.width = tabsize; 269 } 270 } 271 272 Object comp = get(tab, ":comp"); if ((comp != null) && getBoolean(comp, "visible", true)) { 274 setRectangle(comp, "bounds", 275 cx - r.x, stacked ? (r.height + 1) : (cy - r.y), cwidth, cheight); 276 doLayout(comp); 277 } 278 } 279 checkOffset(component); 280 } 281 else if (("panel" == classname) || (classname == "dialog")) { 282 int gap = getInteger(component, "gap", 0); 283 int[][] grid = getGrid(component); 284 int top = 0; int left = 0; 285 int contentwidth = 0; int contentheight = 0; 286 if (grid != null) { top = getInteger(component, "top", 0); 288 left = getInteger(component, "left", 0); 289 int bottom = getInteger(component, "bottom", 0); 290 int right = getInteger(component, "right", 0); 291 contentwidth = left + getSum(grid[0], 0, grid[0].length, gap, false) + right; 293 contentheight = top + getSum(grid[1], 0, grid[1].length, gap, false) + bottom; 294 } 295 296 int titleheight = getSize(component, 0, 0).height; setInteger(component, ":titleheight", titleheight, 0); 298 boolean scrollable = getBoolean(component, "scrollable", false); 299 boolean border = ("panel" == classname) && getBoolean(component, "border", false); 300 int iborder = (border ? 1 : 0); 301 if (scrollable) { if ("panel" == classname) { 303 int head = titleheight / 2; 304 int headgap = (titleheight > 0) ? (titleheight - head - iborder) : 0; 305 scrollable = layoutScroll(component, contentwidth, contentheight, 306 head, 0, 0, 0, border, headgap); 307 } 308 else { scrollable = layoutScroll(component, contentwidth, contentheight, 310 3 + titleheight, 3, 3, 3, true, 0); 311 } 312 } 313 if (!scrollable) { set(component, ":view", null); set(component, ":port", null); 315 } 316 317 if (grid != null) { 318 int areax = 0; int areay = 0; int areawidth = 0; int areaheight = 0; 319 if (scrollable) { 320 Rectangle view = getRectangle(component, ":view"); 322 areawidth = view.width; areaheight = view.height; 323 } 324 else { Rectangle bounds = getRectangle(component, "bounds"); 327 areawidth = bounds.width; areaheight = bounds.height; 328 if ("panel" == classname) { 329 areax = iborder; areay = Math.max(iborder, titleheight); 330 areawidth -= 2 * iborder; areaheight -= areay + iborder; 331 } 332 else { areax = 4; areay = 4 + titleheight; 334 areawidth -= 8; areaheight -= areay + 4; 335 } 336 } 337 338 for (int i = 0; i < 2; i++) { int d = ((i == 0) ? (areawidth - contentwidth) : (areaheight - contentheight)); 341 if (d != 0) { int w = getSum(grid[2 + i], 0, grid[2 + i].length, 0, false); 343 if (w > 0) { 344 for (int j = 0; j < grid[i].length; j++) { 345 if (grid[2 + i][j] != 0) { 346 grid[i][j] += d * grid[2 + i][j] / w; 347 } 348 } 349 } 350 } 351 } 352 353 Object comp = get(component, ":comp"); 354 for (int i = 0; comp != null; comp = get(comp, ":next")) { 355 if (!getBoolean(comp, "visible", true)) { continue; } 356 int ix = areax + left + getSum(grid[0], 0, grid[4][i], gap, true); 357 int iy = areay + top + getSum(grid[1], 0, grid[5][i], gap, true); 358 int iwidth = getSum(grid[0], grid[4][i], grid[6][i], gap, false); 359 int iheight = getSum(grid[1], grid[5][i], grid[7][i], gap, false); 360 String halign = getString(comp, "halign", "fill"); 361 String valign = getString(comp, "valign", "fill"); 362 if ((halign != "fill") || (valign != "fill")) { 363 Dimension d = getPreferredSize(comp); 364 if (halign != "fill") { 365 int dw = Math.max(0, iwidth - d.width); 366 if (halign == "center") { ix += dw / 2; } 367 else if (halign == "right") { ix += dw; } 368 iwidth -= dw; 369 } 370 if (valign != "fill") { 371 int dh = Math.max(0, iheight - d.height); 372 if (valign == "center") { iy += dh / 2; } 373 else if (valign == "bottom") { iy += dh; } 374 iheight -= dh; 375 } 376 } 377 setRectangle(comp, "bounds", ix, iy, iwidth, iheight); 378 doLayout(comp); 379 i++; 380 } 381 } 382 } 383 else if ("desktop" == classname) { 384 Rectangle bounds = getRectangle(component, "bounds"); 385 for (Object comp = get(component, ":comp"); 386 comp != null; comp = get(comp, ":next")) { 387 String iclass = getClass(comp); 388 if (iclass == "dialog") { 389 Dimension d = getPreferredSize(comp); 390 if (get(comp, "bounds") == null) 391 setRectangle(comp, "bounds", 392 Math.max(0, (bounds.width - d.width) / 2), 393 Math.max(0, (bounds.height - d.height) / 2), 394 Math.min(d.width, bounds.width), Math.min(d.height, bounds.height)); 395 } else if ((iclass != ":combolist") && (iclass != ":popup")) { 396 setRectangle(comp, "bounds", 0, 0, bounds.width, bounds.height); 397 } 398 doLayout(comp); 399 } 400 } 401 else if ("spinbox" == classname) { 402 layoutField(component, block, false, 0); 403 } 404 else if ("splitpane" == classname) { 405 Rectangle bounds = getRectangle(component, "bounds"); 406 boolean horizontal = ("vertical" != get(component, "orientation")); 407 int divider = getInteger(component, "divider", -1); 408 int maxdiv = Math.max(0, (horizontal ? bounds.width : bounds.height) - 5); 409 410 Object comp1 = get(component, ":comp"); 411 boolean visible1 = (comp1 != null) && getBoolean(comp1, "visible", true); 412 if (divider == -1) { 413 int d1 = 0; 414 if (visible1) { 415 Dimension d = getPreferredSize(comp1); 416 d1 = horizontal ? d.width : d.height; 417 } 418 divider = Math.min(d1, maxdiv); 419 setInteger(component, "divider", divider, -1); 420 } 421 else if (divider > maxdiv) { 422 setInteger(component, "divider", divider = maxdiv, -1); 423 } 424 425 if (visible1) { 426 setRectangle(comp1, "bounds", 0, 0, horizontal ? divider : bounds.width, 427 horizontal ? bounds.height : divider); 428 doLayout(comp1); 429 } 430 Object comp2 = (comp1 != null) ? get(comp1, ":next") : null; 431 if ((comp2 != null) && getBoolean(comp2, "visible", true)) { 432 setRectangle(comp2, "bounds", horizontal ? (divider + 5) : 0, 433 horizontal ? 0 : (divider + 5), 434 horizontal ? (bounds.width - 5 - divider) : bounds.width, 435 horizontal ? bounds.height : (bounds.height - 5 - divider)); 436 doLayout(comp2); 437 } 438 } 439 else if (("list" == classname) || 440 ("table" == classname) || ("tree" == classname)) { 441 int line = getBoolean(component, "line", true) ? 1 : 0; 442 int width = 0; 443 int columnheight = 0; 444 if ("table" == classname) { 445 Object header = get(component, "header"); 446 int[] columnwidths = null; 447 if (header != null) { 448 columnwidths = new int[getCount(header)]; 449 Object column = get(header, ":comp"); 450 for (int i = 0; i < columnwidths.length; i++) { 451 if (i != 0) { column = get(column, ":next"); } 452 columnwidths[i] = getInteger(column, "width", 80); 453 width += columnwidths[i]; 454 Dimension d = getSize(column, 2, 2); 455 columnheight = Math.max(columnheight, d.height); 456 } 457 } 458 set(component, ":widths", columnwidths); 459 } 460 int y = 0; 461 int level = 0; 462 for (Object item = get(component, ":comp"); item != null;) { 463 int x = 0; 464 int iwidth = 0; int iheight = 0; 465 if ("table" == classname) { 466 iwidth = width; 467 for (Object cell = get(item, ":comp"); cell != null; cell = get(cell, ":next")) { 468 Dimension d = getSize(cell, 2, 2); 469 iheight = Math.max(iheight, d.height); 470 } 471 } 472 else { 473 if ("tree" == classname) { 474 x = (level + 1) * block; 475 } 476 Dimension d = getSize(item, 6, 2); 477 iwidth = d.width; iheight = d.height; 478 width = Math.max(width, x + d.width); 479 } 480 setRectangle(item, "bounds", x, y, iwidth, iheight); 481 y += iheight + line; 482 if ("tree" == classname) { 483 Object next = get(item, ":comp"); 484 if ((next != null) && getBoolean(item, "expanded", true)) { 485 level++; 486 } else { 487 while (((next = get(item, ":next")) == null) && (level > 0)) { 488 item = getParent(item); 489 level--; 490 } 491 } 492 item = next; 493 } else { 494 item = get(item, ":next"); 495 } 496 } 497 layoutScroll(component, width, y - line, columnheight, 0, 0, 0, true, 0); 498 } 499 else if ("menubar" == classname) { 500 Rectangle bounds = getRectangle(component, "bounds"); 501 int x = 0; 502 for (Object menu = get(component, ":comp"); 503 menu != null; menu = get(menu, ":next")) { 504 Dimension d = getSize(menu, 8, 4); 505 setRectangle(menu, "bounds", x, 0, d.width, bounds.height); 506 x += d.width; 507 } 508 } 509 else if ("bean" == classname) { 510 Rectangle r = getRectangle(component, "bounds"); 511 ((Component) get(component, "bean")).setBounds(r); 512 } 513 } 514 515 519 private void checkOffset(Object component) { 520 String placement = getString(component, "placement", "top"); 521 int selected = getInteger(component, "selected", 0); int i = 0; 522 if (placement == "stacked") { 523 int dy = 0; 524 for (Object tab = get(component, ":comp"); tab != null; tab = get(tab, ":next")) { 525 Rectangle r = getRectangle(tab, "bounds"); 526 r.y = dy; 527 dy += r.height; 528 if (i == selected) { dy += getRectangle(get(tab, ":comp"), "bounds").height + 2; } 529 i++; 530 } 531 if (mouseinside == component) { checkLocation(); 533 } 534 return; 535 } 536 boolean horizontal = ((placement == "top") || (placement == "bottom")); 537 Rectangle bounds = getRectangle(component, "bounds"); 538 int panesize = horizontal ? bounds.width : bounds.height; 539 int first = 0; int last = 0; int d = 0; 540 for (Object tab = get(component, ":comp"); tab != null; tab = get(tab, ":next")) { 541 Rectangle r = getRectangle(tab, "bounds"); 542 if (i == 0) { first = (horizontal ? r.x : r.y); } 543 last = (horizontal ? (r.x + r.width) : (r.y + r.height)); 544 if (i == selected) { 545 int ifrom = (horizontal ? r.x : r.y) - 6; 546 int ito = (horizontal ? (r.x + r.width) : (r.y + r.height)) + 6; 547 if (ifrom < 0) { d = -ifrom; } 548 else if (ito > panesize) { d = panesize - ito; } 549 } 550 i++; 551 } 552 d = Math.min(-first, Math.max(d, panesize - last)); 553 if (d != 0) { 554 for (Object tab = get(component, ":comp"); tab != null; tab = get(tab, ":next")) { 555 Rectangle r = getRectangle(tab, "bounds"); 556 if (horizontal) { r.x += d; } else { r.y += d; } 557 Object comp = get(tab, ":comp"); if ( (comp != null) && getBoolean(comp, "visible", true)) { 559 Rectangle rc = getRectangle(comp, "bounds"); 560 if (horizontal) { rc.x -= d; } else { rc.y -= d; } 561 } 562 } 563 if (mouseinside == component) { checkLocation(); 565 } 566 } 567 } 568 569 572 private char[] getChars(Object component, 573 String text, boolean wrap, int width, int height) { 574 char[] chars = (char[]) get(component, ":text"); 575 if ((chars == null) || (chars.length != text.length())) { 576 chars = text.toCharArray(); 577 set(component, ":text", chars); 578 } 579 else text.getChars(0, chars.length, chars, 0); 580 581 if (wrap) { 582 Font currentfont = (Font) get(component, "font"); 583 FontMetrics fm = getFontMetrics((currentfont != null) ? currentfont : font); 584 int lines = (height - 4 + fm.getLeading()) / fm.getHeight(); 585 boolean prevletter = false; int n = chars.length; int linecount = 0; 586 for (int i = 0, j = -1, k = 0; k <= n; k++) { if (((k == n) || (chars[k] == '\n') || (chars[k] == ' ')) && 588 (j > i) && (fm.charsWidth(chars, i, k - i) > width)) { 589 chars[j] = '\n'; 590 k--; } 592 else if ((k == n) || (chars[k] == '\n')) { j = k; prevletter = false; 594 } 595 else { 596 if ((chars[k] == ' ') && (prevletter || (j > i))) { j = k; } prevletter = (chars[k] != ' '); 598 continue; 599 } 600 linecount++; 601 if ((lines != 0) && (linecount == lines)) { return null; } 602 i = j + 1; 603 } 604 } 605 return chars; 606 } 607 608 611 635 636 640 private String getAccelerator(Object component) { 641 Object accelerator = get(component, "accelerator"); 642 if (accelerator != null) { 643 long keystroke = ((Long ) accelerator).longValue(); 644 int keycode = (int) (keystroke >> 32); 645 int modifiers = (int) (keystroke & 0xffff); 646 return KeyEvent.getKeyModifiersText(keycode) + " " + 647 KeyEvent.getKeyText(modifiers); 648 } 649 return null; 650 } 651 652 657 private Object popupCombo(Object combobox) { 658 int combox = 0, comboy = 0, combowidth = 0, comboheight = 0; 660 for (Object comp = combobox; comp != content; comp = getParent(comp)) { 661 Rectangle r = getRectangle(comp, "bounds"); 662 combox += r.x; comboy += r.y; 663 Rectangle view = getRectangle(comp, ":view"); 664 if (view != null) { 665 combox -= view.x; comboy -= view.y; 666 Rectangle port = getRectangle(comp, ":port"); 667 combox += port.x; comboy+= port.y; 668 } 669 if (comp == combobox) { combowidth = r.width; comboheight = r.height; } 670 } 671 Object combolist = createImpl(":combolist"); 673 set(combolist, "combobox", combobox); 674 set(combobox, ":combolist", combolist); 675 popupowner = combobox; 677 insertItem(content, ":comp", combolist, 0); 678 set(combolist, ":parent", content); 679 int pw = 0; int ph = 0; 681 for (Object item = get(combobox, ":comp"); 682 item != null; item = get(item, ":next")) { 683 Dimension d = getSize(item, 8 , 4); 684 setRectangle(item, "bounds", 0, ph, d.width, d.height); 685 pw = Math.max(pw, d.width); 686 ph += d.height; 687 } 688 int listy = 0, listheight = 0; 690 int bellow = getRectangle(content, "bounds").height - comboy - comboheight - 1; 691 if ((ph + 2 > bellow) && (comboy - 1 > bellow)) { listy = Math.max(0, comboy - 1 - ph - 2); 693 listheight = Math.min(comboy - 1, ph + 2); 694 } 695 else { listy = comboy + comboheight + 1; 697 listheight = Math.min(bellow, ph + 2); 698 } 699 setRectangle(combolist, "bounds", combox, listy, combowidth, listheight); 700 layoutScroll(combolist, pw, ph, 0, 0, 0, 0, true, 0); 701 repaint(combolist); 702 int selected = getInteger(combobox, "selected", -1); 704 setInside(combolist, (selected != -1) ? getItem(combobox, selected) : null, true); 705 return combolist; 706 } 707 708 712 private Object popupMenu(Object component) { 713 Object popup = get(component, ":popup"); Object selected = get(component, "selected"); if (popup != null) { if (get(popup, "menu") == selected) { return null; } set(popup, "selected", null); 718 set(popup, "menu", null); 719 repaint(popup); 720 removeItemImpl(content, popup); 721 set(popup, ":parent", null); 722 set(component, ":popup", null); 723 if (mouseinside == popup) { 724 checkLocation(); 725 } 726 popupMenu(popup); } 728 if ((selected == null) || (getClass(selected) != "menu")) { return null; } 730 popup = createImpl(":popup"); 733 set(popup, "menu", selected); 734 set(component, ":popup", popup); 735 insertItem(content, ":comp", popup, 0); 736 set(popup, ":parent", content); 737 int menux = 0, menuy = 0, menuwidth = 0, menuheight = 0; 739 for (Object comp = component; comp != content; comp = getParent(comp)) { 740 Rectangle r = getRectangle(comp, "bounds"); 741 menux += r.x; menuy += r.y; 742 Rectangle view = getRectangle(comp, ":view"); 743 if (view != null) { 744 menux -= view.x; menuy -= view.y; 745 Rectangle port = getRectangle(comp, ":port"); 746 menux += port.x; menuy+= port.y; 747 } 748 if (comp == component) { menuwidth = r.width; menuheight = r.height; } 749 } 750 Rectangle menubounds = getRectangle(selected, "bounds"); 752 boolean menubar = ("menubar" == getClass(component)); 753 if (menubar) { popupowner = component; } 754 popup(selected, popup, 755 menubar ? (("bottom" != get(component, "placement")) ? 'D' : 'U') : 'R', 756 menubar ? (menux + menubounds.x) : menux, menuy + menubounds.y, 757 menubar ? menubounds.width : menuwidth, 758 menubar ? menuheight : menubounds.height, menubar ? 1 : 3); 759 return popup; 760 } 761 762 765 private void popupPopup(Object popupmenu, int x, int y) { 766 Object popup = createImpl(":popup"); 768 set(popup, "menu", popupmenu); 769 set(popupmenu, ":popup", popup); 770 popupowner = popupmenu; 772 insertItem(content, ":comp", popup, 0); 773 set(popup, ":parent", content); 774 popup(popupmenu, popup, 'D', x, y, 0, 0, 0); 776 invoke(popupmenu, null, "menushown"); } 779 780 792 private void popup(Object menu, Object popup, 793 char direction, int x, int y, int width, int height, int offset) { 794 int pw = 0; int ph = 0; 795 for (Object item = get(menu, ":comp"); item != null; item = get(item, ":next")) { 796 String itemclass = getClass(item); 797 Dimension d = (itemclass == "separator") ? new Dimension(1, 1) : 798 getSize(item, 8 , 4); 799 if (itemclass == "checkboxmenuitem") { 800 d.width = d.width + block + 3; 801 d.height = Math.max(block, d.height); 802 } 803 else if (itemclass == "menu") { 804 d.width += block; 805 } 806 String accelerator = getAccelerator(item); if (accelerator != null) { 808 d.width += 4 + getFontMetrics(font).stringWidth(accelerator); } 810 setRectangle(item, "bounds", 1, 1 + ph, d.width, d.height); 811 pw = Math.max(pw, d.width); 812 ph += d.height; 813 } 814 pw += 2; ph += 2; Rectangle desktop = getRectangle(content, "bounds"); 817 if (direction == 'R') { 818 x += ((x + width - offset + pw > desktop.width) && 819 (x >= pw - offset)) ? (offset - pw) : (width - offset); 820 if ((y + ph > desktop.height) && (ph <= y + height)) { y -= ph - height; } 821 } else { 822 boolean topspace = (y >= ph - offset); boolean bottomspace = (desktop.height - y - height >= ph - offset); 824 y += ((direction == 'U') ? (topspace || !bottomspace) : 825 (!bottomspace && topspace)) ? (offset - ph) : (height - offset); 826 } 827 setRectangle(popup, "bounds", 828 Math.max(0, Math.min(x, desktop.width - pw)), 829 Math.max(0, Math.min(y, desktop.height - ph)), pw, ph); 830 repaint(popup); 831 } 832 833 836 private void closeCombo(Object combobox, Object combolist, Object item) { 837 if ((item != null) && getBoolean(item, "enabled", true)) { 838 String text = getString(item, "text", ""); 839 set(combobox, "text", text); putProperty(combobox, "i18n.text", null); setInteger(combobox, "start", text.length(), 0); 842 setInteger(combobox, "end", 0, 0); 843 set(combobox, "icon", get(item, "icon")); 844 validate(combobox); 845 setInteger(combobox, "selected", getIndex(combobox, item), -1); 846 invoke(combobox, item, "action"); 847 } 848 set(combolist, "combobox", null); 849 set(combobox, ":combolist", null); 850 removeItemImpl(content, combolist); 851 repaint(combolist); 852 set(combolist, ":parent", null); 853 popupowner = null; 854 if (mouseinside == combolist) { 855 checkLocation(); 856 } 857 } 858 859 862 private void closeup() { 863 if (popupowner != null) { 864 String classname = getClass(popupowner); 865 if ("menubar" == classname) { 866 set(popupowner, "selected", null); 867 popupMenu(popupowner); 868 repaint(popupowner); } 870 else if ("combobox" == classname) { 871 closeCombo(popupowner, get(popupowner, ":combolist"), null); 872 } 873 else { popupMenu(popupowner); 875 } 876 popupowner = null; 877 } 878 } 879 880 883 private void showTip() { 884 String text = null; 885 tooltipowner = null; 886 String classname = getClass(mouseinside); 887 if ((classname == "tabbedpane") || (classname == "menubar") || (classname == ":popup")) { 888 if (insidepart != null) { 889 text = getString(insidepart, "tooltip", null); 890 } 891 } 892 else if (classname == ":combolist") { 893 if (insidepart instanceof Object []) { 894 text = getString(insidepart, "tooltip", null); 895 } 896 } 897 if (text == null) { text = getString(mouseinside, "tooltip", null); } 899 else { tooltipowner = insidepart; } 900 if (text != null) { 901 FontMetrics fm = getFontMetrics(font); 902 int width = fm.stringWidth(text) + 4; 903 int height = fm.getAscent() + fm.getDescent() + 4; 904 if (tooltipowner == null) { tooltipowner = mouseinside; } 905 Rectangle bounds = getRectangle(content, "bounds"); 906 int tx = Math.max(0, Math.min(mousex + 10, bounds.width - width)); 907 int ty = Math.max(0, Math.min(mousey + 10, bounds.height - height)); 908 setRectangle(tooltipowner, ":tooltipbounds", tx, ty, width, height); 909 repaint(tx, ty, width, height); 910 } 911 } 912 913 916 private void hideTip() { 917 if (tooltipowner != null) { 918 Rectangle bounds = getRectangle(tooltipowner, ":tooltipbounds"); 919 set(tooltipowner, ":tooltipbounds", null); 920 tooltipowner = null; 921 repaint(bounds.x, bounds.y, bounds.width, bounds.height); 922 } 923 } 924 925 928 private void layoutField(Object component, int dw, boolean hidden, int left) { 929 int width = getRectangle(component, "bounds").width - left -dw; 930 String text = getString(component, "text", ""); 931 int start = getInteger(component, "start", 0); 932 if (start > text.length()) { setInteger(component, "start", start = text.length(), 0); } 933 int end = getInteger(component, "end", 0); 934 if (end > text.length()) { setInteger(component, "end", end = text.length(), 0); } 935 int offset = getInteger(component, ":offset", 0); 936 int off = offset; 937 Font currentfont = (Font) get(component, "font"); 938 FontMetrics fm = getFontMetrics((currentfont != null) ? currentfont : font); 939 int caret = hidden ? (fm.charWidth('*') * end) : 940 fm.stringWidth(text.substring(0, end)); 941 if (off > caret) { 942 off = caret; 943 } 944 else if (off < caret - width + 4) { 945 off = caret - width + 4; 946 } 947 off = Math.max(0, Math.min(off, (hidden ? (fm.charWidth('*') * 948 text.length()) : fm.stringWidth(text)) - width + 4)); 949 if (off != offset) { 950 setInteger(component, ":offset", off, 0); 951 } 952 } 953 954 972 private boolean layoutScroll(Object component, 973 int contentwidth, int contentheight, 974 int top, int left, int bottom, int right, boolean border, int topgap) { 975 Rectangle bounds = getRectangle(component, "bounds"); 976 int iborder = border ? 1 : 0; int iscroll = block + 1 - iborder; 977 int portwidth = bounds.width - left - right - 2 * iborder; int portheight = bounds.height - top - topgap - bottom - 2 * iborder; boolean hneed = contentwidth > portwidth; boolean vneed = contentheight > portheight - (hneed ? iscroll : 0); if (vneed) { portwidth -= iscroll; } hneed = hneed || (vneed && (contentwidth > portwidth)); 983 if (hneed) { portheight -= iscroll; } 985 setRectangle(component, ":port", left + iborder, top + iborder + topgap, portwidth, portheight); 986 if (hneed) { 987 setRectangle(component, ":horizontal", left, bounds.height - bottom - block - 1, 988 bounds.width - left - right - (vneed ? block : 0), block + 1); 989 } else { set(component, ":horizontal", null); } 990 if (vneed) { 991 setRectangle(component, ":vertical", bounds.width - right - block - 1, top, 992 block + 1, bounds.height - top - bottom - (hneed ? block : 0)); 993 } else { set(component, ":vertical", null); } 994 995 contentwidth = Math.max(contentwidth, portwidth); 996 contentheight = Math.max(contentheight, portheight); 997 int viewx = 0, viewy = 0; 998 Rectangle view = getRectangle(component, ":view"); 999 if (view != null) { viewx = Math.max(0, Math.min(view.x, contentwidth - portwidth)); 1001 viewy = Math.max(0, Math.min(view.y, contentheight - portheight)); 1002 } 1003 setRectangle(component, ":view", viewx, viewy, contentwidth, contentheight); 1004 return vneed || hneed; 1005 } 1006 1007 1010 private void scrollToVisible(Object component, 1011 int x, int y, int width, int height) { 1012 Rectangle view = getRectangle(component, ":view"); 1013 Rectangle port = getRectangle(component, ":port"); 1014 int vx = Math.max(x + width - port.width, Math.min(view.x, x)); 1015 int vy = Math.max(y + height - port.height, Math.min(view.y, y)); 1016 if ((view.x != vx) || (view.y != vy)) { 1017 repaint(component); view.x = vx; view.y = vy; 1019 } 1020 } 1021 1022 1027 public Dimension getPreferredSize() { 1028 return getPreferredSize(content); 1029 } 1030 1031 1035 private Dimension getPreferredSize(Object component) { 1036 int width = getInteger(component, "width", 0); 1037 int height = getInteger(component, "height", 0); 1038 if ((width > 0) && (height > 0)) { 1039 return new Dimension(width, height); 1040 } 1041 String classname = getClass(component); 1042 if ("label" == classname) { 1043 return getSize(component, 0, 0); 1044 } 1045 if (("button" == classname) || ("togglebutton" == classname)) { 1046 boolean link = ("button" == classname) && (get(component, "type") == "link"); 1047 return getSize(component, link ? 0 : 12, link ? 0 : 6); 1048 } 1049 if ("checkbox" == classname) { 1050 Dimension d = getSize(component, 0, 0); 1051 d.width = d.width + block + 3; 1052 d.height = Math.max(block, d.height); 1053 return d; 1054 } 1055 if ("combobox" == classname) { 1056 if (getBoolean(component, "editable", true)) { 1057 Dimension size = getFieldSize(component); 1058 Image icon = getIcon(component, "icon", null); 1059 if (icon != null) { 1060 size.width += icon.getWidth(this); 1061 size.height = Math.max(size.height, icon.getHeight(this) + 2); 1062 } 1063 size.width += block; 1064 return size; 1065 } else { 1066 Dimension size = getSize(component, 4 , 4); 1068 for (Object item = get(component, ":comp"); item != null; item = get(item, ":next")) { 1069 Dimension d = getSize(item, 4 , 4); 1070 size.width = Math.max(d.width, size.width); size.height = Math.max(d.height, size.height); 1071 } 1072 size.width += block; 1073 if (size.height == 4) { Font customfont = (Font) get(component, "font"); 1075 FontMetrics fm = getFontMetrics((customfont != null) ? customfont : font); 1076 size.height = fm.getAscent() + fm.getDescent() + 4; 1077 } 1078 return size; 1079 } 1080 } 1081 if (("textfield" == classname) || ("passwordfield" == classname)) { 1082 return getFieldSize(component); 1083 } 1084 if ("textarea" == classname) { 1085 int columns = getInteger(component, "columns", 0); 1086 int rows = getInteger(component, "rows", 0); Font currentfont = (Font) get(component, "font"); 1088 FontMetrics fm = getFontMetrics((currentfont != null) ? currentfont : font); 1089 return new Dimension( 1090 ((columns > 0) ? (columns * fm.charWidth('e') + 2) : 76) + 2 + block, 1091 ((rows > 0) ? (rows * fm.getHeight() - fm.getLeading() + 2) : 76) + 2 + block); 1092 } 1093 if ("tabbedpane" == classname) { 1094 String placement = getString(component, "placement", "top"); 1095 boolean horizontal = ((placement != "left") && (placement != "right")); 1096 int tabsize = 0; int contentwidth = 0; int contentheight = 0; for (Object tab = get(component, ":comp"); 1100 tab != null; tab = get(tab, ":next")) { 1101 Dimension d = getSize(tab, 0, 0); 1102 if (placement == "stacked") { tabsize += d.height + 3; } 1103 else { tabsize = Math.max(tabsize, horizontal ? d.height + 5 : d.width + 9); } 1104 1105 Object comp = get(tab, ":comp"); 1106 if ((comp != null) && getBoolean(comp, "visible", true)) { 1107 Dimension dc = getPreferredSize(comp); 1108 contentwidth = Math.max(contentwidth, dc.width); 1109 contentheight = Math.max(contentheight, dc.height); 1110 } 1111 } 1112 return new Dimension(contentwidth + (horizontal ? 4 : (tabsize + 3)), 1113 contentheight + (horizontal ? (tabsize + 3) : 4)); 1114 } 1115 if (("panel" == classname) || (classname == "dialog")) { 1116 Dimension size = getSize(component, 0, 0); 1118 if (classname == "dialog") { 1120 size.width = 8; size.height += 8; } 1122 else if (getBoolean(component, "border", false)) { size.width = 2; size.height += (size.height > 0) ? 1 : 2; } 1125 else { size.width = 0; } size.width += getInteger(component, "left", 0) + getInteger(component, "right", 0); 1128 size.height += getInteger(component, "top", 0) + getInteger(component, "bottom", 0); 1129 int gap = getInteger(component, "gap", 0); 1131 int[][] grid = getGrid(component); 1132 if (grid != null) { size.width += getSum(grid[0], 0, grid[0].length, gap, false); 1134 size.height += getSum(grid[1], 0, grid[1].length, gap, false); 1135 } 1136 return size; 1137 } 1138 else if ("desktop" == classname) { 1139 Dimension size = new Dimension(); 1140 for (Object comp = get(component, ":comp"); 1141 comp != null; comp = get(comp, ":next")) { 1142 String iclass = getClass(comp); 1143 if ((iclass != "dialog") && (iclass != ":popup") && 1144 (iclass != ":combolist")) { 1145 Dimension d = getPreferredSize(comp); 1146 size.width = Math.max(d.width, size.width); 1147 size.height = Math.max(d.height, size.height); 1148 } 1149 } 1150 return size; 1151 } 1152 if ("spinbox" == classname) { 1153 Dimension size = getFieldSize(component); 1154 size.width += block; 1155 return size; 1156 } 1157 if ("progressbar" == classname) { 1158 boolean horizontal = ("vertical" != get(component, "orientation")); 1159 return new Dimension(horizontal ? 76 : 6, horizontal ? 6 : 76); 1160 } 1161 if ("slider" == classname) { 1162 boolean horizontal = ("vertical" != get(component, "orientation")); 1163 return new Dimension(horizontal ? 76 : 10, horizontal ? 10 : 76); 1164 } 1165 if ("splitpane" == classname) { 1166 boolean horizontal = ("vertical" != get(component, "orientation")); 1167 Object comp1 = get(component, ":comp"); 1168 Dimension size = ((comp1 == null) || !getBoolean(comp1, "visible", true)) ? 1169 new Dimension() : getPreferredSize(comp1); 1170 Object comp2 = get(comp1, ":next"); 1171 if ((comp2 != null) && getBoolean(comp2, "visible", true)) { 1172 Dimension d = getPreferredSize(comp2); 1173 size.width = horizontal ? (size.width + d.width) : 1174 Math.max(size.width, d.width); 1175 size.height = horizontal ? Math.max(size.height, d.height) : 1176 (size.height + d.height); 1177 } 1178 if (horizontal) { size.width += 5; } else { size.height += 5; } 1179 return size; 1180 } 1181 if (("list" == classname) || 1182 ("table" == classname) || ("tree" == classname)) { 1183 return new Dimension(76 + 2 + block, 76 + 2 + block); 1184 } 1185 if ("separator" == classname) { 1186 return new Dimension(1, 1); 1187 } 1188 if ("menubar" == classname) { 1189 Dimension size = new Dimension(0, 0); 1190 for (Object menu = get(component, ":comp"); 1191 menu != null; menu = get(menu, ":next")) { 1192 Dimension d = getSize(menu, 8, 4); 1193 size.width += d.width; 1194 size.height = Math.max(size.height, d.height); 1195 } 1196 return size; 1197 } 1198 if ("bean" == classname) { 1199 return ((Component) get(component, "bean")).getPreferredSize(); 1200 } 1201 throw new IllegalArgumentException (classname); 1202 } 1203 1204 1216 private int[][] getGrid(Object component) { 1217 int count = 0; for (Object comp = get(component, ":comp"); comp != null; 1219 comp = get(comp, ":next")) { 1220 if (getBoolean(comp, "visible", true)) { count++; } 1221 } 1222 if (count == 0) { return null; } int columns = getInteger(component, "columns", 0); 1224 int icols = (columns != 0) ? columns : count; 1225 int irows = (columns != 0) ? ((count + columns - 1) / columns) : 1; 1226 int[][] grid = { 1227 new int[icols], new int[irows], new int[icols], new int[irows], new int[count], new int[count], new int[count], new int[count] }; int[] columnheight = new int[icols]; 1232 int[][] cache = null; 1234 int i = 0; int x = 0; int y = 0; 1235 int nextsize = 0; 1236 for (Object comp = get(component, ":comp"); 1237 comp != null; comp = get(comp, ":next")) { 1238 if (!getBoolean(comp, "visible", true)) { continue; } 1239 int colspan = ((columns != 0) && (columns < count)) ? 1240 Math.min(getInteger(comp, "colspan", 1), columns) : 1; 1241 int rowspan = (columns != 1) ? getInteger(comp, "rowspan", 1) : 1; 1242 1243 for (int j = 0; j < colspan; j++) { 1244 if ((columns != 0) && (x + colspan > columns)) { 1245 x = 0; y++; j = -1; 1246 } 1247 else if (columnheight[x + j] > y) { 1248 x += (j + 1); j = -1; 1249 } 1250 } 1251 if (y + rowspan > grid[1].length) { 1252 int[] rowheights = new int[y + rowspan]; 1253 System.arraycopy(grid[1], 0, rowheights, 0, grid[1].length); 1254 grid[1] = rowheights; 1255 int[] rowweights = new int[y + rowspan]; 1256 System.arraycopy(grid[3], 0, rowweights, 0, grid[3].length); 1257 grid[3] = rowweights; 1258 } 1259 for (int j = 0; j < colspan; j++) { 1260 columnheight[x + j] = y + rowspan; 1261 } 1262 1263 int weightx = getInteger(comp, "weightx", 0); 1264 int weighty = getInteger(comp, "weighty", 0); 1265 Dimension d = getPreferredSize(comp); 1266 1267 if (colspan == 1) { 1268 grid[0][x] = Math.max(grid[0][x], d.width); grid[2][x] = Math.max(grid[2][x], weightx); } 1271 else { 1272 if (cache == null) { cache = new int[4][count]; } 1273 cache[0][i] = d.width; 1274 cache[2][i] = weightx; 1275 if ((nextsize == 0) || (colspan < nextsize)) { nextsize = colspan; } 1276 } 1277 if (rowspan == 1) { 1278 grid[1][y] = Math.max(grid[1][y], d.height); grid[3][y] = Math.max(grid[3][y], weighty); } 1281 else { 1282 if (cache == null) { cache = new int[4][count]; } 1283 cache[1][i] = d.height; 1284 cache[3][i] = weighty; 1285 if ((nextsize == 0) || (rowspan < nextsize)) { nextsize = rowspan; } 1286 } 1287 grid[4][i] = x; grid[5][i] = y; grid[6][i] = colspan; grid[7][i] = rowspan; 1292 x += colspan; 1293 i++; 1294 } 1295 1296 while (nextsize != 0) { 1297 int size = nextsize; nextsize = 0; 1298 for (int j = 0; j < 2; j++) { for (int k = 0; k < count; k++) { 1300 if (grid[6 + j][k] == size) { int gridpoint = grid[4 + j][k]; 1303 int weightdiff = cache[2 + j][k]; 1304 for (int m = 0; (weightdiff > 0) && (m < size); m++) { 1305 weightdiff -= grid[2 + j][gridpoint + m]; 1306 } 1307 if (weightdiff > 0) { 1308 int weightsum = cache[2 + j][k] - weightdiff; 1309 for (int m = 0; (weightsum > 0) && (m < size); m++) { 1310 int weight = grid[2 + j][gridpoint + m]; 1311 if (weight > 0) { 1312 int weightinc = weight * weightdiff / weightsum; 1313 grid[2 + j][gridpoint + m] += weightinc; 1314 weightdiff -= weightinc; 1315 weightsum -= weightinc; 1316 } 1317 } 1318 grid[2 + j][gridpoint + size - 1] += weightdiff; 1319 } 1320 1321 int sizediff = cache[j][k]; 1322 int weightsum = 0; 1323 for (int m = 0; (sizediff > 0) && (m < size); m++) { 1324 sizediff -= grid[j][gridpoint + m]; 1325 weightsum += grid[2 + j][gridpoint + m]; 1326 } 1327 if (sizediff > 0) { 1328 for (int m = 0; (weightsum > 0) && (m < size); m++) { 1329 int weight = grid[2 + j][gridpoint + m]; 1330 if (weight > 0) { 1331 int sizeinc = weight * sizediff / weightsum; 1332 grid[j][gridpoint + m] += sizeinc; 1333 sizediff -= sizeinc; 1334 weightsum -= weight; 1335 } 1336 } 1337 grid[j][gridpoint + size - 1] += sizediff; 1338 } 1339 } 1340 else if ((grid[6 + j][k] > size) && 1341 ((nextsize == 0) || (grid[6 + j][k] < nextsize))) { 1342 nextsize = grid[6 + j][k]; 1343 } 1344 } 1345 } 1346 } 1347 return grid; 1348 } 1349 1350 1353 private int getSum(int[] values, 1354 int from, int length, int gap, boolean last) { 1355 if (length <= 0) { return 0; } 1356 int value = 0; 1357 for (int i = 0; i < length; i++) { 1358 value += values[from + i]; 1359 } 1360 return value + (length - (last ? 0 : 1)) * gap; 1361 } 1362 1363 1366 private Dimension getFieldSize(Object component) { 1367 int columns = getInteger(component, "columns", 0); 1368 Font currentfont = (Font) get(component, "font"); 1369 FontMetrics fm = getFontMetrics((currentfont != null) ? currentfont : font); 1370 return new Dimension(((columns > 0) ? 1371 (columns * fm.charWidth('e')) : 76) + 4, 1372 fm.getAscent() + fm.getDescent() + 4); } 1374 1375 1381 private Dimension getSize(Object component, int dx, int dy) { 1382 String text = getString(component, "text", null); 1383 int tw = 0; int th = 0; 1384 if (text != null) { 1385 Font customfont = (Font) get(component, "font"); 1386 FontMetrics fm = getFontMetrics((customfont != null) ? customfont : font); 1387 tw = fm.stringWidth(text); 1388 th = fm.getAscent() + fm.getDescent(); 1389 } 1390 Image icon = getIcon(component, "icon", null); 1391 int iw = 0; int ih = 0; 1392 if (icon != null) { 1393 iw = icon.getWidth(this); 1394 ih = icon.getHeight(this); 1395 if (text != null) { iw += 2; } 1396 } 1397 return new Dimension(tw + iw + dx, Math.max(th, ih) + dy); 1398 } 1399 1400 1403 public void update(Graphics g) { 1404 paint(g); 1405 } 1406 1407 1413 1414 1417 public void paint(Graphics g) { 1418 g.setFont(font); 1419 if (hgradient == null) { 1420 int[][] pix = new int[2][block * block]; 1421 int r1 = c_bg.getRed(); int r2 = c_press.getRed(); 1422 int g1 = c_bg.getGreen(); int g2 = c_press.getGreen(); 1423 int b1 = c_bg.getBlue(); int b2 = c_press.getBlue(); 1424 for (int i = 0; i < block; i++) { 1425 int cr = r1 - (r1 - r2) * i / block; 1426 int cg = g1 - (g1 - g2) * i / block; 1427 int cb = b1 - (b1 - b2) * i / block; 1428 int color = (255 << 24) | (cr << 16) | (cg << 8) | cb; 1429 for (int j = 0; j < block; j++) { 1430 pix[0][i * block + j] = color; 1431 pix[1][j * block + i] = color; 1432 } 1433 } 1434 hgradient = createImage(new MemoryImageSource(block, block, pix[0], 0, block)); 1435 vgradient = createImage(new MemoryImageSource(block, block, pix[1], 0, block)); 1436 } 1437 Rectangle clip = g.getClipBounds(); 1441 paint(g, clip.x, clip.y, clip.width, clip.height, content, isEnabled()); 1443 } 1447 1448 1456 private void paint(Graphics g, 1457 int clipx, int clipy, int clipwidth, int clipheight, 1458 Object component, boolean enabled) { 1459 if (!getBoolean(component, "visible", true)) { return; } 1460 Rectangle bounds = getRectangle(component, "bounds"); 1461 if (bounds == null) { return; } 1462 if (bounds.width < 0) { 1464 bounds.width = Math.abs(bounds.width); 1465 doLayout(component); 1466 } 1467 if ((clipx + clipwidth < bounds.x) || 1469 (clipx > bounds.x + bounds.width) || 1470 (clipy + clipheight < bounds.y) || 1471 (clipy > bounds.y + bounds.height)) { 1472 return; 1473 } 1474 clipx -= bounds.x; clipy -= bounds.y; 1476 g.translate(bounds.x, bounds.y); 1477 String classname = getClass(component); 1479 boolean pressed = (mousepressed == component); 1480 boolean inside = (mouseinside == component) && 1481 ((mousepressed == null) || pressed); 1482 boolean focus = focusinside && (focusowner == component); 1483 enabled = getBoolean(component, "enabled", true); 1485 if ("label" == classname) { 1486 paint(component, 0, 0, bounds.width, bounds.height, 1487 g, clipx, clipy, clipwidth, clipheight, false, false, false, false, 1488 0, 0, 0, 0, false, enabled ? 'e' : 'd', "left", true, false); 1489 } 1490 else if (("button" == classname) || ("togglebutton" == classname)) { 1491 boolean toggled = ("togglebutton" == classname) && getBoolean(component, "selected", false); 1492 boolean link = ("button" == classname) && (get(component, "type") == "link"); 1493 if (link) { 1494 paint(component, 0, 0, bounds.width, bounds.height, 1495 g, clipx, clipy, clipwidth, clipheight, false, false, false, false, 1496 0, 0, 0, 0, focus, enabled ? (pressed ? 'e' : 'l') : 'd', "center", 1497 true, enabled && (inside != pressed)); 1498 } else { char mode = enabled ? ((inside != pressed) ? 'h' : ((pressed || toggled) ? 'p' : 'g')) : 'd'; 1500 paint(component, 0, 0, bounds.width, bounds.height, 1501 g, clipx, clipy, clipwidth, clipheight, true, true, true, true, 1502 2, 5, 2, 5, focus, mode, "center", true, false); 1503 } 1505 } 1506 else if ("checkbox" == classname) { 1507 paint(component, 0, 0, bounds.width, bounds.height, 1508 g, clipx, clipy, clipwidth, clipheight, false, false, false, false, 1509 0, block + 3, 0, 0, false, enabled ? 'e' : 'd', "left", true, false); 1510 1511 boolean selected = getBoolean(component, "selected", false); 1512 String group = getString(component, "group", null); 1513 Color border = enabled ? c_border : c_disable; 1514 Color foreground = enabled ? ((inside != pressed) ? c_hover : 1515 (pressed ? c_press : c_ctrl)) : c_bg; 1516 int dy = (bounds.height - block + 2) / 2; 1517 if (group == null) { 1518 paintRect(g, 1, dy + 1, block - 2, block - 2, 1519 border, foreground, true, true, true, true, true); 1520 } else { 1521 g.setColor((foreground != c_ctrl) ? foreground : c_bg); 1522 g.fillOval(1, dy + 1, block - 3 + evm, block - 3 + evm); 1523 g.setColor(border); 1524 g.drawOval(1, dy + 1, block - 3, block - 3); 1525 } 1526 if (focus) { 1527 g.setColor(c_focus); 1528 if (group == null) { 1529 g.drawRect(3, dy + 3, block - 7, block - 7); 1530 } else { 1531 g.drawOval(3, dy + 3, block - 7, block - 7); 1532 } 1533 } 1534 if((!selected && inside && pressed) || 1535 (selected && (!inside || !pressed))) { 1536 g.setColor(enabled ? c_text : c_disable); 1537 if (group == null) { 1538 g.fillRect(3, dy + block - 9, 2 + evm, 6 + evm); 1539 g.drawLine(3, dy + block - 4, block - 4, dy + 3); 1540 g.drawLine(4, dy + block - 4, block - 4, dy + 4); 1541 } else { 1542 g.fillOval(5, dy + 5, block - 10 + evm, block - 10 + evm); 1543 g.drawOval(4, dy + 4, block - 9, block - 9); 1544 } 1545 } 1546 } 1547 else if ("combobox" == classname) { 1548 if (getBoolean(component, "editable", true)) { 1549 Image icon = getIcon(component, "icon", null); 1550 int left = (icon != null) ? icon.getWidth(this) : 0; 1551 paintField(g, clipx, clipy, clipwidth, clipheight, component, 1552 bounds.width - block, bounds.height, focus, enabled, false, left); 1553 if (icon != null) { 1554 g.drawImage(icon, 2, (bounds.height - icon.getHeight(this)) / 2, this); 1555 } 1556 paintArrow(g, bounds.width - block, 0, block, bounds.height, 1557 'S', enabled, inside, pressed, "down", true, false, true, true, true); 1558 } else { 1559 paint(component, 0, 0, bounds.width, bounds.height, 1560 g, clipx, clipy, clipwidth, clipheight, 1561 true, true, true, true, 1, 1, 1, 1 + block, focus, 1562 enabled ? ((inside != pressed) ? 'h' : (pressed ? 'p' : 'g')) : 'd', 1563 "left", false, false); 1564 g.setColor(enabled ? c_text : c_disable); 1565 paintArrow(g, bounds.width - block, 0, block, bounds.height, 'S'); 1566 } 1567 } 1568 else if (":combolist" == classname) { 1569 paintScroll(component, classname, pressed, inside, focus, enabled, 1570 g, clipx, clipy, clipwidth, clipheight); 1571 } 1572 else if (("textfield" == classname) || ("passwordfield" == classname)) { 1573 paintField(g, clipx, clipy, clipwidth, clipheight, component, 1574 bounds.width, bounds.height, focus, enabled, ("passwordfield" == classname), 0); 1575 } 1576 else if ("textarea" == classname) { 1577 paintScroll(component, classname, pressed, inside, focus, enabled, 1578 g, clipx, clipy, clipwidth, clipheight); 1579 } 1580 else if ("tabbedpane" == classname) { 1581 int i = 0; Object selectedtab = null; 1582 int selected = getInteger(component, "selected", 0); 1583 String placement = getString(component, "placement", "top"); 1584 boolean horizontal = ((placement == "top") || (placement == "bottom")); 1585 boolean stacked = (placement == "stacked"); 1586 int bx = stacked ? 0 : horizontal ? 2 : 1, by = stacked ? 0 : horizontal ? 1 : 2, 1587 bw = 2 * bx, bh = 2 * by; 1588 g.clipRect(0, 0, bounds.width, bounds.height); for (Object tab = get(component, ":comp"); tab != null; tab = get(tab, ":next")) { 1591 Rectangle r = getRectangle(tab, "bounds"); 1592 if (selected != i) { 1593 boolean hover = inside && (mousepressed == null) && (insidepart == tab); 1594 boolean tabenabled = enabled && getBoolean(tab, "enabled", true); 1595 paint(tab, r.x + bx, r.y + by, r.width - bw, r.height - bh, 1596 g, clipx, clipy, clipwidth, clipheight, 1597 (placement != "bottom"), (placement != "right"), 1598 !stacked && (placement != "top"), (placement != "left"), 1599 1, 3, 1, 3, false, tabenabled ? (hover ? 'h' : 'g') : 'd', "left", true, false); 1600 1601 } else { 1602 selectedtab = tab; 1603 paint(tab, (placement == "left") ? r.width - 1 : 0, 1605 stacked ? (r.y + r.height - 1) : (placement == "top") ? r.height - 1 : 0, 1606 (horizontal || stacked) ? bounds.width : (bounds.width - r.width + 1), 1607 stacked ? (bounds.height - r.y - r.height + 1) : 1608 horizontal ? (bounds.height - r.height + 1) : bounds.height, 1609 g, true, true, true, true, enabled ? 'e' : 'd'); 1610 Object comp = get(selectedtab, ":comp"); 1611 if ((comp != null) && getBoolean(comp, "visible", true)) { 1612 clipx -= r.x; clipy -= r.y; g.translate(r.x, r.y); paint(g, clipx, clipy, clipwidth, clipheight, comp, enabled); 1614 clipx += r.x; clipy += r.y; g.translate(-r.x, -r.y); 1615 } 1616 } 1617 i++; 1618 } 1619 1620 if (selectedtab != null) { 1622 Rectangle r = getRectangle(selectedtab, "bounds"); 1623 int ph = stacked ? 3 : (horizontal ? 5 : 4); 1625 int pv = stacked ? 1 : (horizontal ? 2 : 3); 1626 paint(selectedtab, r.x, r.y, r.width, r.height, 1627 g, clipx, clipy, clipwidth, clipheight, 1628 (placement != "bottom"), (placement != "right"), 1629 !stacked && (placement != "top"), (placement != "left"), 1630 pv, ph, pv, ph, focus, enabled ? 'b' : 'i', "left", true, false); 1631 } 1632 g.setClip(clipx, clipy, clipwidth, clipheight); } 1634 else if (("panel" == classname) || ("dialog" == classname)) { 1635 int titleheight = getInteger(component, ":titleheight", 0); 1636 if ("dialog" == classname) { 1637 paint(component, 0, 0, bounds.width, 3 + titleheight, 1638 g, clipx, clipy, clipwidth, clipheight, true, true, false, true, 1639 1, 2, 1, 2, false, 'g', "left", false, false); 1640 int controlx = bounds.width - titleheight - 1; 1641 if (getBoolean(component, "closable", false)) { 1642 paint(component, g, controlx, 3, titleheight - 2, titleheight - 2, 'c'); 1643 controlx -= titleheight; 1644 } 1645 if (getBoolean(component, "maximizable", false)) { 1646 paint(component, g, controlx, 3, titleheight - 2, titleheight - 2, 'm'); 1647 controlx -= titleheight; 1648 } 1649 if (getBoolean(component, "iconifiable", false)) { 1650 paint(component, g, controlx, 3, titleheight - 2, titleheight - 2, 'i'); 1651 } 1652 paintRect(g, 0, 3 + titleheight, bounds.width, bounds.height - 3 - titleheight, 1653 c_border, c_press, false, true, true, true, true); paint(component, 3, 3 + titleheight, bounds.width - 6, bounds.height - 6 - titleheight, 1656 g, true, true, true, true, 'b'); 1657 } else { boolean border = getBoolean(component, "border", false); 1659 paint(component, 0, titleheight / 2, bounds.width, bounds.height - (titleheight / 2), 1660 g, border, border, border, border, enabled ? 'e' : 'd'); 1661 paint(component, 0, 0, bounds.width, titleheight, g, clipx, clipy, clipwidth, clipheight, false, false, false, false, 1663 0, 3, 0, 3, false, enabled ? 'x' : 'd', "left", false, false); 1664 } 1665 1666 if (get(component, ":port") != null) { 1667 paintScroll(component, classname, pressed, inside, focus, enabled, 1668 g, clipx, clipy, clipwidth, clipheight); 1669 } 1670 else { 1671 for (Object comp = get(component, ":comp"); 1672 comp != null; comp = get(comp, ":next")) { 1673 paint(g, clipx, clipy, clipwidth, clipheight, comp, enabled); 1674 } 1675 } 1676 } 1677 else if ("desktop" == classname) { 1678 paintRect(g, 0, 0, bounds.width, bounds.height, 1679 c_border, c_bg, false, false, false, false, true); 1680 paintReverse(g, clipx, clipy, clipwidth, clipheight, 1681 get(component, ":comp"), enabled); 1682 if ((tooltipowner != null) && (component == content)) { 1684 Rectangle r = getRectangle(tooltipowner, ":tooltipbounds"); 1685 paintRect(g, r.x, r.y, r.width, r.height, 1686 c_border, c_bg, true, true, true, true, true); 1687 String text = getString(tooltipowner, "tooltip", null); 1688 g.setColor(c_text); 1689 g.drawString(text, r.x + 2, r.y + g.getFontMetrics().getAscent() + 2); } 1691 } 1692 else if ("spinbox" == classname) { 1693 paintField(g, clipx, clipy, clipwidth, clipheight, component, 1694 bounds.width - block, bounds.height, focus, enabled, false, 0); 1695 paintArrow(g, bounds.width - block, 0, block, bounds.height / 2, 1696 'N', enabled, inside, pressed, "up", true, false, false, true, true); 1697 paintArrow(g, bounds.width - block, bounds.height / 2, 1698 block, bounds.height - (bounds.height / 2), 1699 'S', enabled, inside, pressed, "down", true, false, true, true, true); 1700 } 1701 else if ("progressbar" == classname) { 1702 int minimum = getInteger(component, "minimum", 0); 1703 int maximum = getInteger(component, "maximum", 100); 1704 int value = getInteger(component, "value", 0); 1705 boolean horizontal = ("vertical" != get(component, "orientation")); 1706 int length = (value - minimum) * 1707 ((horizontal ? bounds.width : bounds.height) - 1) / (maximum - minimum); 1708 paintRect(g, 0, 0, horizontal ? length : bounds.width, 1709 horizontal ? bounds.height : length, enabled ? c_border : c_disable, 1710 c_select, true, true, horizontal, !horizontal, true); 1711 paintRect(g, horizontal ? length : 0, horizontal ? 0 : length, 1712 horizontal ? (bounds.width - length) : bounds.width , 1713 horizontal ? bounds.height : (bounds.height - length), 1714 enabled ? c_border : c_disable, c_bg, true, true, true, true, true); 1715 } 1716 else if ("slider" == classname) { 1717 int minimum = getInteger(component, "minimum", 0); 1718 int maximum = getInteger(component, "maximum", 100); 1719 int value = getInteger(component, "value", 0); 1720 boolean horizontal = ("vertical" != get(component, "orientation")); 1721 int length = (value - minimum) * 1722 ((horizontal ? bounds.width : bounds.height) - block) / 1723 (maximum - minimum); 1724 paintRect(g, horizontal ? 0 : 3, horizontal ? 3 : 0, 1725 horizontal ? length : (bounds.width - 6), 1726 horizontal ? (bounds.height - 6) : length, 1727 enabled ? c_border : c_disable, 1728 c_bg, true, true, horizontal, !horizontal, true); 1729 paintRect(g, horizontal ? length : 0, horizontal ? 0 : length, 1730 horizontal ? block : bounds.width, horizontal ? bounds.height : block, 1731 enabled ? c_border : c_disable, 1732 enabled ? c_ctrl : c_bg, true, true, true, true, true); 1733 if (focus) { 1734 g.setColor(c_focus); 1735 g.drawRect(horizontal ? (length + 2) : 2, horizontal ? 2 : (length + 2), 1736 (horizontal ? block : bounds.width) - 5, 1737 (horizontal ? bounds.height : block) - 5); 1738 } 1740 paintRect(g, horizontal ? (block + length) : 3, 1741 horizontal ? 3 : (block + length), 1742 bounds.width - (horizontal ? (block + length) : 6), 1743 bounds.height - (horizontal ? 6 : (block + length)), 1744 enabled ? c_border : c_disable, 1745 c_bg, horizontal, !horizontal, true, true, true); 1746 } 1747 else if ("splitpane" == classname) { 1748 boolean horizontal = ("vertical" != get(component, "orientation")); 1749 int divider = getInteger(component, "divider", -1); 1750 paintRect(g, horizontal ? divider : 0, horizontal ? 0 : divider, 1751 horizontal ? 5 : bounds.width, horizontal ? bounds.height : 5, 1752 c_border, c_bg, false, false, false, false, true); 1753 g.setColor(enabled ? (focus ? c_focus : c_border) : c_disable); 1754 int xy = horizontal ? bounds.height : bounds.width; 1755 int xy1 = Math.max(0, xy / 2 - 12); 1756 int xy2 = Math.min(xy / 2 + 12, xy - 1); 1757 for (int i = divider + 1; i < divider + 4; i += 2) { 1758 if (horizontal) { g.drawLine(i, xy1, i, xy2); } 1759 else { g.drawLine(xy1, i, xy2, i); } 1760 } 1761 Object comp1 = get(component, ":comp"); 1762 if (comp1 != null) { 1763 paint(g, clipx, clipy, clipwidth, clipheight, comp1, enabled); 1764 Object comp2 = get(comp1, ":next"); 1765 if (comp2 != null) { 1766 paint(g, clipx, clipy, clipwidth, clipheight, comp2, enabled); 1767 } 1768 } 1769 } 1770 else if (("list" == classname) || 1771 ("table" == classname) || ("tree" == classname)) { 1772 paintScroll(component, classname, pressed, inside, focus, enabled, 1773 g, clipx, clipy, clipwidth, clipheight); 1774 } 1775 else if ("separator" == classname) { 1776 g.setColor(enabled ? c_border : c_disable); 1777 g.fillRect(0, 0, bounds.width + evm, bounds.height + evm); 1778 } 1779 else if ("menubar" == classname) { 1780 Object selected = get(component, "selected"); 1781 boolean bottom = ("bottom" == get(component, "placement")); 1782 int lastx = 0; 1783 for (Object menu = get(component, ":comp"); 1784 menu != null; menu = get(menu, ":next")) { 1785 Rectangle mb = getRectangle(menu, "bounds"); 1786 if (clipx + clipwidth <= mb.x) { break; } 1787 if (clipx >= mb.x + mb.width) { continue; } 1788 boolean menuenabled = enabled && getBoolean(menu, "enabled", true); 1789 boolean armed = (selected == menu); 1790 boolean hoover = (selected == null) && (insidepart == menu); 1791 paint(menu, mb.x, 0, mb.width, bounds.height, 1792 g, clipx, clipy, clipwidth, clipheight, bottom || armed, armed, !bottom || armed, armed, 1, 3, 1, 3, false, 1794 enabled ? (menuenabled ? (armed ? 's' : (hoover ? 'h' : 'g')) : 'r') : 'd', "left", true, false); 1795 lastx = mb.x + mb.width; 1796 } 1797 paintRect(g, lastx, 0, bounds.width - lastx, bounds.height, 1798 enabled ? c_border : c_disable, enabled ? c_ctrl : c_bg, 1799 bottom, false, !bottom, false, true); 1800 } 1801 else if (":popup" == classname) { 1802 paintRect(g, 0, 0, bounds.width, bounds.height, 1803 c_border, c_textbg, true, true, true, true, true); 1804 Object selected = get(component, "selected"); 1805 for (Object menu = get(get(component, "menu"), ":comp"); 1806 menu != null; menu = get(menu, ":next")) { 1807 Rectangle r = getRectangle(menu, "bounds"); 1808 if (clipy + clipheight <= r.y) { break; } 1809 if (clipy >= r.y + r.height) { continue; } 1810 String itemclass = getClass(menu); 1811 if (itemclass == "separator") { 1812 g.setColor(c_border); 1813 g.fillRect(r.x, r.y, bounds.width - 2 + evm, r.height + evm); 1814 } else { 1815 boolean armed = (selected == menu); 1816 boolean menuenabled = getBoolean(menu, "enabled", true); 1817 paint(menu, r.x, r.y, bounds.width - 2, r.height, 1818 g, clipx, clipy, clipwidth, clipheight, false, false, false, false, 1819 2, (itemclass == "checkboxmenuitem") ? (block + 7) : 4, 2, 4, false, 1820 menuenabled ? (armed ? 's' : 't') : 'd', "left", true, false); 1821 if (itemclass == "checkboxmenuitem") { 1822 boolean checked = getBoolean(menu, "selected", false); 1823 String group = getString(menu, "group", null); 1824 g.translate(r.x + 4, r.y + 2); 1825 g.setColor(menuenabled ? c_border : c_disable); 1826 if (group == null) { 1827 g.drawRect(1, 1, block - 3, block - 3); 1828 } else { 1829 g.drawOval(1, 1, block - 3, block - 3); 1830 } 1831 if (checked) { 1832 g.setColor(menuenabled ? c_text : c_disable); 1833 if (group == null) { 1834 g.fillRect(3, block - 9, 2 + evm, 6 + evm); 1835 g.drawLine(3, block - 4, block - 4, 3); 1836 g.drawLine(4, block - 4, block - 4, 4); 1837 } else { 1838 g.fillOval(5, 5, block - 10 + evm, block - 10 + evm); 1839 g.drawOval(4, 4, block - 9, block - 9); 1840 } 1841 } 1842 g.translate(-r.x - 4, -r.y - 2); 1843 } 1844 if (itemclass == "menu") { 1845 paintArrow(g, r.x + bounds.width - block, r.y, block, r.height, 'E'); 1846 } 1847 else { 1848 String accelerator = getAccelerator(menu); 1849 if (accelerator != null) { g.drawString(accelerator, bounds.width - 4 - 1851 getFontMetrics(font).stringWidth(accelerator), r.y + 2 + 10); 1852 } 1853 } 1854 } 1855 } 1856 } 1857 else if ("bean" == classname) { 1858 g.clipRect(0, 0, bounds.width, bounds.height); 1859 ((Component) get(component, "bean")).paint(g); 1860 g.setClip(clipx, clipy, clipwidth, clipheight); 1861 } 1862 else throw new IllegalArgumentException (classname); 1863 g.translate(-bounds.x, -bounds.y); 1864 clipx += bounds.x; clipy += bounds.y; 1865 } 1866 1867 1870 private void paintReverse(Graphics g, 1871 int clipx, int clipy, int clipwidth, int clipheight, 1872 Object component, boolean enabled) { 1873 if (component != null) { 1874 Rectangle bounds = getRectangle(component, "bounds"); 1875 if ((clipx < bounds.x) || 1876 (clipx + clipwidth > bounds.x + bounds.width) || 1877 (clipy < bounds.y) || 1878 (clipy + clipheight > bounds.y + bounds.height)) { 1879 paintReverse(g, clipx, clipy, clipwidth, clipheight, 1880 get(component, ":next"), enabled); 1881 } 1882 paint(g, clipx, clipy, clipwidth, clipheight, component, enabled); 1883 } 1884 } 1885 1886 1889 private void paintField(Graphics g, 1890 int clipx, int clipy, int clipwidth, int clipheight, Object component, 1891 int width, int height, 1892 boolean focus, boolean enabled, boolean hidden, int left) { 1893 boolean editable = getBoolean(component, "editable", true); 1894 paintRect(g, 0, 0, width, height, enabled ? c_border : c_disable, 1895 editable ? c_textbg : c_bg, true, true, true, true, true); 1896 g.clipRect(1 + left, 1, width - left - 2, height - 2); 1897 1898 String text = getString(component, "text", ""); 1899 int offset = getInteger(component, ":offset", 0); 1900 Font currentfont = (Font) get(component, "font"); 1901 if (currentfont != null) { g.setFont(currentfont); } 1902 FontMetrics fm = g.getFontMetrics(); 1903 1904 int caret = 0; 1905 if (focus) { 1906 int start = getInteger(component, "start", 0); 1907 int end = getInteger(component, "end", 0); 1908 caret = hidden ? (fm.charWidth('*') * end) : 1909 fm.stringWidth(text.substring(0, end)); 1910 if (start != end) { 1911 int is = hidden ? (fm.charWidth('*') * start) : 1912 fm.stringWidth(text.substring(0, start)); 1913 g.setColor(c_select); 1914 g.fillRect(2 + left - offset + Math.min(is, caret), 1, 1915 Math.abs(caret - is) + evm, height - 2 + evm); 1916 } 1917 } 1918 1919 if (focus) { 1920 g.setColor(c_focus); 1921 g.fillRect(1 + left - offset + caret, 1, 1 + evm, height - 2 + evm); 1922 } 1923 1924 g.setColor(enabled ? c_text : c_disable); 1925 int fx = 2 + left - offset; 1926 int fy = (height + fm.getAscent() - fm.getDescent()) / 2; 1927 if (hidden) { 1928 int fh = fm.charWidth('*'); 1929 for (int i = text.length(); i > 0; i--) { 1930 g.drawString("*", fx, fy); 1931 fx += fh; 1932 } 1933 } else { 1934 g.drawString(text, fx, fy); 1935 } 1936 if (currentfont != null) { g.setFont(font); } 1937 g.setClip(clipx, clipy, clipwidth, clipheight); 1938 } 1939 1940 1956 private void paintScroll(Object component, String classname, 1957 boolean pressed, boolean inside, boolean focus, boolean enabled, 1958 Graphics g, int clipx, int clipy, int clipwidth, int clipheight) { 1959 Rectangle port = getRectangle(component, ":port"); 1960 Rectangle horizontal = getRectangle(component, ":horizontal"); 1961 Rectangle vertical = getRectangle(component, ":vertical"); 1962 Rectangle view = getRectangle(component, ":view"); 1963 1964 if (horizontal != null) { int x = horizontal.x; int y = horizontal.y; int width = horizontal.width; int height = horizontal.height; 1966 paintArrow(g, x, y, block, height, 1967 'W', enabled, inside, pressed, "left", true, true, true, false, true); 1968 paintArrow(g, x + width - block, y, block, height, 1969 'E', enabled, inside, pressed, "right", true, false, true, true, true); 1970 1971 int track = width - (2 * block); 1972 if (track < 10) { 1973 paintRect(g, x + block, y, track, height, 1974 enabled ? c_border : c_disable, c_bg, true, true, true, true, true); 1975 } 1976 else { 1977 int knob = Math.max(track * port.width / view.width, 10); 1978 int decrease = view.x * (track - knob) / (view.width - port.width); 1979 paintRect(g, x + block, y, decrease, height, 1980 enabled ? c_border : c_disable, c_bg, false, true, true, false, true); 1981 paintRect(g, x + block + decrease, y, knob, height, 1982 enabled ? c_border : c_disable, enabled ? c_ctrl : c_bg, true, true, true, true, true); 1983 int n = Math.min(5, (knob - 4) / 3); 1984 g.setColor(enabled ? c_border : c_disable); 1985 int cx = (x + block + decrease) + (knob + 2 - n * 3) / 2; 1986 for (int i = 0; i < n; i++ ) { 1987 g.drawLine(cx + i * 3, y + 3, cx + i * 3, y + height - 5); 1988 } 1989 int increase = track - decrease - knob; 1990 paintRect(g, x + block + decrease + knob, y, increase, height, 1991 enabled ? c_border : c_disable, c_bg, false, false, true, true, true); 1992 } 1993 } 1994 1995 if (vertical != null) { int x = vertical.x; int y = vertical.y; int width = vertical.width; int height = vertical.height; 1997 paintArrow(g, x, y, width, block, 1998 'N', enabled, inside, pressed, "up", true, true, false, true, false); 1999 paintArrow(g, x, y + height - block, width, block, 2000 'S', enabled, inside, pressed, "down", false, true, true, true, false); 2001 2002 int track = height - (2 * block); 2003 if (track < 10) { 2004 paintRect(g, x, y + block, width, track, 2005 enabled ? c_border : c_disable, c_bg, true, true, true, true, false); 2006 } 2007 else { 2008 int knob = Math.max(track * port.height / view.height, 10); 2009 int decrease = view.y * (track - knob) / (view.height - port.height); 2010 paintRect(g, x, y + block, width, decrease, 2011 enabled ? c_border : c_disable, c_bg, true, false, false, true, false); 2012 paintRect(g, x, y + block + decrease, width, knob, 2013 enabled ? c_border : c_disable, enabled ? c_ctrl : c_bg, true, true, true, true, false); 2014 int n = Math.min(5, (knob - 4) / 3); 2015 g.setColor(enabled ? c_border : c_disable); 2016 int cy = (y + block + decrease) + (knob + 2 - n * 3) / 2; 2017 for (int i = 0; i < n; i++ ) { 2018 g.drawLine(x + 3, cy + i * 3, x + width - 5, cy + i * 3); 2019 } 2020 int increase = track - decrease - knob; 2021 paintRect(g, x, y + block + decrease + knob, width, increase, 2022 enabled ? c_border : c_disable, c_bg, false, false, true, true, false); 2023 } 2024 } 2025 2026 boolean hneed = (horizontal != null); boolean vneed = (vertical != null); 2027 if (("panel" != classname) && ("dialog" != classname) && 2028 (("textarea" != classname) || getBoolean(component, "border", true))) { 2029 paintRect(g, port.x - 1, port.y - 1, port.width + (vneed ? 1 : 2), port.height + (hneed ? 1 : 2), 2030 enabled ? c_border : c_disable, c_textbg, true, true, !hneed, !vneed, true); 2031 if ("table" == classname) { 2032 Object header = get(component, "header"); 2033 if (header != null) { 2034 int[] columnwidths = (int []) get(component, ":widths"); 2035 Object column = get(header, ":comp"); int x = 0; 2036 g.clipRect(0, 0, port.width + 2, port.y); for (int i = 0; i < columnwidths.length; i++) { 2038 if (i != 0) { column = get(column, ":next"); } 2039 boolean lastcolumn = (i == columnwidths.length - 1); 2040 int width = lastcolumn ? (view.width - x + 2) : columnwidths[i]; 2041 2042 paint(column, x - view.x, 0, width, port.y - 1, 2043 g, clipx, clipy, clipwidth, clipheight, 2044 true, true, false, lastcolumn, 1, 1, 0, 0, false, 2045 enabled ? 'g' : 'd', "left", false, false); 2046 2047 Object sort = get(column, "sort"); if (sort != null) { 2049 paintArrow(g, x - view.x + width - block, 0, block, port.y, 2050 (sort == "ascent") ? 'S' : 'N'); 2051 } 2052 x += width; 2053 } 2054 g.setClip(clipx, clipy, clipwidth, clipheight); 2055 } 2056 } 2057 } 2058 int x1 = Math.max(clipx, port.x); 2059 int x2 = Math.min(clipx + clipwidth, port.x + port.width); 2060 int y1 = Math.max(clipy, port.y); 2061 int y2 = Math.min(clipy + clipheight, port.y + port.height); 2062 if ((x2 > x1) && (y2 > y1)) { 2063 g.clipRect(x1, y1, x2 - x1, y2 - y1); 2064 g.translate(port.x - view.x, port.y - view.y); 2065 2066 paint(component, classname, focus, enabled, 2067 g, view.x - port.x + x1, view.y - port.y + y1, x2 - x1, y2 - y1, port.width, view.width); 2068 2069 g.translate(view.x - port.x, view.y - port.y); 2070 g.setClip(clipx, clipy, clipwidth, clipheight); 2071 } 2072 } 2073 2074 2078 private void paint(Object component, 2079 String classname, boolean focus, boolean enabled, 2080 Graphics g, int clipx, int clipy, int clipwidth, int clipheight, 2081 int portwidth, int viewwidth) { 2082 if ("textarea" == classname) { 2083 char[] chars = (char[]) get(component, ":text"); 2084 int start = focus ? getInteger(component, "start", 0) : 0; 2085 int end = focus ? getInteger(component, "end", 0) : 0; 2086 int is = Math.min(start, end); int ie = Math.max(start, end); 2087 Font customfont = (Font) get(component, "font"); 2088 if (customfont != null) { g.setFont(customfont); } 2089 FontMetrics fm = g.getFontMetrics(); 2090 int fontascent = fm.getAscent(); int fontheight = fm.getHeight(); 2091 int ascent = 1; 2092 2093 for (int i = 0, j = 0; j <= chars.length; j++) { 2094 if ((j == chars.length) || (chars[j] == '\n')) { 2095 if (clipy + clipheight <= ascent) { break; } if (clipy < ascent + fontheight) { if (focus && (is != ie) && (ie >= i) && (is <= j)) { 2098 int xs = (is < i) ? -1 : ((is > j) ? (viewwidth - 1) : 2099 fm.charsWidth(chars, i, is - i)); 2100 int xe = ((j != -1) && (ie > j)) ? (viewwidth - 1) : 2101 fm.charsWidth(chars, i, ie - i); 2102 g.setColor(c_select); 2103 g.fillRect(1 + xs, ascent, xe - xs + evm, fontheight + evm); 2104 } 2105 g.setColor(enabled ? c_text : c_disable); 2106 g.drawChars(chars, i, j - i, 1, ascent + fontascent); 2107 if (focus && (end >= i) && (end <= j)) { 2108 int caret = fm.charsWidth(chars, i, end - i); 2109 g.setColor(c_focus); 2110 g.fillRect(caret, ascent, 1 + evm, fontheight + evm); 2111 } 2112 } 2113 ascent += fontheight; 2114 i = j + 1; 2115 } 2116 } 2117 if (customfont != null) { g.setFont(font); } } 2119 else if (":combolist" == classname) { 2120 Object lead = get(component, ":lead"); 2121 for (Object choice = get(get(component, "combobox"), ":comp"); 2122 choice != null; choice = get(choice, ":next")) { 2123 Rectangle r = getRectangle(choice, "bounds"); 2124 if (clipy + clipheight <= r.y) { break; } 2125 if (clipy >= r.y + r.height) { continue; } 2126 paint(choice, r.x, r.y, portwidth, r.height, 2127 g, clipx, clipy, clipwidth, clipheight, 2128 false, false, false, false, 2, 4, 2, 4, false, 2129 getBoolean(choice, "enabled", true) ? ((lead == choice) ? 's' : 't') : 'd', 2130 "left", false, false); 2131 } 2132 } 2133 else if (("panel" == classname) || ("dialog" == classname)) { 2134 for (Object comp = get(component, ":comp"); 2135 comp != null; comp = get(comp, ":next")) { 2136 paint(g, clipx, clipy, clipwidth, clipheight, comp, enabled); 2137 } 2138 } 2139 else { Object lead = get(component, ":lead"); 2141 int[] columnwidths = ("table" == classname) ? ((int []) get(component, ":widths")) : null; 2142 boolean line = getBoolean(component, "line", true); int iline = line ? 1 : 0; 2143 boolean angle = ("tree" == classname) && getBoolean(component, "angle", false); 2144 for (Object item = get(component, ":comp"), next = null; item != null; item = next) { 2145 if (focus && (lead == null)) { 2146 set(component, ":lead", lead = item); } 2148 Rectangle r = getRectangle(item, "bounds"); 2149 if (clipy + clipheight <= r.y) { break; } boolean subnode = false; boolean expanded = false; 2151 if ("tree" != classname) { 2152 next = get(item, ":next"); 2153 } 2154 else { 2155 subnode = (next = get(item, ":comp")) != null; 2156 expanded = subnode && getBoolean(item, "expanded", true); 2157 if (!expanded) { 2158 for (Object node = item; (node != component) && 2159 ((next = get(node, ":next")) == null); node = getParent(node)); 2160 } 2161 } 2162 if (clipy >= r.y + r.height + iline) { 2163 if (angle) { 2164 Object nodebelow = get(item, ":next"); 2165 if (nodebelow != null) { g.setColor(c_bg); int x = r.x - block / 2; 2167 g.drawLine(x, r.y, x, getRectangle(nodebelow, "bounds").y); 2168 } 2169 } 2170 continue; } 2172 2173 boolean selected = getBoolean(item, "selected", false); 2174 boolean focused = focus && (lead == item); 2175 paintRect(g, ("tree" != classname) ? 0 : r.x, r.y, 2176 ("tree" != classname) ? viewwidth : r.width, r.height, c_focus, 2177 selected ? c_select : c_textbg, focused, focused, focused, focused, true); 2178 if (line) { 2179 g.setColor(c_bg); 2180 g.drawLine(0, r.y + r.height, viewwidth, r.y + r.height); 2181 } 2182 if ("table" != classname) { boolean itemenabled = enabled && getBoolean(item, "enabled", true); 2184 paint(item, r.x, r.y, viewwidth, r.height, 2185 g, clipx, clipy, clipwidth, clipheight, false, false, false, false, 2186 1, 3, 1, 3, false, itemenabled ? 'e' : 'd', "left", false, false); 2187 if ("tree" == classname) { 2188 int x = r.x - block / 2; int y = r.y + (r.height - 1) / 2; 2189 if (angle) { 2190 g.setColor(c_bg); 2191 g.drawLine(x, r.y, x, y); g.drawLine(x, y, r.x - 1, y); 2192 Object nodebelow = get(item, ":next"); 2193 if (nodebelow != null) { 2194 g.drawLine(x, y, x, getRectangle(nodebelow, "bounds").y); 2195 } 2196 } 2197 if (subnode) { 2198 paintRect(g, x - 4, y - 4, 9, 9, itemenabled ? c_border : c_disable, 2199 itemenabled ? c_ctrl : c_bg, true, true, true, true, true); 2200 g.setColor(itemenabled ? c_text : c_disable); 2201 g.drawLine(x - 2, y, x + 2, y); 2202 if (!expanded) { g.drawLine(x, y - 2, x, y + 2); } 2203 } 2204 } 2205 } 2206 else { int i = 0; int x = 0; 2208 for (Object cell = get(item, ":comp"); cell != null; cell = get(cell, ":next")) { 2209 if (clipx + clipwidth <= x) { break; } 2210 int iwidth = 80; 2212 if ((columnwidths != null) && (columnwidths.length > i)) { 2213 iwidth = (i != columnwidths.length - 1) ? 2214 columnwidths[i] : Math.max(iwidth, viewwidth - x); 2215 } 2216 if (clipx < x + iwidth) { 2217 boolean cellenabled = enabled && getBoolean(cell, "enabled", true); 2218 paint(cell, r.x + x, r.y, iwidth, r.height - 1, 2219 g, clipx, clipy, clipwidth, clipheight, false, false, false, false, 2220 1, 1, 1, 1, false, cellenabled ? 'e' : 'd', "left", false, false); 2221 } 2222 i++; x += iwidth; 2223 } 2224 } 2225 } 2226 } 2227 } 2228 2229 2232 private void paintRect(Graphics g, int x, int y, int width, int height, 2233 Color border, Color bg, 2234 boolean top, boolean left, boolean bottom, boolean right, boolean horizontal) { 2235 if ((width <= 0) || (height <= 0)) return; 2236 g.setColor(border); 2237 if (top) { 2238 g.drawLine(x + width - 1, y, x, y); 2239 y++; height--; if (height <= 0) return; 2240 } 2241 if (left) { 2242 g.drawLine(x, y, x, y + height - 1); 2243 x++; width--; if (width <= 0) return; 2244 } 2245 if (bottom) { 2246 g.drawLine(x, y + height - 1, x + width - 1, y + height - 1); 2247 height--; if (height <= 0) return; 2248 } 2249 if (right) { 2250 g.drawLine(x + width - 1, y + height - 1, x + width - 1, y); 2251 width--; if (width <= 0) return; 2252 } 2253 2254 if (bg == c_ctrl) { 2255 fill(g, x, y, width, height, horizontal); 2256 } 2257 else { 2258 g.setColor(bg); 2259 g.fillRect(x, y, width + evm, height + evm); 2260 } 2261 } 2262 2263 2266 private void fill(Graphics g, int x, int y, int width, int height, boolean horizontal) { 2267 if (horizontal) { 2268 if (height > block) { 2269 g.setColor(c_bg); 2270 g.fillRect(x, y, width + evm, height - block + evm); 2271 } 2272 for (int i = 0; i < width; i += block) { 2273 g.drawImage(hgradient, x + i, (height > block) ? (y + height - block) : y, 2274 x + Math.min(i + block, width) + evm, y + height + evm, 2275 0, 0, Math.min(block, width - i) + evm, Math.min(block, height) + evm, null); 2276 } 2277 } 2278 else { 2279 if (width > block) { 2280 g.setColor(c_bg); 2281 g.fillRect(x, y, width - block + evm, height + evm); 2282 } 2283 for (int i = 0; i < height; i += block) { 2284 g.drawImage(vgradient, (width > block) ? (x + width - block) : x, y + i, 2285 x + width + evm, y + Math.min(i + block, height) + evm, 2286 0, 0, Math.min(block, width) + evm, Math.min(block, height - i) + evm, null); 2287 } 2288 } 2289 } 2290 2291 2294 private void paintArrow(Graphics g, int x, int y, int width, int height, 2295 char dir, boolean enabled, boolean inside, boolean pressed, String part, 2296 boolean top, boolean left, boolean bottom, boolean right, boolean horizontal) { 2297 inside = inside && (insidepart == part); 2298 pressed = pressed && (pressedpart == part); 2299 paintRect(g, x, y, width, height, enabled ? c_border : c_disable, 2300 enabled ? ((inside != pressed) ? c_hover : 2301 (pressed ? c_press : c_ctrl)) : c_bg, 2302 top, left, bottom, right, horizontal); 2303 g.setColor(enabled ? c_text : c_disable); 2304 paintArrow(g, x + (left ? 1 : 0), y + (top ? 1 : 0), 2305 width - (left ? 1 : 0) - (right ? 1 : 0), height - (top ? 1 : 0) - (bottom ? 1 : 0), dir); 2306 } 2307 2308 2311 private void paintArrow(Graphics g, 2312 int x, int y, int width, int height, char dir) { 2313 int cx = x + width / 2 - 2; 2314 int cy = y + height / 2 - 2; 2315 for (int i = 0; i < 4; i++) { 2316 if (dir == 'N') { g.drawLine(cx + 1 - i, cy + i, cx + 1 + i, cy + i); 2318 } 2319 else if (dir == 'W') { g.drawLine(cx + i, cy + 1 - i, cx + i, cy + 1 + i); 2321 } 2322 else if (dir == 'S') { g.drawLine(cx + 1 - i, cy + 4 - i, cx + 1 + i, cy + 4 - i); 2324 } 2325 else { g.drawLine(cx + 4 - i, cy + 1 - i, cx + 4 - i, cy + 1 + i); 2327 } 2328 } 2329 } 2330 2331 2334 private void paint(Object component, int x, int y, int width, int height, 2335 Graphics g, boolean top, boolean left, boolean bottom, boolean right, 2336 char mode) { 2337 if ((width <= 0) || (height <= 0)) { return; } 2338 2339 if (top || left || bottom || right) { g.setColor(((mode != 'd') && (mode != 'i')) ? c_border : c_disable); 2341 if (top) { 2342 g.drawLine(x + width - 1, y, x, y); 2343 y++; height--; if (height <= 0) { return; } 2344 } 2345 if (left) { 2346 g.drawLine(x, y, x, y + height - 1); 2347 x++; width--; if (width <= 0) { return; } 2348 } 2349 if (bottom) { 2350 g.drawLine(x, y + height - 1, x + width - 1, y + height - 1); 2351 height--; if (height <= 0) { return; } 2352 } 2353 if (right) { 2354 g.drawLine(x + width - 1, y + height - 1, x + width - 1, y); 2355 width--; if (width <= 0) { return; } 2356 } 2357 } 2358 2359 Color background = (Color) get(component, "background"); 2360 switch (mode) { 2361 case 'e': case 'l': case 'd': case 'g': case 'r': break; 2362 case 'b': case 'i': case 'x': if (background == null) { background = c_bg; } break; 2363 case 'h': background = (background != null) ? background.brighter() : c_hover; break; 2364 case 'p': background = (background != null) ? background.darker() : c_press; break; 2365 case 't': if (background == null) { background = c_textbg; } break; 2366 case 's': background = c_select; break; 2367 default: throw new IllegalArgumentException (); 2368 } 2369 if (((mode == 'g') || (mode == 'r')) && (background == null)) { 2370 fill(g, x, y, width, height, true); 2371 } 2372 else if (background != null) { 2373 g.setColor(background); 2374 if (mode != 'x') { g.fillRect(x, y, width + evm, height + evm); } 2375 } 2376 } 2377 2378 2381 private void paint(Object component, Graphics g, 2382 int x, int y, int width, int height, char type) { 2383 paint(component, x, y, width, height, g, true, true, true, true, 'g'); 2384 g.setColor(Color.black); 2385 switch (type) { 2386 case 'c': g.drawLine(x + 3, y + 4, x + width - 5, y + height - 4); 2388 g.drawLine(x + 3, y + 3, x + width - 4, y + height - 4); 2389 g.drawLine(x + 4, y + 3, x + width - 4, y + height - 5); 2390 g.drawLine(x + width - 5, y + 3, x + 3, y + height - 5); 2391 g.drawLine(x + width - 4, y + 3, x + 3, y + height - 4); 2392 g.drawLine(x + width - 4, y + 4, x + 4, y + height - 4); 2393 break; 2394 case 'm': g.drawRect(x + 3, y + 3, width - 7, height - 7); 2396 g.drawLine(x + 4, y + 4, x + width - 5, y + 4); 2397 break; 2398 case 'i': g.fillRect(x + 3, y + height - 5, width - 6, 2); 2400 break; 2401 } 2402 } 2403 2404 2408 private void paint(Object component, int x, int y, int width, int height, 2409 Graphics g, int clipx, int clipy, int clipwidth, int clipheight, 2410 boolean top, boolean left, boolean bottom, boolean right, 2411 int toppadding, int leftpadding, int bottompadding, int rightpadding, boolean focus, 2412 char mode, String alignment, boolean mnemonic, boolean underline) { 2413 paint(component, x, y, width, height, 2414 g, top, left, bottom, right, mode); 2415 if (top) { y++; height--; } if (left) { x++; width--; } 2416 if (bottom) { height--; } if (right) { width--; } 2417 if ((width <= 0) || (height <= 0)) { return; } 2418 2419 if (focus) { 2420 g.setColor(c_focus); 2421 g.drawRect(x + 1, y + 1, width - 3, height - 3); 2422 } 2423 2424 String text = getString(component, "text", null); 2425 Image icon = getIcon(component, "icon", null); 2426 if ((text == null) && (icon == null)) { return; } 2427 2428 x += leftpadding; y += toppadding; 2429 width -= leftpadding + rightpadding; height -= toppadding + bottompadding; 2430 2431 alignment = getString(component, "alignment", alignment); 2432 Font customfont = (text != null) ? (Font) get(component, "font") : null; 2433 if (customfont != null) { g.setFont(customfont); } 2434 2435 FontMetrics fm = null; 2436 int tw = 0, th = 0; 2437 int ta = 0; 2438 if (text != null) { 2439 fm = g.getFontMetrics(); 2440 tw = fm.stringWidth(text); 2441 ta = fm.getAscent(); 2442 th = fm.getDescent() + ta; 2443 } 2444 int iw = 0, ih = 0; 2445 if (icon != null) { 2446 iw = icon.getWidth(this); 2447 ih = icon.getHeight(this); 2448 if (text != null) { iw += 2; } 2449 } 2450 2451 boolean clipped = (tw + iw > width) || (th > height) || (ih > height); 2452 int cx = x; 2453 if ("center" == alignment) { cx += (width - tw - iw) / 2; } 2454 else if ("right" == alignment) { cx += width - tw - iw; } 2455 2456 if (clipped) { g.clipRect(x, y, width, height); } 2457 if (mode == 'x') { g.drawLine(cx, y + height / 2, cx + iw + tw, y + height / 2); } 2458 if (icon != null) { 2459 g.drawImage(icon, cx, y + (height - ih) / 2, this); 2460 cx += iw; 2461 } 2462 if (text != null) { 2463 Color foreground = (Color) get(component, "foreground"); 2464 if (foreground == null) { 2465 foreground = (mode == 'l') ? Color.blue : 2466 (((mode != 'd') && (mode != 'r')) ? c_text : c_disable); 2467 } 2468 g.setColor(foreground); 2469 int ty = y + (height - th) / 2 + ta; 2470 g.drawString(text, cx, ty); 2471 if (mnemonic) { 2472 int imnemonic = getInteger(component, "mnemonic", -1); 2473 if ((imnemonic != -1) && (imnemonic < text.length())) { 2474 int mx = cx + fm.stringWidth(text.substring(0, imnemonic)); 2475 g.drawLine(mx, ty + 1, mx + fm.charWidth(text.charAt(imnemonic)), ty + 1); 2476 } 2477 } 2478 if (underline) { g.drawLine(cx, ty + 1, cx + tw, ty + 1); 2480 } 2481 } 2482 if (clipped) { g.setClip(clipx, clipy, clipwidth, clipheight); } 2483 2484 if (customfont != null) { g.setFont(font); } } 2486 2487 2491 public synchronized void run() { 2492 while (timer == Thread.currentThread()) { 2493 try { 2494 if (watch == 0) { 2495 wait(0); 2496 } else { 2497 long current = System.currentTimeMillis(); 2498 if (watch > current) { 2499 wait(watch - current); 2500 } else { 2501 watch = 0; 2502 if ((watchdelay == 300L) || (watchdelay == 60L)) { 2503 if (processScroll(mousepressed, pressedpart)) { setTimer(60L); } 2504 } else if ((watchdelay == 375L) || (watchdelay == 75L)) { 2505 if (processSpin(mousepressed, pressedpart)) { setTimer(75L); } 2506 } else if (watchdelay == 750L) { 2507 showTip(); 2508 } 2509 } 2510 } 2511 } catch (InterruptedException ie) {} } 2513 } 2514 2515 2518 private void setTimer(long delay) { 2519 watchdelay = delay; 2520 if (delay == 0) { 2521 watch = 0; 2522 } else { 2523 long prev = watch; 2524 watch = System.currentTimeMillis() + delay; 2525 if (timer == null) { 2526 timer = new Thread (this); 2527 timer.setPriority(Thread.MIN_PRIORITY); 2528 timer.setDaemon(true); 2529 timer.start(); 2530 } 2531 if ((prev == 0) || (watch < prev)) { 2532 synchronized (this) { notify(); } 2533 } 2535 } 2536 } 2537 2538 2545 public boolean isFocusTraversable() { 2546 return true; 2547 } 2548 2549 2553 protected void processEvent(AWTEvent e) { 2554 int id = e.getID(); 2556 if ((id == MouseEvent.MOUSE_ENTERED) || (id == MouseEvent.MOUSE_MOVED) || 2557 (id == MouseEvent.MOUSE_EXITED) || (id == MouseEvent.MOUSE_PRESSED) || 2558 (id == MouseEvent.MOUSE_DRAGGED) || (id == MouseEvent.MOUSE_RELEASED)) { 2559 MouseEvent me = (MouseEvent) e; 2560 int x = me.getX(); 2561 int y = me.getY(); 2562 int clickcount = me.getClickCount(); 2563 boolean shiftdown = me.isShiftDown(); 2564 boolean controldown = me.isControlDown(); 2565 boolean popuptrigger = me.isPopupTrigger(); 2566 if (id == MouseEvent.MOUSE_ENTERED) { 2567 if (mousepressed == null) { 2568 findComponent(content, x, y); 2569 handleMouseEvent(x, y, clickcount, shiftdown, controldown, popuptrigger, 2570 MouseEvent.MOUSE_ENTERED, mouseinside, insidepart); 2571 } 2572 } 2573 else if (id == MouseEvent.MOUSE_MOVED) { 2574 Object previnside = mouseinside; 2575 Object prevpart = insidepart; 2576 findComponent(content, x, y); 2577 if ((previnside == mouseinside) && (prevpart == insidepart)) { 2578 handleMouseEvent(x, y, clickcount, shiftdown, controldown, popuptrigger, 2579 MouseEvent.MOUSE_MOVED, mouseinside, insidepart); 2580 } 2581 else { 2582 handleMouseEvent(x, y, clickcount, shiftdown, controldown, popuptrigger, 2583 MouseEvent.MOUSE_EXITED, previnside, prevpart); 2584 handleMouseEvent(x, y, clickcount, shiftdown, controldown, popuptrigger, 2585 MouseEvent.MOUSE_ENTERED, mouseinside, insidepart); 2586 } 2587 } 2588 else if (id == MouseEvent.MOUSE_EXITED) { 2589 if (mousepressed == null) { 2590 Object mouseexit = mouseinside; 2591 Object exitpart = insidepart; 2592 mouseinside = insidepart = null; 2593 handleMouseEvent(x, y, clickcount, shiftdown, controldown, popuptrigger, 2594 MouseEvent.MOUSE_EXITED, mouseexit, exitpart); 2595 } 2596 } 2597 else if (id == MouseEvent.MOUSE_PRESSED) { 2598 if (popupowner != null) { String classname = getClass(mouseinside); 2600 if ((popupowner != mouseinside) && 2601 (classname != ":popup") && (classname != ":combolist")) { 2602 closeup(); 2603 } 2604 } 2605 hideTip(); mousepressed = mouseinside; 2607 pressedpart = insidepart; 2608 handleMouseEvent(x, y, clickcount, shiftdown, controldown, popuptrigger, 2609 MouseEvent.MOUSE_PRESSED, mousepressed, pressedpart); 2610 } 2611 else if (id == MouseEvent.MOUSE_DRAGGED) { 2612 hideTip(); Object previnside = mouseinside; 2614 Object prevpart = insidepart; 2615 findComponent(content, x, y); 2616 boolean same = (previnside == mouseinside) && (prevpart == insidepart); 2617 boolean isin = (mousepressed == mouseinside) && (pressedpart == insidepart); 2618 boolean wasin = (mousepressed == previnside) && (pressedpart == prevpart); 2619 2620 if (wasin && !isin) { 2621 handleMouseEvent(x, y, clickcount, shiftdown, controldown, popuptrigger, 2622 MouseEvent.MOUSE_EXITED, mousepressed, pressedpart); 2623 } 2624 else if (!same && (popupowner != null) && !wasin) { 2625 handleMouseEvent(x, y, clickcount, shiftdown, controldown, popuptrigger, 2626 DRAG_EXITED, previnside, prevpart); 2627 } 2628 if (isin && !wasin) { 2629 handleMouseEvent(x, y, clickcount, shiftdown, controldown, popuptrigger, 2630 MouseEvent.MOUSE_ENTERED, mousepressed, pressedpart); 2631 } 2632 else if (!same && (popupowner != null) && !isin) { 2633 handleMouseEvent(x, y, clickcount, shiftdown, controldown, popuptrigger, 2634 DRAG_ENTERED, mouseinside, insidepart); 2635 } 2636 if (isin == wasin) { 2637 handleMouseEvent(x, y, clickcount, shiftdown, controldown, popuptrigger, 2638 MouseEvent.MOUSE_DRAGGED, mousepressed, pressedpart); 2639 } 2640 } 2641 else if (id == MouseEvent.MOUSE_RELEASED) { 2642 hideTip(); Object mouserelease = mousepressed; 2644 Object releasepart = pressedpart; 2645 mousepressed = pressedpart = null; 2646 handleMouseEvent(x, y, clickcount, shiftdown, controldown, popuptrigger, 2647 MouseEvent.MOUSE_RELEASED, mouserelease, releasepart); 2648 if ((mouseinside != null) && 2649 ((mouserelease != mouseinside) || (releasepart != insidepart))) { 2650 handleMouseEvent(x, y, clickcount, shiftdown, controldown, popuptrigger, 2651 MouseEvent.MOUSE_ENTERED, mouseinside, insidepart); 2652 } 2653 } 2654 } 2655 else if (id == MOUSE_WHEEL) { 2656 Rectangle port = getRectangle(mouseinside, ":port"); 2657 if (port != null) { Rectangle bounds = getRectangle(mouseinside, "bounds"); 2660 try { if (wheelrotation == null) { 2662 wheelrotation = e.getClass().getMethod("getWheelRotation", null); 2663 } 2664 int rotation = ((Integer ) wheelrotation.invoke(e, null)).intValue(); 2665 2666 if (port.x + port.width < bounds.width) { processScroll(mouseinside, (rotation > 0) ? "down" : "up"); } 2669 else if (port.y + port.height < bounds.height) { processScroll(mouseinside, (rotation > 0) ? "right" : "left"); 2671 } 2672 } catch (Exception exc) { } 2673 } 2674 } 2675 else if ((id == KeyEvent.KEY_PRESSED) || (id == KeyEvent.KEY_TYPED)) { 2676 if (focusinside && ((popupowner != null) || (focusowner != null))) { 2677 hideTip(); KeyEvent ke = (KeyEvent) e; 2679 int keychar = ke.getKeyChar(); 2680 boolean control = (keychar <= 0x1f) || 2681 ((keychar >= 0x7f) && (keychar <= 0x9f)) || 2682 (keychar >= 0xffff) || ke.isControlDown(); 2683 int keycode = control ? ke.getKeyCode() : 0; 2684 2685 if ((control == (id == KeyEvent.KEY_PRESSED)) && 2686 processKeyPress((popupowner != null) ? popupowner : focusowner, 2687 ke.isShiftDown(), ke.isControlDown(), ke.getModifiers(), 2688 control ? 0 : keychar, keycode)) { 2689 ke.consume(); 2690 } 2691 else if ((keycode == KeyEvent.VK_TAB) || 2692 ((keycode == KeyEvent.VK_F6) && (ke.isAltDown() || ke.isControlDown()))) { 2693 boolean outgo = (keycode == KeyEvent.VK_F6); 2694 if (!ke.isShiftDown() ? setNextFocusable(focusowner, outgo) : 2695 setPreviousFocusable(focusowner, outgo)) { 2696 ke.consume(); 2697 } else if (MOUSE_WHEEL != 0) { if (!ke.isShiftDown()) { 2699 transferFocus(); 2700 } 2701 else { try { 2702 getClass().getMethod("transferFocusBackward", null). invoke(this, null); 2703 } catch (Exception exc) { } } 2704 } 2705 repaint(focusowner); 2706 closeup(); 2707 } 2708 else if (keycode == KeyEvent.VK_F8) { 2709 for (Object splitpane = focusowner; 2710 splitpane != null; splitpane = getParent(splitpane)) { 2711 if (getClass(splitpane) == "splitpane") { 2712 setFocus(splitpane); repaint(splitpane); ke.consume(); break; } 2714 } 2715 } 2716 else if ((id == KeyEvent.KEY_PRESSED) && ((keychar != 0) || ke.isActionKey()) && 2717 checkMnemonic(focusowner, true, null, ke.getKeyCode(), ke.getModifiers())) { 2718 ke.consume(); 2719 } 2720 } 2721 } 2722 else if (id == FocusEvent.FOCUS_LOST) { 2723 focusinside = false; 2724 if (focusowner != null) { repaint(focusowner); } 2725 closeup(); 2726 } 2727 else if (id == FocusEvent.FOCUS_GAINED) { 2728 focusinside = true; 2729 if (focusowner == null) { setFocus(content); } 2730 else { repaint(focusowner); } 2731 } 2732 else if ((id == ComponentEvent.COMPONENT_RESIZED) || 2733 (id == ComponentEvent.COMPONENT_SHOWN)) { 2734 Dimension d = getSize(); 2735 setRectangle(content, "bounds", 0, 0, d.width, d.height); 2736 validate(content); 2737 closeup(); 2738 if (!focusinside) { requestFocus(); } 2739 } 2740 } 2741 2742 2745 private void checkLocation() { 2746 findComponent(content, mousex, mousey); 2747 handleMouseEvent(mousex, mousex, 1, false, false, false, 2748 MouseEvent.MOUSE_ENTERED, mouseinside, insidepart); 2749 } 2750 2751 2754 private boolean processKeyPress(Object component, 2755 boolean shiftdown, boolean controldown, int modifiers, int keychar, int keycode) { 2756 String classname = getClass(component); 2757 if ("button" == classname) { 2758 if (keychar == KeyEvent.VK_SPACE || 2759 ((keycode == KeyEvent.VK_ENTER) && 2760 (get(component, "type") == "default")) || 2761 ((keycode == KeyEvent.VK_ESCAPE) && (get(component, "type") == "cancel"))) { 2763 invoke(component, null, "action"); 2765 repaint(component); 2766 return true; 2767 } 2768 } 2769 else if (("checkbox" == classname) || ("togglebutton" == classname)) { 2770 if (keychar == KeyEvent.VK_SPACE) { 2771 changeCheck(component, true); 2772 repaint(component); 2773 return true; 2774 } 2775 } 2776 else if ("combobox" == classname) { 2777 Object combolist = get(component, ":combolist"); 2778 if (combolist == null) { boolean editable = getBoolean(component, "editable", true); 2780 if (editable && processField(component, shiftdown, controldown, modifiers, 2781 keychar, keycode, false, false, false)) { 2782 setInteger(component, "selected", -1, -1); 2783 return true; 2784 } 2785 if ((keychar == KeyEvent.VK_SPACE) || (keycode == KeyEvent.VK_DOWN)) { 2786 popupCombo(component); 2787 } 2788 else return false; 2790 } 2791 else { 2792 if ((keycode == KeyEvent.VK_UP) || 2793 (keycode == KeyEvent.VK_DOWN) || (keycode == KeyEvent.VK_PAGE_UP) || 2794 (keycode == KeyEvent.VK_PAGE_DOWN) || 2795 (keycode == KeyEvent.VK_HOME) || (keycode == KeyEvent.VK_END)) { 2796 Object next = getListItem(component, combolist, keycode, 2797 get(combolist, ":lead"), false); 2798 if (next != null) { 2799 setInside(combolist, next, true); 2800 } 2801 } 2802 else if ((keycode == KeyEvent.VK_ENTER) || (keychar == KeyEvent.VK_SPACE)) { 2803 closeCombo(component, combolist, get(combolist, ":lead")); } 2805 else if (keycode == KeyEvent.VK_ESCAPE) { 2806 closeCombo(component, combolist, null); 2807 } 2808 else if (!processField(component, shiftdown, controldown, modifiers, 2809 keychar, keycode, false, false, false)) { 2810 Object item = findText((char) keychar, component, combolist, false); 2811 if (item != null) { 2812 setInside(combolist, item, true); 2813 } 2814 else return false; 2815 } 2816 } 2817 return true; 2818 } 2819 else if (("textfield" == classname) || ("passwordfield" == classname)) { 2820 return processField(component, shiftdown, controldown, modifiers, 2821 keychar, keycode, false, ("passwordfield" == classname), false); 2822 } 2823 else if ("textarea" == classname) { 2824 char[] chars = (char[]) get(component, ":text"); 2825 int start = getInteger(component, "start", 0); 2826 int end = getInteger(component, "end", 0); 2827 2828 int istart = start; 2829 int iend = end; 2830 String insert = null; 2831 if ((keycode == KeyEvent.VK_HOME) && !controldown) { 2832 while ((iend > 0) && (chars[iend - 1] != '\n')) { iend--; } 2833 if (!shiftdown) { istart = iend; } 2834 } 2835 else if ((keycode == KeyEvent.VK_END) && !controldown) { 2836 while ((iend < chars.length) && (chars[iend] != '\n')) { iend++; } 2837 if (!shiftdown) { istart = iend; } 2838 } 2839 else if ((keycode == KeyEvent.VK_UP) || (keycode == KeyEvent.VK_PAGE_UP) || 2840 (keycode == KeyEvent.VK_DOWN) || (keycode == KeyEvent.VK_PAGE_DOWN)) { 2841 Font currentfont = (Font) get(component, "font"); 2842 FontMetrics fm = getFontMetrics((currentfont != null) ? currentfont : font); 2843 int fh = fm.getHeight(); 2844 int y = 0; int linestart = 0; 2845 for (int i = 0; i < iend; i++) { 2846 if ((chars[i] == '\n') || (chars[i] == '\t')) { 2847 linestart = i + 1; y += fh; 2848 } 2849 } 2850 if (keycode == KeyEvent.VK_UP) { y -= fh; } 2851 else if (keycode == KeyEvent.VK_DOWN) { y += fh; } 2852 else { 2853 int dy = getRectangle(component, ":port").height; 2854 y += (keycode == KeyEvent.VK_PAGE_UP) ? -dy : dy; } 2856 int x = fm.charsWidth(chars, linestart, iend - linestart); 2857 iend = getCaretLocation(component, x, y, true, false); 2858 if (!shiftdown) { istart = iend; } 2859 } 2860 else return processField(component, shiftdown, controldown, modifiers, 2861 keychar, keycode, true, false, false); 2862 return changeField(component, 2863 getString(component, "text", ""), insert, istart, iend, start, end); 2864 } 2865 else if ("tabbedpane" == classname) { 2866 if ((keycode == KeyEvent.VK_RIGHT) || (keycode == KeyEvent.VK_DOWN) || 2867 (keycode == KeyEvent.VK_LEFT) || (keycode == KeyEvent.VK_UP)) { 2868 int selected = getInteger(component, "selected", 0); 2869 boolean increase = (keycode == KeyEvent.VK_RIGHT) || (keycode == KeyEvent.VK_DOWN); 2870 int newvalue = selected; 2871 int n = increase ? getItemCountImpl(component, ":comp") : 0; 2872 int d = (increase ? 1 : -1); 2873 for (int i = selected + d; increase ? (i < n) : (i >= 0); i += d) { 2874 if (getBoolean(getItem(component, i), "enabled", true)) { 2875 newvalue = i; break; 2876 } 2877 } 2878 if (newvalue != selected) { 2879 setInteger(component, "selected", newvalue, 0); 2880 checkOffset(component); 2881 repaint(component); 2882 invoke(component, getItem(component, newvalue), "action"); 2883 } 2884 } 2885 } 2886 else if ("spinbox" == classname) { 2887 if ((keycode == KeyEvent.VK_UP) || (keycode == KeyEvent.VK_DOWN)) { 2888 processSpin(component, (keycode == KeyEvent.VK_UP)? "up" : "down"); 2889 return true; 2890 } 2891 return processField(component, shiftdown, controldown, modifiers, 2892 keychar, keycode, false, false, true); 2893 } 2894 else if ("slider" == classname) { 2895 int value = getInteger(component, "value", 0); 2896 int d = 0; 2897 if ((keycode == KeyEvent.VK_HOME) || (keycode == KeyEvent.VK_LEFT) || 2898 (keycode == KeyEvent.VK_UP) || (keycode == KeyEvent.VK_PAGE_UP)) { 2899 d = getInteger(component, "minimum", 0) - value; 2900 if ((keycode == KeyEvent.VK_LEFT) || (keycode == KeyEvent.VK_UP)) { 2901 d = Math.max(d, -getInteger(component, "unit", 5)); 2902 } 2903 else if (keycode == KeyEvent.VK_PAGE_UP) { 2904 d = Math.max(d, -getInteger(component, "block", 25)); 2905 } 2906 } 2907 else if ((keycode == KeyEvent.VK_END) || (keycode == KeyEvent.VK_RIGHT) || 2908 (keycode == KeyEvent.VK_DOWN) || (keycode == KeyEvent.VK_PAGE_DOWN)) { 2909 d = getInteger(component, "maximum", 100) - value; 2910 if ((keycode == KeyEvent.VK_RIGHT) || (keycode == KeyEvent.VK_DOWN)) { 2911 d = Math.min(d, getInteger(component, "unit", 5)); 2912 } 2913 else if (keycode == KeyEvent.VK_PAGE_DOWN) { 2914 d = Math.min(d, getInteger(component, "block", 25)); 2915 } 2916 } 2917 if (d != 0) { 2918 setInteger(component, "value", value + d, 0); 2919 repaint(component); 2920 invoke(component, null, "action"); 2921 } 2922 } 2923 else if ("splitpane" == classname) { 2924 int divider = getInteger(component, "divider", -1); 2925 int d = 0; 2926 if (keycode == KeyEvent.VK_HOME) { 2927 d = -divider; 2928 } 2929 else if ((keycode == KeyEvent.VK_LEFT) || (keycode == KeyEvent.VK_UP)) { 2930 d = Math.max(-10, -divider); 2931 } 2932 else if ((keycode == KeyEvent.VK_END) || 2933 (keycode == KeyEvent.VK_RIGHT) || (keycode == KeyEvent.VK_DOWN)) { 2934 boolean horizontal = ("vertical" != get(component, "orientation")); 2935 Rectangle bounds = getRectangle(component, "bounds"); 2936 int max = (horizontal ? bounds.width : bounds.height) - 5; 2937 d = max - divider; 2938 if (keycode != KeyEvent.VK_END) { 2939 d = Math.min(d, 10); 2940 } 2941 } 2942 if (d != 0) { 2943 setInteger(component, "divider", divider + d, -1); 2944 validate(component); 2945 } 2946 } 2947 else if (("list" == classname) || ("table" == classname)) { 2948 return processList(component, shiftdown, controldown, keychar, keycode, false); 2949 } 2950 else if ("tree" == classname) { 2951 if (keycode == KeyEvent.VK_LEFT) { 2953 Object lead = get(component, ":lead"); 2954 if ((get(lead, ":comp") != null) && getBoolean(lead, "expanded", true)) { setBoolean(lead, "expanded", false, true); 2956 selectItem(component, lead, true); 2957 validate(component); 2958 invoke(component, lead, "collapse"); return true; 2960 } 2961 else { Object parent = getParent(lead); 2963 if (parent != component) { 2964 selectItem(component, parent, true); 2965 setLead(component, lead, parent); 2966 return true; 2967 } 2968 } 2969 } 2970 else if (keycode == KeyEvent.VK_RIGHT) { 2972 Object lead = get(component, ":lead"); 2973 Object node = get(lead, ":comp"); 2974 if (node != null) { 2975 if (getBoolean(lead, "expanded", true)) { selectItem(component, node, true); 2977 setLead(component, lead, node); 2978 } 2979 else { setBoolean(lead, "expanded", true, true); 2981 selectItem(component, lead, true); 2982 validate(component); 2983 invoke(component, lead, "expand"); } 2985 return true; 2986 } 2987 } 2988 return processList(component, shiftdown, controldown, keychar, keycode, true); 2989 } 2990 else if (("menubar" == classname) || ("popupmenu" == classname)) { 2991 Object previous = null; Object last = null; 2993 for (Object i = get(component, ":popup"); 2994 i != null; i = get(i, ":popup")) { 2995 previous = last; last = i; 2996 } 2997 Object selected = get(last, "selected"); 2999 Object hotpopup = ((selected != null) || (previous == null)) ? 3000 last : previous; 3001 if ((selected == null) && (previous != null)) { 3002 selected = get(previous, "selected"); 3003 } 3004 3005 if ((keycode == KeyEvent.VK_UP) || (keycode == KeyEvent.VK_DOWN)) { 3006 Object next = getMenu(hotpopup, 3007 selected, keycode == KeyEvent.VK_DOWN, true); 3008 if (next != null) { 3009 set(hotpopup, "selected", null); 3010 popupMenu(hotpopup); 3011 set(hotpopup, "selected", next); 3012 repaint(hotpopup); 3013 } 3014 } 3015 else if (keycode == KeyEvent.VK_LEFT) { 3016 if (previous != null) { selected = get(previous, "selected"); 3018 set(previous, "selected", null); 3019 popupMenu(previous); 3020 set(previous, "selected", selected); 3021 repaint(previous); } 3023 else if ("menubar" == classname) { Object next = getMenu(component, get(component, "selected"), false, false); 3025 if (next != null) { 3026 set(component, "selected", next); 3027 Object popup = popupMenu(component); 3028 set(popup, "selected", getMenu(popup, null, true, true)); 3029 repaint(component); } 3031 } 3032 } 3033 else if (keycode == KeyEvent.VK_RIGHT) { 3034 if ((previous != null) && (selected == null)) { set(last, "selected", get(get(last, "menu"), ":comp")); 3036 repaint(last); } 3038 else if ((selected != null) && (getClass(selected) == "menu")) { Object popup = popupMenu(last); 3040 set(popup, "selected", getMenu(popup, null, true, true)); 3041 } 3042 else if ("menubar" == classname) { Object next = getMenu(component, get(component, "selected"), true, false); 3044 if (next != null) { 3045 set(component, "selected", next); 3046 Object popup = popupMenu(component); 3047 set(popup, "selected", getMenu(popup, null, true, true)); 3048 repaint(component); } 3050 } 3051 } 3052 else if ((keycode == KeyEvent.VK_ENTER) || 3053 (keychar == KeyEvent.VK_SPACE) || (keycode == KeyEvent.VK_ESCAPE)) { 3054 if ((keycode != KeyEvent.VK_ESCAPE) && 3055 getBoolean(selected, "enabled", true)) { 3056 if ((selected != null) && (getClass(selected) == "checkboxmenuitem")) { 3057 changeCheck(selected, false); 3058 } 3059 else invoke(selected, null, "action"); 3060 } 3061 closeup(); 3062 } 3063 else return false; 3064 return true; 3065 } 3066 return false; 3067 } 3068 3069 3072 private boolean changeCheck(Object component, boolean box) { 3073 String group = getString(component, "group", null); 3074 if (group != null) { 3075 if (getBoolean(component, "selected", false)) { return false; } 3076 for (Object comp = get(getParent(component), ":comp"); 3077 comp != null; comp = get(comp, ":next")) { 3078 if (comp == component) { 3079 setBoolean(component, "selected", true); 3080 } 3081 else if (group.equals(get(comp, "group")) && 3082 getBoolean(comp, "selected", false)) { 3083 setBoolean(comp, "selected", false); 3084 if (box) { repaint(comp); } } 3086 } 3087 } 3088 else { 3089 setBoolean(component, "selected", 3090 !getBoolean(component, "selected", false), false); 3091 } 3092 invoke(component, null, "action"); 3093 return true; 3094 } 3095 3096 3103 private Object getMenu(Object component, Object part, 3104 boolean forward, boolean popup) { 3105 Object previous = null; 3106 for (int i = 0; i < 2; i++) { for (Object item = (i == 0) ? get(part, ":next") : 3108 get(popup ? get(component, "menu") : component, ":comp"); 3109 (i == 0) ? (item != null) : (item != part); item = get(item, ":next")) { 3110 if ((getClass(item) != "separator") && getBoolean(item, "enabled", true)) { 3111 if (forward) { return item; } 3112 previous = item; 3113 } 3114 } 3115 } 3116 return previous; 3117 } 3118 3119 3126 private boolean processField(Object component, 3127 boolean shiftdown, boolean controldown, int modifiers, 3128 int keychar, int keycode, 3129 boolean multiline, boolean hidden, boolean filter) { 3130 String text = getString(component, "text", ""); 3131 int start = getInteger(component, "start", 0); 3132 int end = getInteger(component, "end", 0); 3133 boolean editable = getBoolean(component, "editable", true); 3134 3135 int istart = start; 3136 int iend = end; 3137 String insert = null; 3138 if (editable && (keychar != 0) && 3139 (modifiers != InputEvent.ALT_MASK)) { 3141 insert = String.valueOf((char) keychar); 3142 } 3143 else if (editable && (keycode == KeyEvent.VK_ENTER)) { 3144 if (multiline) { insert = "\n"; } 3145 else { return invoke(component, null, "perform"); } 3146 } 3147 else if (editable && (keycode == KeyEvent.VK_BACK_SPACE)) { 3148 insert = ""; 3149 if (start == end) { istart -= 1; } 3150 } 3151 else if (keycode == KeyEvent.VK_END) { 3152 iend = text.length(); 3153 if (!shiftdown) { istart = iend; } 3154 } 3155 else if (keycode == KeyEvent.VK_HOME) { 3156 iend = 0; 3157 if (!shiftdown) { istart = iend; } 3158 } 3159 else if (keycode == KeyEvent.VK_LEFT) { 3160 if (controldown) { 3161 for (int i = 0; i < 2; i++) { 3162 while ((iend > 0) && ((i != 0) == 3163 Character.isLetterOrDigit(text.charAt(iend - 1)))) { iend--; } 3164 } 3165 } else { 3166 iend -= 1; 3167 } 3168 if (!shiftdown) { istart = iend; } 3169 } 3170 else if (keycode == KeyEvent.VK_RIGHT) { 3171 if (controldown) { 3172 for (int i = 0; i < 2; i++) { 3173 while ((iend < text.length()) && ((i == 0) == 3174 Character.isLetterOrDigit(text.charAt(iend)))) { iend++; } 3175 } 3176 } else { 3177 iend += 1; 3178 } 3179 if (!shiftdown) { istart = iend; } 3180 } 3181 else if (editable && (keycode == KeyEvent.VK_DELETE)) { 3182 insert = ""; 3183 if (start == end) { iend += 1; } 3184 } 3185 else if (controldown && 3186 ((keycode == KeyEvent.VK_A) || (keycode == 0xBF))) { 3187 istart = 0; iend = text.length(); 3189 } 3190 else if (controldown && (keycode == 0xDC)) { 3191 istart = iend = text.length(); } 3193 else if ((editable && !hidden && controldown && (keycode == KeyEvent.VK_X)) || 3194 (!hidden && controldown && (keycode == KeyEvent.VK_C))) { 3195 if (start != end) { 3196 clipboard = text.substring( 3197 Math.min(start, end), Math.max(start, end)); 3198 try { 3199 getToolkit().getSystemClipboard().setContents( 3200 new StringSelection(clipboard), null); 3201 } catch (Exception exc) {} 3202 if (keycode == KeyEvent.VK_X) { insert = ""; } else { return true; } 3203 } 3204 } 3205 else if (editable && controldown && (keycode == KeyEvent.VK_V)) { 3206 try { 3207 insert = (String ) getToolkit().getSystemClipboard(). 3208 getContents(this).getTransferData(DataFlavor.stringFlavor); 3209 } catch (Exception exc) { 3210 insert = clipboard; 3211 } 3212 if (insert != null) { insert = filter(insert, multiline); 3214 } 3215 } 3216 if (filter && (insert != null)) { for (int i = insert.length() - 1; i >= 0; i--) { 3218 if (!Character.isDigit(insert.charAt(i))) { return false; } 3219 } 3220 } 3221 return changeField(component, text, insert, istart, iend, start, end); 3222 } 3223 3224 3229 private static String filter(String text, boolean multiline) { 3230 StringBuffer filtered = new StringBuffer (text.length()); 3231 for (int i = 0; i < text.length(); i++) { 3232 char ckey = text.charAt(i); 3233 if (((ckey > 0x1f) && (ckey < 0x7f)) || 3234 ((ckey > 0x9f) && (ckey < 0xffff)) || 3235 (multiline && (ckey == '\n'))) { 3236 filtered.append(ckey); 3237 } 3238 } 3239 return (filtered.length() != text.length()) ? filtered.toString() : text; 3240 } 3241 3242 3252 private boolean changeField(Object component, String text, String insert, 3253 int movestart, int moveend, int start, int end) { 3254 movestart = Math.max(0, Math.min(movestart, text.length())); 3255 moveend = Math.max(0, Math.min(moveend, text.length())); 3256 if ((insert == null) && (start == movestart) && (end == moveend)) { 3257 return false; 3258 } 3259 if (insert != null) { 3260 int min = Math.min(movestart, moveend); 3261 set(component, "text", text.substring(0, min) + insert + 3262 text.substring(Math.max(movestart, moveend))); 3263 movestart = moveend = min + insert.length(); 3264 invoke(component, null, "action"); } 3266 if (start != movestart) { setInteger(component, "start", movestart, 0); } 3267 if (end != moveend) { setInteger(component, "end", moveend, 0); } 3268 validate(component); 3269 invoke(component, null, (insert != null) ? 3270 ((insert.length() > 0) ? "insert" : "remove") : "caret"); 3271 return true; 3272 } 3273 3274 3277 private boolean processList(Object component, boolean shiftdown, boolean controldown, 3278 int keychar, int keycode, boolean recursive) { 3279 if ((keycode == KeyEvent.VK_UP) || (keycode == KeyEvent.VK_DOWN) || (keycode == KeyEvent.VK_PAGE_UP) || 3281 (keycode == KeyEvent.VK_PAGE_DOWN) || 3282 (keycode == KeyEvent.VK_HOME) || (keycode == KeyEvent.VK_END)) { 3283 Object lead = get(component, ":lead"); 3284 Object row = getListItem(component, component, keycode, lead, recursive); 3285 if (row != null) { 3286 String selection = getString(component, "selection", "single"); 3287 if (shiftdown && (selection != "single") && (lead != null)) { 3288 extend(component, lead, row, recursive); 3289 } 3290 else if (!controldown) { 3291 selectItem(component, row, recursive); 3292 } 3293 setLead(component, lead, row); 3294 return true; 3295 } 3296 } 3297 else if (keycode == KeyEvent.VK_LEFT) { 3298 return processScroll(component, "left"); 3299 } 3300 else if (keycode == KeyEvent.VK_RIGHT) { 3301 return processScroll(component, "right"); 3302 } 3303 else if (keychar == KeyEvent.VK_SPACE) { select(component, get(component, ":lead"), recursive, shiftdown, controldown); return true; 3306 } 3307 else if (controldown) { 3308 if (((keycode == KeyEvent.VK_A) || (keycode == 0xBF)) && (getString(component, "selection", "single") != "single")) { selectAll(component, true, recursive); 3311 return true; 3312 } 3313 else if (keycode == 0xDC) { selectAll(component, false, recursive); 3315 return true; 3316 } 3317 } 3318 else { 3319 Object item = findText((char) keychar, component, component, recursive); 3320 if (item != null) { 3321 select(component, item, recursive, false, false); 3322 return true; 3323 } 3324 } 3325 return false; 3326 } 3327 3328 3337 private Object findText(char keychar, Object component, 3338 Object leadowner, boolean recursive) { 3339 if (keychar != 0) { 3340 long current = System.currentTimeMillis(); 3341 int i = (current > findtime + 1000) ? 1 : 0; findtime = current; 3343 Object lead = get(leadowner, ":lead"); 3344 for (; i < 2; i++) { findprefix = (i == 0) ? (findprefix + keychar) : String.valueOf(keychar); 3346 for (int j = 0; j < 2; j++) { for (Object item = (j == 0) ? ((i == 0) ? lead : getNextItem(component, lead, recursive)) : 3348 get(component, ":comp"); (j == 0) ? (item != null) : (item != lead); 3349 item = getNextItem(component, item, recursive)) { 3350 if (getString(item, "text", "").regionMatches(true, 3351 0, findprefix, 0, findprefix.length())) { return item; 3353 } 3354 } 3355 } 3356 } 3357 } 3358 return null; 3359 } 3360 3361 3364 private Object getListItem(Object component, Object scrollpane, 3365 int keycode, Object lead, boolean recursive) { 3366 Object row = null; 3367 if (keycode == KeyEvent.VK_UP) { 3368 for (Object prev = get(component, ":comp"); prev != lead; 3369 prev = getNextItem(component, prev, recursive)) { 3370 row = prev; } 3372 } 3373 else if (keycode == KeyEvent.VK_DOWN) { 3374 row = (lead == null) ? get(component, ":comp") : 3375 getNextItem(component, lead, recursive); 3376 } 3377 else if ((keycode == KeyEvent.VK_PAGE_UP) || 3378 (keycode == KeyEvent.VK_PAGE_DOWN)) { 3379 Rectangle view = getRectangle(scrollpane, ":view"); 3380 Rectangle port = getRectangle(scrollpane, ":port"); 3381 Rectangle rl = (lead != null) ? getRectangle(lead, "bounds") : null; 3382 int vy = (keycode == KeyEvent.VK_PAGE_UP) ? 3383 view.y : (view.y + port.height); 3384 if ((keycode == KeyEvent.VK_PAGE_UP) && 3385 (rl != null) && (rl.y <= view.y)) { 3386 vy -= port.height; 3387 } 3388 if ((keycode == KeyEvent.VK_PAGE_DOWN) && 3389 (rl != null) && (rl.y + rl.height >= view.y + port.height)) { 3390 vy += port.height; 3391 } 3392 for (Object item = get(component, ":comp"); item != null; 3393 item = getNextItem(component, item, recursive)) { 3394 Rectangle r = getRectangle(item, "bounds"); 3395 if (keycode == KeyEvent.VK_PAGE_UP) { 3396 row = item; 3397 if (r.y + r.height > vy) { break; } 3398 } else { 3399 if (r.y > vy) { break; } 3400 row = item; 3401 } 3402 } 3403 } 3404 else if (keycode == KeyEvent.VK_HOME) { 3405 row = get(component, ":comp"); 3406 } 3407 else if (keycode == KeyEvent.VK_END) { 3408 for (Object last = lead; last != null; 3409 last = getNextItem(component, last, recursive)) { 3410 row = last; 3411 } 3412 } 3413 return row; 3414 } 3415 3416 3422 private void selectAll(Object component, 3423 boolean selected, boolean recursive) { 3424 boolean changed = false; 3425 for (Object item = get(component, ":comp"); 3426 item != null; item = getNextItem(component, item, recursive)) { 3427 if (setBoolean(item, "selected", selected, false)) { 3428 repaint(component, null, item); changed = true; 3429 } 3430 } 3431 set(component, ":anchor", null); 3432 if (changed) { invoke(component, null, "action"); } 3433 } 3434 3435 3441 private void selectItem(Object component, Object row, boolean recursive) { 3442 boolean changed = false; 3443 for (Object item = get(component, ":comp"); 3444 item != null; item = getNextItem(component, item, recursive)) { 3445 if (setBoolean(item, "selected", (item == row), false)) { 3446 repaint(component, null, item); changed = true; 3447 } 3448 } 3449 set(component, ":anchor", null); 3450 if (changed) { invoke(component, row, "action"); } 3451 } 3452 3453 3456 private void extend(Object component, Object lead, 3457 Object row, boolean recursive) { 3458 Object anchor = get(component, ":anchor"); 3459 if (anchor == null) { set(component, ":anchor", anchor = lead); } 3460 char select = 'n'; boolean changed = false; 3461 for (Object item = get(component, ":comp"); item != null; item = getNextItem(component, item, recursive)) { 3463 if (item == anchor) select = (select == 'n') ? 'y' : 'r'; 3464 if (item == row) select = (select == 'n') ? 'y' : 'r'; 3465 if (setBoolean(item, "selected", (select != 'n'), false)) { 3466 repaint(component, null, item); changed = true; 3467 } 3468 if (select == 'r') select = 'n'; 3469 } 3470 if (changed) { invoke(component, row, "action"); } 3471 } 3472 3473 3479 private void setLead(Object component, Object oldlead, Object lead) { 3480 if (oldlead != lead) { if (oldlead != null) { repaint(component, null, oldlead); } 3482 set(component, ":lead", lead); 3483 repaint(component, null, lead); 3484 3485 Rectangle r = getRectangle(lead, "bounds"); 3486 scrollToVisible(component, r.x, r.y, 0, r.height); 3487 } 3488 } 3489 3490 3496 private void setInside(Object component, Object part, boolean scroll) { 3497 Object previous = get(component, ":lead"); 3498 if (previous != null) { 3499 repaint(component, ":combolist", previous); 3500 } 3501 set(component, ":lead", part); 3502 if (part != null) { 3503 repaint(component, ":combolist", part); 3504 if (scroll) { 3505 Rectangle r = getRectangle(part, "bounds"); 3506 scrollToVisible(component, r.x, r.y, 0, r.height); 3507 } 3508 } 3509 } 3510 3511 3515 private void handleMouseEvent(int x, int y, int clickcount, 3516 boolean shiftdown, boolean controldown, boolean popuptrigger, 3517 int id, Object component, Object part) { 3518 if (id == MouseEvent.MOUSE_ENTERED) { 3519 setTimer(750L); 3520 } 3521 else if (id == MouseEvent.MOUSE_EXITED) { 3522 hideTip(); 3523 } 3524 if (!getBoolean(component, "enabled", true)) { return; } 3525 String classname = getClass(component); 3526 if (("button" == classname) || 3527 ("checkbox" == classname) || ("togglebutton" == classname)) { 3528 if ((id == MouseEvent.MOUSE_ENTERED) || 3529 (id == MouseEvent.MOUSE_EXITED) || 3530 (id == MouseEvent.MOUSE_PRESSED) || 3531 (id == MouseEvent.MOUSE_RELEASED)) { 3532 if (id == MouseEvent.MOUSE_PRESSED) { 3533 setFocus(component); 3534 } 3535 if (("button" == classname) && 3536 ((mousepressed == null) || (mousepressed == component)) && 3537 ((id == MouseEvent.MOUSE_ENTERED) || 3538 (id == MouseEvent.MOUSE_EXITED)) && 3539 (get(component, "type") == "link")) { 3540 setCursor(Cursor.getPredefinedCursor( 3541 (id == MouseEvent.MOUSE_ENTERED) ? 3542 Cursor.HAND_CURSOR : Cursor.DEFAULT_CURSOR)); 3543 } 3544 else if ((id == MouseEvent.MOUSE_RELEASED) && 3545 (mouseinside == component)) { 3546 if ("button" != classname) { 3547 changeCheck(component, true); 3548 } 3549 else invoke(component, null, "action"); 3550 } 3551 repaint(component); 3552 } 3553 } 3554 else if ("combobox" == classname) { 3555 boolean editable = getBoolean(component, "editable", true); 3556 if (editable && (part == null)) { Image icon = null; 3558 int left = ((id == MouseEvent.MOUSE_PRESSED) && 3559 ((icon = getIcon(component, "icon", null)) != null)) ? 3560 icon.getWidth(this) : 0; 3561 processField(x, y, clickcount, id, component, false, false, left); 3562 } 3563 else if (part != "icon") { if (((id == MouseEvent.MOUSE_ENTERED) || 3565 (id == MouseEvent.MOUSE_EXITED)) && (mousepressed == null)) { 3566 if (editable) { repaint(component, "combobox", part); } else { repaint(component); } } 3569 else if (id == MouseEvent.MOUSE_PRESSED) { 3570 Object combolist = get(component, ":combolist"); 3571 if (combolist == null) { setFocus(component); 3573 repaint(component); 3574 popupCombo(component); 3575 } else { closeCombo(component, combolist, null); 3577 } 3578 } 3579 else if (id == MouseEvent.MOUSE_RELEASED) { 3580 if (mouseinside != component) { 3581 Object combolist = get(component, ":combolist"); 3582 closeCombo(component, combolist, 3583 ((mouseinside == combolist) && (insidepart instanceof Object [])) ? insidepart : null); 3584 } else { 3585 repaint(component); 3586 } 3587 } 3588 } 3589 } 3590 else if (":combolist" == classname) { 3591 if (!processScroll(x, y, id, component, part)) { 3592 if ((id == MouseEvent.MOUSE_ENTERED) || (id == DRAG_ENTERED)) { 3593 if (part != null) { setInside(component, part, false); 3595 } 3596 } 3597 else if (id == MouseEvent.MOUSE_RELEASED) { 3598 closeCombo(get(component, "combobox"), component, part); 3599 } 3600 } 3601 } 3602 else if (("textfield" == classname) || ("passwordfield" == classname)) { 3603 processField(x, y, clickcount, id, component, 3604 false, ("passwordfield" == classname), 0); 3605 } 3606 else if ("textarea" == classname) { 3607 if (!processScroll(x, y, id, component, part)) { 3608 processField(x, y, clickcount, id, component, true, false, 0); 3609 } 3610 } 3611 else if ("panel" == classname) { 3612 processScroll(x, y, id, component, part); 3613 } 3614 else if ("desktop" == classname) { 3615 if (part == "modal") { 3616 if (id == MouseEvent.MOUSE_ENTERED) { 3617 setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); 3618 } 3619 else if (id == MouseEvent.MOUSE_EXITED) { 3620 setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); 3621 } 3622 } 3623 } 3624 else if ("spinbox" == classname) { 3625 if (part == null) { 3626 processField(x, y, clickcount, id, component, false, false, 0); 3627 } 3628 else { if ((id == MouseEvent.MOUSE_ENTERED) || 3630 (id == MouseEvent.MOUSE_EXITED) || 3631 (id == MouseEvent.MOUSE_PRESSED) || 3632 (id == MouseEvent.MOUSE_RELEASED)) { 3633 if (id == MouseEvent.MOUSE_PRESSED) { 3634 setFocus(component); 3635 if (processSpin(component, part)) { setTimer(375L); } 3636 } 3638 else { 3639 if (id == MouseEvent.MOUSE_RELEASED) { 3640 setTimer(0L); 3641 } 3642 } 3643 repaint(component, classname, part); 3644 } 3645 } 3646 } 3647 else if ("tabbedpane" == classname) { 3648 if ((id == MouseEvent.MOUSE_ENTERED) || 3649 (id == MouseEvent.MOUSE_EXITED)) { 3650 if ((part != null) && getBoolean(part, "enabled", true) && 3651 (getInteger(component, "selected", 0) != getIndex(component, part))) { 3652 repaint(component, "tabbedpane", part); 3653 } 3654 } 3655 else if ((part != null) && (id == MouseEvent.MOUSE_PRESSED) && 3656 getBoolean(part, "enabled", true)) { 3657 int selected = getInteger(component, "selected", 0); 3658 int current = getIndex(component, part); 3659 if (selected == current) { 3660 setFocus(component); 3661 repaint(component, "tabbedpane", part); 3662 } 3663 else { 3664 setInteger(component, "selected", current, 0); 3665 setNextFocusable(component, false); 3668 checkOffset(component); 3669 repaint(component); 3670 invoke(component, part, "action"); 3671 } 3672 } 3673 } 3674 else if ("slider" == classname) { 3675 if ((id == MouseEvent.MOUSE_PRESSED) || 3676 (id == MouseEvent.MOUSE_DRAGGED)) { 3677 if (id == MouseEvent.MOUSE_PRESSED) { 3678 setReference(component, block / 2, block / 2); 3679 setFocus(component); 3680 } 3681 int minimum = getInteger(component, "minimum", 0); 3682 int maximum = getInteger(component, "maximum", 100); 3683 int value = getInteger(component, "value", 50); 3684 Rectangle bounds = getRectangle(component, "bounds"); 3685 boolean horizontal = ("vertical" != get(component, "orientation")); 3686 int newvalue = minimum + 3687 (horizontal ? (x - referencex) : (y - referencey)) * 3688 (maximum - minimum) / 3689 ((horizontal ? bounds.width : bounds.height) - block); newvalue = Math.max(minimum, Math.min(newvalue, maximum)); 3691 if (value != newvalue) { 3692 setInteger(component, "value", newvalue, 50); 3693 invoke(component, null, "action"); 3694 } 3695 if ((value != newvalue) || (id == MouseEvent.MOUSE_PRESSED)) { 3696 repaint(component); 3697 } 3698 } 3699 } 3700 else if ("splitpane" == classname) { 3701 if (id == MouseEvent.MOUSE_PRESSED) { 3702 setReference(component, 2, 2); 3703 } 3704 else if (id == MouseEvent.MOUSE_DRAGGED) { 3705 int divider = getInteger(component, "divider", -1); 3706 boolean horizontal = ("vertical" != get(component, "orientation")); 3707 int moveto = horizontal ? (x - referencex) : (y - referencey); 3708 Rectangle bounds = getRectangle(component, "bounds"); 3709 moveto = Math.max(0, Math.min(moveto, 3710 Math.abs(horizontal ? bounds.width : bounds.height) - 5)); 3711 if (divider != moveto) { 3712 setInteger(component, "divider", moveto, -1); 3713 validate(component); 3714 } 3715 } 3716 else if ((id == MouseEvent.MOUSE_ENTERED) && (mousepressed == null)) { 3717 boolean horizontal = ("vertical" != get(component, "orientation")); 3718 setCursor(Cursor.getPredefinedCursor(horizontal ? 3719 Cursor.E_RESIZE_CURSOR : Cursor.S_RESIZE_CURSOR)); 3720 } 3721 else if (((id == MouseEvent.MOUSE_EXITED) && (mousepressed == null)) || 3722 ((id == MouseEvent.MOUSE_RELEASED) && (mouseinside != component))) { 3723 setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); 3724 } 3725 } 3726 else if (("list" == classname) || 3727 ("table" == classname) || ("tree" == classname)) { 3728 if (!processScroll(x, y, id, component, part)) { 3729 if (((id == MouseEvent.MOUSE_PRESSED)|| 3730 ((id == MouseEvent.MOUSE_DRAGGED) && 3731 !shiftdown && !controldown))) { 3732 Rectangle port = getRectangle(component, ":port"); 3734 int my = y + port.y - referencey; 3735 for (Object item = get(component, ":comp"); item != null;) { 3736 Rectangle r = getRectangle(item, "bounds"); 3737 if (my < r.y + r.height) { 3738 if (id == MouseEvent.MOUSE_DRAGGED) { scrollToVisible(component, r.x, r.y, 0, r.height); 3740 } 3741 else if ("tree" == classname) { 3742 int mx = x + port.x - referencex; 3743 if (mx < r.x) { 3744 if ((mx >= r.x - block) && (get(item, ":comp") != null)) { 3745 boolean expanded = getBoolean(item, "expanded", true); 3746 setBoolean(item, "expanded", !expanded, true); 3747 selectItem(component, item, true); 3748 setLead(component, get(component, ":lead"), item); 3749 setFocus(component); 3750 validate(component); 3751 invoke(component, item, expanded ? "collapse" : "expand"); } 3753 break; 3754 } 3755 } 3756 if ((id != MouseEvent.MOUSE_DRAGGED) || 3757 !getBoolean(item, "selected", false)) { 3758 if (id != MouseEvent.MOUSE_DRAGGED) { 3759 if (setFocus(component)) { repaint(component, classname, item); } } 3761 select(component, item, ("tree" == classname), shiftdown, controldown); 3762 if (clickcount == 2) { invoke(component, item, "perform"); } 3763 } 3764 break; 3765 } 3766 item = getNextItem(component, item, ("tree" == classname)); 3767 } 3768 } 3769 } 3770 } 3771 else if ("menubar" == classname) { 3772 Object selected = get(component, "selected"); 3773 if (((id == MouseEvent.MOUSE_ENTERED) || (id == MouseEvent.MOUSE_EXITED)) && 3774 (part != null) && (selected == null) && getBoolean(part, "enabled", true)) { 3775 repaint(component, classname, part); 3776 } 3777 else if ((part != null) && ((selected == null) ? 3778 (id == MouseEvent.MOUSE_PRESSED) : 3779 ((id == MouseEvent.MOUSE_ENTERED) || (id == DRAG_ENTERED))) && 3780 getBoolean(part, "enabled", true)) { 3781 set(component, "selected", part); 3783 popupMenu(component); 3784 repaint(component, classname, part); 3785 } 3786 else if ((id == MouseEvent.MOUSE_PRESSED) && (selected != null)) { 3787 closeup(); 3788 } 3789 else if (id == MouseEvent.MOUSE_RELEASED) { 3790 if ((part != insidepart) && ((insidepart == null) || 3791 ((insidepart instanceof Object []) && (getClass(insidepart) != "menu")))) { 3792 if ((insidepart != null) && getBoolean(insidepart, "enabled", true)) { 3793 if (getClass(insidepart) == "checkboxmenuitem") { 3794 changeCheck(insidepart, false); 3795 } 3796 else invoke(insidepart, null, "action"); 3797 } 3798 closeup(); 3799 } 3800 } 3801 } 3802 else if (":popup" == classname) { 3803 if (part != null) { 3804 if (((id == MouseEvent.MOUSE_ENTERED) || (id == DRAG_ENTERED)) && 3805 getBoolean(part, "enabled", true)) { 3806 set(component, "selected", part); 3807 popupMenu(component); 3808 repaint(component, classname, part); 3809 } 3810 else if (id == MouseEvent.MOUSE_RELEASED) { 3811 if ((insidepart == null) || (getClass(insidepart) != "menu")) { 3812 if ((insidepart != null) && getBoolean(insidepart, "enabled", true)) { 3813 if (getClass(insidepart) == "checkboxmenuitem") { 3814 changeCheck(insidepart, false); 3815 } 3816 else invoke(insidepart, null, "action"); 3817 } 3818 closeup(); 3819 } 3820 } 3821 else if (((id == MouseEvent.MOUSE_EXITED) || (id == DRAG_EXITED)) && 3822 getBoolean(part, "enabled", true)) { 3823 if (getClass(part) != "menu") { 3824 set(component, "selected", null); 3825 } 3826 repaint(component, classname, part); 3827 } 3828 } 3829 } 3830 else if ("dialog" == classname) { 3831 if (part == "header") { 3832 if (id == MouseEvent.MOUSE_PRESSED) { 3833 Rectangle bounds = getRectangle(component, "bounds"); 3834 referencex = x - bounds.x; referencey = y - bounds.y; 3835 Object parent = getParent(component); 3836 if (get(parent, ":comp") != component) { removeItemImpl(parent, component); 3838 insertItem(parent, ":comp", component, 0); 3839 set(component, ":parent", parent); 3840 repaint(component); setNextFocusable(component, false); 3842 } 3843 } 3844 else if (id == MouseEvent.MOUSE_DRAGGED) { 3845 Rectangle bounds = getRectangle(component, "bounds"); 3846 Rectangle parents = getRectangle(getParent(component), "bounds"); 3847 int mx = Math.max(0, Math.min(x - referencex, parents.width - bounds.width)); 3848 int my = Math.max(0, Math.min(y - referencey, parents.height - bounds.height)); 3849 if ((bounds.x != mx) || (bounds.y != my)) { 3850 repaint(component, Math.min(bounds.x, mx), Math.min(bounds.y, my), 3852 bounds.width + Math.abs(mx - bounds.x), bounds.height + Math.abs(my - bounds.y)); 3853 bounds.x = mx; bounds.y = my; 3854 } 3855 } 3856 } 3857 else if (!processScroll(x, y, id, component, part) && (part != null)) { 3858 if (id == MouseEvent.MOUSE_PRESSED) { 3859 referencex = x; referencey = y; 3860 } 3861 else if (id == MouseEvent.MOUSE_DRAGGED) { 3862 repaint(component); 3863 Rectangle bounds = getRectangle(component, "bounds"); 3864 if ((part == ":nw") || (part == ":n") || (part == ":ne")) { 3865 bounds.y += y - referencey; bounds.height -= y - referencey; 3866 } 3867 if ((part == ":ne") || (part == ":e") || (part == ":se")) { 3868 bounds.width += x - referencex; 3869 } 3870 if ((part == ":sw") || (part == ":s") || (part == ":se")) { 3871 bounds.height += y - referencey; 3872 } 3873 if ((part == ":nw") || (part == ":w") || (part == ":sw")) { 3874 bounds.x += x - referencex; bounds.width -= x - referencex; 3875 } 3876 referencex = x; referencey = y; 3877 doLayout(component); repaint(component); 3878 } 3879 else if (id == MouseEvent.MOUSE_ENTERED) { 3880 setCursor(Cursor.getPredefinedCursor( 3881 (part == ":n") ? Cursor.N_RESIZE_CURSOR : 3882 (part == ":ne") ? Cursor.NE_RESIZE_CURSOR : 3883 (part == ":e") ? Cursor.E_RESIZE_CURSOR : 3884 (part == ":se") ? Cursor.SE_RESIZE_CURSOR : 3885 (part == ":s") ? Cursor.S_RESIZE_CURSOR : 3886 (part == ":sw") ? Cursor.SW_RESIZE_CURSOR : 3887 (part == ":w") ? Cursor.W_RESIZE_CURSOR : 3888 Cursor.NW_RESIZE_CURSOR)); 3889 } 3890 else if (id == MouseEvent.MOUSE_EXITED) { 3891 setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); 3892 } 3893 } 3894 } 3895 3896 if (popuptrigger) { Object popupmenu = get(component, "popupmenu"); 3898 if (popupmenu != null) { 3899 popupPopup(popupmenu, x, y); 3900 } 3901 } 3902 } 3903 3904 3911 private void setReference(Object component, int x, int y) { 3912 referencex = x; referencey = y; 3913 for (; component != null; component = getParent(component)) { 3914 Rectangle bounds = getRectangle(component, "bounds"); 3915 referencex += bounds.x; referencey += bounds.y; 3916 3917 Rectangle port = getRectangle(component, ":port"); 3918 if (port != null) { Rectangle view = getRectangle(component, ":view"); 3920 referencex -= view.x - port.x; referencey -= view.y - port.y; 3921 } 3922 } 3923 } 3924 3925 3928 private void select(Object component, Object row, 3929 boolean recursive, boolean shiftdown, boolean controldown) { 3930 String selection = getString(component, "selection", "single"); 3931 Object lead = null; 3932 if (shiftdown && (selection != "single") && 3933 ((lead = get(component, ":lead")) != null)) { 3934 extend(component, lead, row, recursive); 3935 } 3936 else { 3937 if (controldown && (selection == "multiple")) { 3938 setBoolean(row, "selected", 3939 !getBoolean(row, "selected", false), false); 3940 repaint(component, null, row); 3941 invoke(component, row, "action"); 3942 set(component, ":anchor", null); 3943 } 3944 else if (controldown && getBoolean(row, "selected", false)) { 3945 for (Object item = row; 3946 item != null; item = getNextItem(component, item, recursive)) { 3947 if (setBoolean(item, "selected", false, false)) { 3948 repaint(component, null, item); 3949 } 3950 } 3951 invoke(component, row, "action"); 3952 set(component, ":anchor", null); 3953 } 3954 else { 3955 selectItem(component, row, recursive); 3956 } 3957 } 3958 setLead(component, (lead != null) ? lead : get(component, ":lead"), row); 3959 } 3960 3961 3968 private Object getNextItem(Object component, 3969 Object item, boolean recursive) { 3970 if (!recursive) { return get(item, ":next"); } 3971 Object next = get(item, ":comp"); 3972 if ((next == null) || !getBoolean(item, "expanded", true)) { 3973 while ((item != component) && ((next = get(item, ":next")) == null)) { 3974 item = getParent(item); 3975 } 3976 } 3977 return next; 3978 } 3979 3980 3983 private void processField(int x, int y, int clickcount, 3984 int id, Object component, 3985 boolean multiline, boolean hidden, int left) { 3986 if (id == MouseEvent.MOUSE_PRESSED) { 3987 setReference(component, 2 + left, 2); 3989 int mx = x - referencex; 3990 int my = 0; 3991 if (!multiline) { 3992 mx += getInteger(component, ":offset", 0); 3993 } else { 3994 Rectangle port = getRectangle(component, ":port"); 3995 mx += port.x - 1; 3996 my = y - referencey + port.y - 1; 3997 } 3998 int caretstart = getCaretLocation(component, mx, my, multiline, hidden); 3999 int caretend = caretstart; 4000 if (clickcount > 1) { 4001 String text = getString(component, "text", ""); 4002 while ((caretstart > 0) && ((clickcount == 2) ? 4003 Character.isLetterOrDigit(text.charAt(caretstart - 1)) : 4004 (text.charAt(caretstart - 1) != '\n'))) { caretstart--; } 4005 while ((caretend < text.length()) && ((clickcount == 2) ? 4006 Character.isLetterOrDigit(text.charAt(caretend)) : 4007 (text.charAt(caretend) != '\n'))) { caretend++; } 4008 } 4009 setInteger(component, "start", caretstart, 0); 4010 setInteger(component, "end", caretend, 0); 4011 setFocus(component); 4012 validate(component); } 4014 else if (id == MouseEvent.MOUSE_DRAGGED) { 4015 int mx = x - referencex; 4016 int my = 0; 4017 if (!multiline) { 4018 mx += getInteger(component, ":offset", 0); 4019 } else { 4020 Rectangle port = getRectangle(component, ":port"); 4021 mx += port.x - 1; 4022 my = y - referencey + port.y - 1; 4023 } 4024 int dragcaret = getCaretLocation(component, mx, my, multiline, hidden); 4025 if (dragcaret != getInteger(component, "end", 0)) { 4026 setInteger(component, "end", dragcaret, 0); 4027 validate(component); } 4029 } 4030 else if ((id == MouseEvent.MOUSE_ENTERED) && (mousepressed == null)) { 4031 setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR)); 4032 } 4033 else if (((id == MouseEvent.MOUSE_EXITED) && (mousepressed == null)) || 4034 ((id == MouseEvent.MOUSE_RELEASED) && 4035 ((mouseinside != component) || (insidepart != null)))) { 4036 setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); 4037 } 4038 } 4039 4040 4043 private int getCaretLocation(Object component, 4044 int x, int y, boolean multiline, boolean hidden) { 4045 Font currentfont = (Font) get(component, "font"); 4046 FontMetrics fm = getFontMetrics((currentfont != null) ? currentfont : font); 4047 char[] chars = multiline ? ((char[]) get(component, ":text")) : 4048 getString(component, "text", "").toCharArray(); int linestart = 0; 4050 if (multiline) { 4051 int height = fm.getHeight(); for (int i = 0; (y >= height) && (i < chars.length); i++) { 4053 if ((chars[i] == '\n') || (chars[i] == '\t')) { 4054 linestart = i + 1; y -= height; 4055 } 4056 } 4057 } 4058 for (int i = linestart; i < chars.length; i++) { 4059 if ((chars[i] == '\n') || (chars[i] == '\t')) { return i; } 4060 int charwidth = fm.charWidth(hidden ? '*' : chars[i]); 4061 if (x <= (charwidth / 2)) { return i; } 4062 x -= charwidth; 4063 } 4064 return chars.length; 4065 } 4066 4067 4070 private boolean processScroll(int x, int y, 4071 int id, Object component, Object part) { 4072 if ((part == "up") || (part == "down") || 4073 (part == "left") || (part == "right")) { 4074 if ((id == MouseEvent.MOUSE_ENTERED) || 4075 (id == MouseEvent.MOUSE_EXITED) || 4076 (id == MouseEvent.MOUSE_PRESSED) || 4077 (id == MouseEvent.MOUSE_RELEASED)) { 4078 if (id == MouseEvent.MOUSE_PRESSED) { 4079 if (processScroll(component, part)) { 4080 setTimer(300L); return true; 4081 } 4082 } 4083 else { 4084 if (id == MouseEvent.MOUSE_RELEASED) { setTimer(0L); } 4085 repaint(component, null, part); 4086 } 4087 } 4088 } 4089 else if ((part == "uptrack") || (part == "downtrack") || 4090 (part == "lefttrack") || (part == "righttrack")) { 4091 if (id == MouseEvent.MOUSE_PRESSED) { 4092 if (processScroll(component, part)) { 4093 setTimer(300L); 4094 } 4095 } 4096 else if (id == MouseEvent.MOUSE_RELEASED) { 4097 setTimer(0L); 4098 } 4099 } 4100 else if ((part == "vknob") || (part == "hknob")) { 4101 if (id == MouseEvent.MOUSE_PRESSED) { 4102 Rectangle port = getRectangle(component, ":port"); 4103 Rectangle view = getRectangle(component, ":view"); 4104 if (part == "hknob") { 4105 referencex = x - view.x * (port.width - 2 * block) / view.width; 4106 } else { 4107 referencey = y - view.y * (port.height - 2 * block) / view.height; 4108 } 4109 } 4110 else if (id == MouseEvent.MOUSE_DRAGGED) { 4111 Rectangle port = getRectangle(component, ":port"); 4112 Rectangle view = getRectangle(component, ":view"); 4113 if (part == "hknob") { 4114 int viewx = (x - referencex) * view.width / (port.width - 2 * block); 4115 viewx = Math.max(0, Math.min(viewx, view.width - port.width)); 4116 if (view.x != viewx) { 4117 view.x = viewx; 4118 repaint(component, null, "horizontal"); 4119 } 4120 } 4121 else { int viewy = (y - referencey) * view.height / (port.height - 2 * block); 4123 viewy = Math.max(0, Math.min(viewy, view.height - port.height)); 4124 if (view.y != viewy) { 4125 view.y = viewy; 4126 repaint(component, null, "vertical"); 4127 } 4128 } 4129 } 4130 } 4131 else if (part == "corner") { 4132 part = "corner"; } 4134 else { if (id == MouseEvent.MOUSE_PRESSED) { 4136 Rectangle port = getRectangle(component, ":port"); 4137 if (port != null) { setReference(component, port.x, port.y); } 4138 } 4139 return false; 4140 } 4141 return true; 4142 } 4143 4144 4147 private boolean processScroll(Object component, Object part) { 4148 Rectangle view = getRectangle(component, ":view"); 4149 Rectangle port = ((part == "left") || (part == "up")) ? null : 4150 getRectangle(component, ":port"); 4151 int dx = 0; int dy = 0; 4152 if (part == "left") { dx = -10; } 4153 else if (part == "lefttrack") { dx = -port.width; } 4154 else if (part == "right") { dx = 10; } 4155 else if (part == "righttrack") { dx = port.width; } 4156 else if (part == "up") { dy = -10; } 4157 else if (part == "uptrack") { dy = -port.height; } 4158 else if (part == "down") { dy = 10; } 4159 else if (part == "downtrack") { dy = port.height; } 4160 if (dx != 0) { 4161 dx = (dx < 0) ? Math.max(-view.x, dx) : 4162 Math.min(dx, view.width - port.width - view.x); 4163 } 4164 else if (dy != 0) { 4165 dy = (dy < 0) ? Math.max(-view.y, dy) : 4166 Math.min(dy, view.height - port.height - view.y); 4167 } 4168 else return false; 4169 if ((dx == 0) && (dy == 0)) { return false; } 4170 view.x += dx; view.y += dy; 4171 repaint(component, null, (dx != 0) ? "horizontal" : "vertical"); 4172 return (((part == "left") || (part == "lefttrack")) && (view.x > 0)) || 4173 (((part == "right") || (part == "righttrack")) && 4174 (view.x < view.width - port.width)) || 4175 (((part == "up") || (part == "uptrack")) && (view.y > 0)) || 4176 (((part == "down") || (part == "downtrack")) && 4177 (view.y < view.height - port.height)); 4178 } 4179 4180 4183 private boolean processSpin(Object component, Object part) { 4184 String text = getString(component, "text", ""); 4185 try { 4186 int itext = Integer.parseInt(text); 4187 int step = getInteger(component, "step", 1); 4188 if ((part == "up") ? 4189 (itext + step <= getInteger(component, "maximum", Integer.MAX_VALUE)) : 4190 (itext - step >= getInteger(component, "minimum", Integer.MIN_VALUE))) { 4191 String value = String.valueOf((part == "up") ? (itext + step) : (itext - step)); 4192 setString(component, "text", value, null); 4193 setInteger(component, "start", value.length(), 0); 4194 setInteger(component, "end", 0, 0); 4195 repaint(component, "spinbox", "text"); 4196 invoke(component, null, "action"); 4197 return true; 4198 } 4199 } catch (NumberFormatException nfe) {} 4200 return false; 4201 } 4202 4203 4206 private boolean invoke(Object component, Object part, String event) { 4207 Object method = get(component, event); 4208 if (method != null) { 4209 invokeImpl(method, part); 4210 return true; 4211 } 4212 return false; 4213 } 4214 4215 4218 private void invokeImpl(Object method, Object part) { 4219 Object [] data = (Object []) method; 4220 Object [] args = (data.length > 2) ? new Object [(data.length - 2) / 3] : null; 4221 if (args != null) for (int i = 0; i < args.length; i++) { 4222 Object target = data[2 + 3 * i]; 4223 if ("thinlet" == target) { 4224 args[i] = this; 4225 } 4226 else { 4227 if ("item" == target) { target = part; } 4228 Object parametername = data[2 + 3 * i + 1]; 4229 if (parametername == null) { 4230 args[i] = target; 4231 } 4233 else { 4234 args[i] = (target != null) ? get(target, parametername) : null; 4235 if (args[i] == null) { args[i] = data[2 + 3 * i + 2]; } 4236 } 4237 } 4238 } 4239 try { 4240 ((Method) data[1]).invoke(data[0], args); 4241 } catch (InvocationTargetException ite) { 4242 handleException(ite.getTargetException()); 4243 } catch (Throwable throwable) { 4244 handleException(throwable); 4245 } 4246 } 4247 4248 4254 protected void handleException(Throwable throwable) { 4255 throwable.printStackTrace(); 4256 } 4257 4258 4261 private boolean findComponent(Object component, int x, int y) { 4262 if (component == content) { 4263 mouseinside = insidepart = null; 4264 mousex = x; mousey = y; 4265 } 4266 if (!getBoolean(component, "visible", true)) { return false; } 4267 Rectangle bounds = getRectangle(component, "bounds"); 4268 if ((bounds == null) || !(bounds.contains(x, y))) { return false; } 4269 mouseinside = component; 4270 x -= bounds.x; y -= bounds.y; 4271 String classname = getClass(component); 4272 4273 if ("combobox" == classname) { 4274 if (getBoolean(component, "editable", true) && (x <= bounds.width - block)) { 4275 Image icon = getIcon(component, "icon", null); 4276 insidepart = ((icon != null) && (x <= 2 + icon.getWidth(this))) ? 4277 "icon" : null; 4278 } else { 4279 insidepart = "down"; 4280 } 4281 } 4282 else if (":combolist" == classname) { 4283 if (!findScroll(component, x, y)) { 4284 y += getRectangle(component, ":view").y; 4285 for (Object choice = get(get(component, "combobox"), ":comp"); 4286 choice != null; choice = get(choice, ":next")) { 4287 Rectangle r = getRectangle(choice, "bounds"); 4288 if ((y >= r.y) && (y < r.y + r.height)) { 4289 insidepart = choice; break; 4290 } 4291 } 4292 } 4293 } 4294 else if ("textarea" == classname) { 4295 findScroll(component, x, y); 4296 } 4297 else if ("tabbedpane" == classname) { 4298 int selected = getInteger(component, "selected", 0); 4299 int i = 0; 4300 for (Object tab = get(component, ":comp"); tab != null; tab = get(tab, ":next")) { 4301 Rectangle r = getRectangle(tab, "bounds"); 4302 if (i == selected) { 4303 Object tabcontent = get(tab, ":comp"); 4304 if ((tabcontent != null) && findComponent(tabcontent, x - r.x, y - r.y)) { 4305 break; 4306 } 4307 } 4308 if (r.contains(x, y)) { 4309 insidepart = tab; break; 4310 } 4311 i++; 4312 } 4313 } 4314 else if (("panel" == classname) || ("desktop" == classname) || 4315 ("dialog" == classname)) { 4316 if ("dialog" == classname) { 4317 boolean resizable = getBoolean(component, "resizable", false); 4318 if (resizable && (x < 4)) { 4319 insidepart = (y < block) ? ":nw" : 4320 (y >= bounds.height - block) ? ":sw" : ":w"; 4321 } 4322 else if (resizable && (y < 4)) { 4323 insidepart = (x < block) ? ":nw" : 4324 (x >= bounds.width - block) ? ":ne" : ":n"; 4325 } 4326 else if (resizable && (x >= bounds.width - 4)) { 4327 insidepart = (y < block) ? ":ne" : 4328 (y >= bounds.height - block) ? ":se" : ":e"; 4329 } 4330 else if (resizable && (y >= bounds.height - 4)) { 4331 insidepart = (x < block) ? ":sw" : 4332 (x >= bounds.width - block) ? ":se" : ":s"; 4333 } 4334 else { 4335 int titleheight = getInteger(component, ":titleheight", 0); 4336 if (y < 4 + titleheight) { 4337 insidepart = "header"; 4338 } 4339 } 4340 } 4341 if ((insidepart == null) && !findScroll(component, x, y)) { 4342 Rectangle port = getRectangle(component, ":port"); 4343 if (port != null) { Rectangle view = getRectangle(component, ":view"); 4345 x += view.x - port.x; y += view.y - port.y; 4346 } 4347 for (Object comp = get(component, ":comp"); 4348 comp != null; comp = get(comp, ":next")) { 4349 if (findComponent(comp, x, y)) { break; } 4350 if (("desktop" == classname) && 4351 getBoolean(comp, "modal", false)) { insidepart = "modal"; break; } } 4353 } 4354 } 4355 else if ("spinbox" == classname) { 4356 insidepart = (x <= bounds.width - block) ? null : 4357 ((y <= bounds.height / 2) ? "up" : "down"); 4358 } 4359 else if ("splitpane" == classname) { 4360 Object comp1 = get(component, ":comp"); 4361 if (comp1 != null) { 4362 if (!findComponent(comp1, x, y)) { 4363 Object comp2 = get(comp1, ":next"); 4364 if (comp2 != null) { 4365 findComponent(comp2, x, y); 4366 } 4367 } 4368 } 4369 } 4370 else if ("list" == classname) { 4371 findScroll(component, x, y); 4372 } 4373 else if ("table" == classname) { 4374 if (!findScroll(component, x, y)) { 4375 } 4376 } 4377 else if ("tree" == classname) { 4378 findScroll(component, x, y); 4379 } 4380 else if ("menubar" == classname) { 4381 for (Object menu = get(component, ":comp"); 4382 menu != null; menu = get(menu, ":next")) { 4383 Rectangle r = getRectangle(menu, "bounds"); 4384 if ((x >= r.x) && (x < r.x + r.width)) { 4385 insidepart = menu; break; 4386 } 4387 } 4388 } 4389 else if (":popup" == classname) { 4390 for (Object menu = get(get(component, "menu"), ":comp"); 4391 menu != null; menu = get(menu, ":next")) { 4392 Rectangle r = getRectangle(menu, "bounds"); 4393 if ((y >= r.y) && (y < r.y + r.height)) { 4394 insidepart = menu; break; 4395 } 4396 } 4397 } 4398 return true; 4399 } 4400 4401 4408 private boolean findScroll(Object component, int x, int y) { 4409 Rectangle port = getRectangle(component, ":port"); 4410 if ((port == null) || port.contains(x, y)) { return false; } 4411 Rectangle view = getRectangle(component, ":view"); 4412 Rectangle horizontal = getRectangle(component, ":horizontal"); 4413 Rectangle vertical = getRectangle(component, ":vertical"); 4414 if ((horizontal != null) && horizontal.contains(x, y)) { 4415 findScroll(x - horizontal.x, horizontal.width, port.width, view.x, view.width, true); 4416 } 4417 else if ((vertical != null) && vertical.contains(x, y)) { 4418 findScroll(y - vertical.y, vertical.height, port.height, view.y, view.height, false); 4419 } 4420 else { insidepart = "corner"; } 4421 return true; 4422 } 4423 4424 4432 private void findScroll(int p, int size, int portsize, int viewp, int viewsize, boolean horizontal) { 4433 if (p < block) { insidepart = horizontal ? "left" : "up"; } 4434 else if (p > size - block) { insidepart = horizontal ? "right" : "down"; } 4435 else { 4436 int track = size - 2 * block; 4437 if (track < 10) { insidepart = "corner"; return; } int knob = Math.max(track * portsize / viewsize, 10); 4439 int decrease = viewp * (track - knob) / (viewsize - portsize); 4440 if (p < block + decrease) { insidepart = horizontal ? "lefttrack" : "uptrack"; } 4441 else if (p < block + decrease + knob) { insidepart = horizontal ? "hknob" : "vknob"; } 4442 else { insidepart = horizontal ? "righttrack" : "downtrack"; } 4443 } 4444 } 4445 4446 4449 private void repaint(Object component, Object classname, Object part) { 4450 Rectangle b = getRectangle(component, "bounds"); 4451 if (classname == "combobox") { repaint(component, b.x + b.width - block, b.y, block, b.height); } 4454 else if (classname == "spinbox") { 4455 if (part == "text") { repaint(component, b.x, b.y, b.width - block, b.height); 4457 } 4458 else { repaint(component, b.x + b.width - block, 4460 (part == "up") ? b.y : (b.y + b.height - b.height / 2), block, b.height / 2); 4461 } 4462 } 4463 else if ((classname == "tabbedpane") || (classname == "menubar") || (classname == ":popup")) { Rectangle r = getRectangle(part, "bounds"); 4469 repaint(component, b.x + r.x, b.y + r.y, 4470 (classname == ":popup") ? b.width : r.width, r.height); 4471 } 4472 else if ((part == "left") || (part == "right")) { Rectangle r = getRectangle(component, ":horizontal"); 4475 repaint(component, b.x + ((part == "left") ? r.x : (r.x + r.width - block)), b.y + r.y, block, r.height); 4476 } 4477 else if ((part == "up") || (part == "down")) { Rectangle r = getRectangle(component, ":vertical"); 4479 repaint(component, b.x + r.x, b.y + ((part == "up") ? r.y : (r.y + r.height - block)), r.width, block); 4480 } 4481 else if ((part == "text") || (part == "horizontal") || (part == "vertical")) { 4482 Rectangle port = getRectangle(component, ":port"); repaint(component, b.x + port.x, b.y + port.y, port.width, port.height); 4484 if (part == "horizontal") { 4485 Rectangle r = getRectangle(component, ":horizontal"); 4486 repaint(component, b.x + r.x, b.y + r.y, r.width, r.height); 4487 repaint(component, b.x + r.x, b.y, r.width, port.y); } 4489 else if (part == "vertical") { 4490 Rectangle r = getRectangle(component, ":vertical"); 4491 repaint(component, b.x + r.x, b.y + r.y, r.width, r.height); 4492 } 4493 } 4494 else { Rectangle port = getRectangle(component, ":port"); 4496 Rectangle view = getRectangle(component, ":view"); 4497 Rectangle r = getRectangle(part, "bounds"); 4498 if ((r.y + r.height >= view.y) && (r.y <= view.y + port.height)) { 4499 repaint(component, b.x + port.x, b.y + port.y - view.y + r.y, 4500 port.width, r.height); 4501 } 4503 } 4504 } 4505 4506 4510 private void validate(Object component) { 4511 repaint(component); 4512 Rectangle bounds = getRectangle(component, "bounds"); 4513 if (bounds != null) { bounds.width = -1 * Math.abs(bounds.width); } 4514 } 4515 4516 4520 public void repaint(Object component) { 4521 Rectangle bounds = getRectangle(component, "bounds"); 4522 if (bounds != null) { 4523 repaint(component, bounds.x, bounds.y, bounds.width, bounds.height); 4524 } 4525 } 4526 4527 4535 private void repaint(Object component, int x, int y, int width, int height) { 4536 while ((component = getParent(component)) != null) { 4537 Rectangle bounds = getRectangle(component, "bounds"); 4538 x += bounds.x; y += bounds.y; 4539 Rectangle view = getRectangle(component, ":view"); 4540 if (view != null) { 4541 Rectangle port = getRectangle(component, ":port"); 4542 x += -view.x + port.x; y += -view.y + port.y; } 4544 } 4545 repaint(x, y, width, height); 4546 } 4547 4548 4556 public boolean requestFocus(Object component) { if (isFocusable(component, true)) { 4558 setFocus(component); 4559 repaint(component); 4560 return true; 4561 } 4562 return false; 4563 } 4564 4565 4570 private boolean setFocus(Object component) { 4571 if (!focusinside) { requestFocus(); 4573 } 4574 if (focusowner != component) { 4575 Object focused = focusowner; 4576 if (focusowner != null) { 4577 focusowner = null; repaint(focused); 4579 invoke(focused, null, "focuslost"); 4581 } 4582 if(focusowner == null) { focusowner = component; 4584 invoke(component, null, "focusgained"); 4586 } 4587 return true; 4588 } 4589 return false; 4590 } 4591 4592 4595 private boolean setNextFocusable(Object current, boolean outgo) { 4596 boolean consumed = true; 4597 for (Object next = null, component = current; true; component = next) { 4598 next = get(component, ":comp"); if (next == null) { next = get(component, ":next"); } while (next == null) { component = getParent(component); if (component == null) { return false; } 4603 if ((component == content) || ((getClass(component) == "dialog") && 4604 (!outgo || getBoolean(component, "modal", false)))) { 4605 consumed = false; next = component; } 4608 else { 4609 next = get(component, ":next"); 4610 } 4611 } 4612 if (next == current) { return false; } if (isFocusable(next, false)) { 4614 setFocus(next); 4615 return consumed; 4616 } 4617 } 4618 } 4619 4620 4623 private boolean setPreviousFocusable(Object component, boolean outgo) { 4624 for (int i = 0; i < 2; i++) { Object previous = getPreviousFocusable(component, null, true, false, (i == 0), outgo); 4626 if (previous != null) { 4627 setFocus(previous); 4628 return (i == 0); 4629 } 4630 } 4631 return false; 4632 } 4633 4634 4642 private Object getPreviousFocusable(Object component, 4643 Object block, boolean start, boolean upward, boolean backward, boolean outgo) { 4644 Object previous = null; 4645 if ((component != null) && (component != block)) { 4646 boolean go = ((getClass(component) != "dialog") || 4647 (outgo && !getBoolean(component, "modal", false))); 4648 if (!start && !upward && go) { 4649 previous = getPreviousFocusable(get(component, ":next"), block, false, false, backward, outgo); 4650 } 4651 if ((previous == null) && ((upward && backward) || (!start && !upward))) { 4652 previous = getPreviousFocusable(get(component, ":comp"), block, false, false, backward, outgo); 4653 if ((previous == null) && isFocusable(component, false)) { 4654 previous = component; 4655 } 4656 } 4657 if ((previous == null) && (start || upward) && go) { 4658 previous = getPreviousFocusable(getParent(component), component, false, true, backward, outgo); 4659 } 4660 if ((previous == null) && (start || upward) && !backward && go) { 4661 previous = getPreviousFocusable(get(component, ":next"), block, false, false, backward, outgo); 4662 } 4663 } 4664 return previous; 4665 } 4666 4667 4674 private boolean isFocusable(Object component, boolean forced) { 4675 String classname = getClass(component); 4676 if ((classname == "button") || (classname == "checkbox") || ("togglebutton" == classname) || 4677 (classname == "combobox") || (classname == "textfield") || 4678 (classname == "passwordfield") || (classname == "textarea") || 4679 (classname == "spinbox") || (classname == "slider") || 4680 (classname == "list") || (classname == "table") || (classname == "tree") || 4681 (classname == "tabbedpane") || (forced && (classname == "splitpane"))) { 4682 for (Object comp = component; comp != null;) { 4683 if (!getBoolean(comp, "enabled", true) || !getBoolean(comp, "visible", true)) { 4685 return false; 4686 } 4687 Object parent = getParent(comp); 4688 if ((getClass(comp) == "tab") && (getItem(parent, 4690 getInteger(parent, "selected", 0)) != comp)) { return false; } 4691 comp = parent; 4692 } 4693 return true; 4694 } 4695 return false; 4696 } 4697 4698 4700 4707 public static Object create(String classname) { for (int i = 0; i < dtd.length; i += 3) { 4709 if (dtd[i].equals(classname)) { 4710 return createImpl((String ) dtd[i]); 4711 } 4712 } 4713 throw new IllegalArgumentException ("unknown " + classname); 4714 } 4715 4716 4722 public static String getClass(Object component) { return (String ) get(component, ":class"); 4724 } 4725 4726 4731 public Object getDesktop() { return content; 4733 } 4734 4735 4738 private static Object createImpl(String classname) { 4739 return new Object [] { ":class", classname, null }; 4740 } 4741 4742 4745 private static boolean set(Object component, Object key, Object value) { 4746 Object [] previous = (Object []) component; 4747 for (Object [] entry = previous; entry != null; 4748 entry = (Object []) entry[2]) { 4749 if (entry[0] == key) { 4750 if (value != null) { Object oldvalue = entry[1]; 4752 entry[1] = value; 4753 return !value.equals(oldvalue); 4754 } 4755 else { previous[2] = entry[2]; 4757 entry[2] = null; 4758 return true; 4759 } 4760 } 4761 previous = entry; 4762 } 4763 if (value != null) { previous[2] = new Object [] { key, value, null }; 4765 return true; 4766 } 4767 return false; 4768 } 4769 4770 4773 private static Object get(Object component, Object key) { 4774 for (Object [] entry = (Object []) component; entry != null; 4775 entry = (Object []) entry[2]) { 4776 if (entry[0] == key) { 4777 return entry[1]; 4778 } 4779 } 4780 return null; 4781 } 4782 4783 4789 public int getCount(Object component) { 4790 return getItemCountImpl(component, ":comp"); 4791 } 4792 4793 4799 public Object getParent(Object component) { 4800 return get(component, ":parent"); 4801 } 4802 4803 4809 public int getSelectedIndex(Object component) { 4810 String classname = getClass(component); 4811 if ((classname == "combobox") || (classname == "tabbedpane")) { 4812 return getInteger(component, "selected", (classname == "combobox") ? -1 : 0); 4813 } 4814 if ((classname == "list") || (classname == "table") || (classname == "tree")) { 4815 Object item = get(component, ":comp"); 4816 for (int i = 0; item != null; i++) { 4817 if (getBoolean(item, "selected", false)) { return i; } 4818 item = get(item, ":next"); 4819 } 4820 return -1; 4821 } 4822 throw new IllegalArgumentException (classname); 4823 } 4824 4825 4831 public Object getSelectedItem(Object component) { 4832 String classname = getClass(component); 4833 if ((classname == "combobox") || (classname == "tabbedpane")) { 4834 int index = getInteger(component, "selected", 4835 (classname == "combobox") ? -1 : 0); 4836 return (index != -1) ? getItemImpl(component, ":comp", index) : null; 4837 } 4838 if ((classname == "list") || (classname == "table") || (classname == "tree")) { 4839 for (Object item = findNextItem(component, classname, null); item != null; 4840 item = findNextItem(component, classname, item)) { 4841 if (getBoolean(item, "selected", false)) { return item; } 4842 } 4843 return null; 4844 } 4845 throw new IllegalArgumentException (classname); 4846 } 4847 4848 4855 public Object [] getSelectedItems(Object component) { 4856 String classname = getClass(component); 4857 Object [] selecteds = new Object [0]; 4858 for (Object item = findNextItem(component, classname, null); item != null; 4859 item = findNextItem(component, classname, item)) { 4860 if (getBoolean(item, "selected", false)) { 4861 Object [] temp = new Object [selecteds.length + 1]; 4862 System.arraycopy(selecteds, 0, temp, 0, selecteds.length); 4863 temp[selecteds.length] = item; 4864 selecteds = temp; 4865 } 4866 } 4867 return selecteds; 4868 } 4869 4870 4873 private Object findNextItem(Object component, String classname, Object item) { 4874 if (item == null) { return get(component, ":comp"); 4876 } 4877 else if ("tree" == classname) { Object next = get(item, ":comp"); 4879 if ((next == null) || !getBoolean(item, "expanded", true)) { while ((item != component) && ((next = get(item, ":next")) == null)) { 4881 item = getParent(item); } 4883 } 4884 return next; 4885 } 4886 else { return get(item, ":next"); 4888 } 4889 } 4890 4891 4896 public void removeAll(Object component) { 4897 if (get(component, ":comp") != null) { 4898 set(component, ":comp", null); 4899 update(component, "validate"); 4900 } 4901 } 4902 4903 4906 private static int getItemCountImpl(Object component, String key) { 4907 int i = 0; 4908 for (Object comp = get(component, key); comp != null; comp = get(comp, ":next")) { 4909 i++; 4910 } 4911 return i; 4912 } 4913 4914 4921 public Object getItem(Object component, int index) { 4922 return getItemImpl(component, ":comp", index); 4923 } 4924 4925 4931 public Object [] getItems(Object component) { 4932 Object [] items = new Object [getItemCountImpl(component, ":comp")]; 4933 Object comp = get(component, ":comp"); 4934 for (int i = 0; i < items.length; i++) { 4935 items[i] = comp; 4936 comp = get(comp, ":next"); 4937 } 4938 return items; 4939 } 4940 4941 4944 private static Object getItemImpl(Object component, Object key, int index) { 4945 int i = 0; 4946 for (Object item = get(component, key); item != null; item = get(item, ":next")) { 4947 if (i == index) { return item; } 4948 i++; 4949 } 4950 return null; 4951 } 4952 4953 4956 private int getIndex(Object component, Object value) { 4957 int index = 0; 4958 for (Object item = get(component, ":comp"); item != null; item = get(item, ":next")) { 4959 if (value == item) { return index; } 4960 index++; 4961 } 4962 return -1; 4963 } 4964 4965 4970 public void add(Object component) { 4971 add(content, component, 0); 4972 } 4973 4974 4980 public void add(Object parent, Object component) { 4981 add(parent, component, -1); 4982 } 4983 4984 4992 public void add(Object parent, Object component, int index) { 4993 addImpl(parent, component, index); 4994 update(component, "validate"); 4995 if (parent == content) { 4996 setNextFocusable(component, false); 4997 } 4998 } 4999 5000 5003 private void insertItem(Object parent, 5004 Object key, Object component, int index) { 5005 Object item = parent, next = get(parent, key); 5006 for (int i = 0;; i++) { 5007 if ((i == index) || (next == null)) { 5008 set(item, key, component); 5009 set(component, ":next", next); 5010 break; 5011 } 5012 next = get(item = next, key = ":next"); 5013 } 5014 } 5015 5016 5022 public void remove(Object component) { 5023 update(component, "validate"); 5024 Object parent = getParent(component); 5025 Object classname = getClass(component); 5026 if (("popupmenu" == classname) || ("header" == classname)) { 5027 set(parent, classname, null); 5028 } 5029 else { 5030 removeItemImpl(parent, component); 5031 for (Object comp = focusowner; comp != null; comp = getParent(comp)) { 5033 if (comp == component) { 5034 setNextFocusable(parent, false); break; 5035 } 5036 } 5037 } 5038 } 5039 5040 5045 private void removeItemImpl(Object parent, Object component) { 5046 Object previous = null; for (Object comp = get(parent, ":comp"); comp != null;) { 5048 Object next = get(comp, ":next"); 5049 if (next == component) { previous = comp; break; } 5050 comp = next; 5051 } 5052 set((previous != null) ? previous : parent, 5053 (previous != null) ? ":next" : ":comp", get(component, ":next")); 5054 set(component, ":next", null); set(component, ":parent", null); } 5056 5057 5063 public Object find(String name) { 5064 return find(content, name); 5065 } 5066 5067 5074 public Object find(Object component, String name) { 5075 if (name.equals(get(component, "name"))) { 5076 return component; 5077 } 5078 Object found = null; 5080 for (Object comp = get(component, ":comp"); comp != null; comp = get(comp, ":next")) { 5081 if ((found = find(comp, name)) != null) { return found; } 5082 } 5083 Object header = get(component, "header"); if ((header != null) && ((found = find(header, name)) != null)) { return found; } 5086 Object popupmenu = get(component, "popupmenu"); if ((popupmenu != null) && ((found = find(popupmenu, name)) != null)) { return found; } 5089 return null; 5090 } 5091 5092 5107 private boolean checkMnemonic(Object component, 5108 boolean parent, Object checked, int keycode, int modifiers) { 5109 if ((component == null) || !getBoolean(component, "visible", true) || 5110 !getBoolean(component, "enabled", true)) { return false; 5112 } 5113 String classname = getClass(component); 5114 if ("label" == classname) { 5115 if (hasMnemonic(component, keycode, modifiers)) { 5116 Object labelfor = get(component, "for"); 5117 if (labelfor != null) { 5118 requestFocus(labelfor); 5119 return true; 5120 } 5121 } 5122 } 5123 else if ("button" == classname) { 5124 if (((modifiers == 0) && 5125 (((keycode == KeyEvent.VK_ENTER) && (get(component, "type") == "default")) || 5126 ((keycode == KeyEvent.VK_ESCAPE) && (get(component, "type") == "cancel")))) || 5127 hasMnemonic(component, keycode, modifiers)) { 5128 invoke(component, null, "action"); 5129 repaint(component); 5130 return true; 5131 } 5132 } 5133 else if (("checkbox" == classname) || ("togglebutton" == classname)) { 5134 if (hasMnemonic(component, keycode, modifiers)) { 5135 changeCheck(component, true); 5136 repaint(component); 5137 return true; 5138 } 5139 } 5140 else if ("menubar" == classname) { 5141 for (Object menu = get(component, ":comp"); menu != null; menu = get(menu, ":next")) { 5142 if (hasMnemonic(menu, keycode, modifiers) || 5143 ((modifiers == 0) && (keycode == KeyEvent.VK_F10))) { 5144 closeup(); 5145 set(component, "selected", menu); 5146 popupMenu(component); 5147 repaint(component, "menubar", menu); 5148 return true; 5149 } 5150 } 5151 } 5152 else if (("menuitem" == classname) || ("checkboxmenuitem" == classname)) { 5153 if (hasAccelerator(component, keycode, modifiers)) { 5154 invoke(component, null, "action"); 5155 } 5156 } 5157 else if ("tabbedpane" == classname) { 5158 int selected = getInteger(component, "selected", 0); int i = 0; 5159 for (Object tab = get(component, ":comp"); tab != null; tab = get(tab, ":next")) { 5160 if (hasMnemonic(tab, keycode, modifiers)) { 5161 if (selected != i) { 5162 setInteger(component, "selected", i, 0); 5163 repaint(component); 5164 invoke(component, getItem(component, i), "action"); 5165 } 5166 return true; 5167 } 5168 i++; 5169 } 5170 Object comp = get(getItem(component, selected), ":comp"); 5171 if ((comp != null) && (comp != checked) && 5172 checkMnemonic(comp, false, null, keycode, modifiers)) { 5173 return true; 5174 } 5175 } 5176 if (("panel" == classname) || ("desktop" == classname) || 5178 ("dialog" == classname) || ("splitpane" == classname) || 5179 ("menubar" == classname) || ("menu" == classname)) { 5180 for (Object comp = get(component, ":comp"); comp != null; comp = get(comp, ":next")) { 5181 if ((comp != checked) && checkMnemonic(comp, false, null, keycode, modifiers)) { return true; } 5182 } 5183 } 5184 if (parent && (("dialog" != classname) || !getBoolean(component, "modal", false))) { 5186 if (checkMnemonic(getParent(component), true, 5187 ("tab" == classname) ? checked : component, keycode, modifiers)) { return true; } 5188 } 5189 return false; 5190 } 5191 5192 5198 private boolean hasMnemonic(Object component, int keycode, int modifiers) { 5199 if (modifiers == InputEvent.ALT_MASK) { 5200 int index = getInteger(component, "mnemonic", -1); 5201 if (index != -1) { 5202 String text = getString(component, "text", null); 5203 return (text != null) && (text.length() > index) && 5204 (Character.toUpperCase(text.charAt(index)) == keycode); 5205 } 5206 } 5207 return false; 5208 } 5209 5210 5216 private boolean hasAccelerator(Object component, int keycode, int modifiers) { 5217 Object accelerator = get(component, "accelerator"); 5218 if (accelerator != null) { 5219 long keystroke = ((Long ) accelerator).longValue(); 5220 return ((keystroke >> 32) == modifiers) && ((keystroke & 0xffff) == keycode); 5221 } 5222 return false; 5223 } 5224 5225 5234 public void putProperty(Object component, Object key, Object value) { 5235 Object table = get(component, ":bind"); 5236 if (value != null) { 5237 if (table == null) { 5238 set(component, ":bind", table = new Hashtable()); 5239 } 5240 ((Hashtable) table).put(key, value); 5241 } 5242 else if (table != null) { 5243 ((Hashtable) table).remove(key); 5244 } 5245 } 5246 5247 5254 public Object getProperty(Object component, Object key) { 5255 Object table = get(component, ":bind"); 5256 return (table != null) ? ((Hashtable) table).get(key) : null; 5257 } 5258 5259 5261 5270 public Object parse(String path) throws IOException { 5271 return parse(path, this); 5272 } 5273 5274 5283 public Object parse(String path, Object handler) throws IOException { 5284 InputStream inputstream = null; 5285 try { 5286 inputstream = getClass().getResourceAsStream(path); 5287 if (inputstream == null) { 5288 try { 5289 inputstream = new URL(path).openStream(); 5290 } catch (MalformedURLException mfe) { } 5291 } 5292 } catch (Throwable e) {} 5293 return parse(inputstream, handler); 5294 } 5295 5296 5303 public Object parse(InputStream inputstream) throws IOException { 5304 return parse(inputstream, this); 5305 } 5306 5307 5315 public Object parse(InputStream inputstream, Object handler) throws IOException { 5316 return parse(inputstream, true, false, handler); 5317 } 5318 5319 5327 protected void parseXML(InputStream inputstream) throws IOException { 5328 parse(inputstream, false, false, null); 5329 } 5330 5331 5337 protected void startElement(String name, Hashtable attributelist) {} 5338 5339 5344 protected void characters(String text) {} 5345 5346 5349 protected void endElement() {} 5350 5351 5361 protected Object parseDOM(InputStream inputstream) throws IOException { 5362 return parse(inputstream, false, true, null); 5363 } 5364 5365 5372 protected static String getDOMAttribute(Object node, String key) { 5373 return (String ) get(node, key.intern()); 5374 } 5375 5376 5382 protected static String getDOMText(Object node) { 5383 return (String ) get(node, ":text"); 5384 } 5385 5386 5393 protected static int getDOMCount(Object node, String key) { 5394 return getItemCountImpl(node, key.intern()); 5395 } 5396 5397 5405 protected static Object getDOMNode(Object node, String key, int index) { 5406 return getItemImpl(node, key.intern(), index); 5407 } 5408 5409 5416 public void setResourceBundle(ResourceBundle resourcebundle) { 5417 this.resourcebundle = resourcebundle; 5418 } 5419 5420 5430 private Object parse(InputStream inputstream, 5431 boolean validate, boolean dom, Object handler) throws IOException { 5432 Reader reader = new BufferedReader(new InputStreamReader(inputstream)); 5433 try { 5434 Object [] parentlist = null; 5435 Object current = null; 5436 Hashtable attributelist = null; 5437 Vector methods = (validate && !dom) ? new Vector() : null; 5438 StringBuffer text = new StringBuffer (); 5439 for (int c = reader.read(); c != -1;) { 5440 if (c == '<') { 5441 if ((c = reader.read()) == '/') { if (text.length() > 0) { 5443 if (text.charAt(text.length() - 1) == ' ') { 5444 text.setLength(text.length() - 1); 5445 } 5446 if (!validate) { 5447 if (dom) { 5448 set(current, ":text", text.toString()); 5449 } else { 5450 characters(text.toString()); 5451 } 5452 } 5453 text.setLength(0); 5457 } 5458 String tagname = (String ) parentlist[2]; for (int i = 0; i < tagname.length(); i++) { if ((c = reader.read()) != tagname.charAt(i)) { 5461 throw new IllegalArgumentException (tagname); 5462 } 5463 } 5464 while (" \t\n\r".indexOf(c = reader.read()) != -1); if (c != '>') throw new IllegalArgumentException (); c = reader.read(); 5467 if (!validate && !dom) { endElement(); } 5468 if (parentlist[0] == null) { 5469 reader.close(); 5470 finishParse(methods, current, handler); 5471 return current; 5472 } 5473 current = parentlist[0]; 5474 parentlist = (Object []) parentlist[1]; 5475 } 5476 else if (c == '!') { while ((c = reader.read()) != '>'); } 5479 else if (c == '?') { boolean question = false; while (((c = reader.read()) != '>') || !question) { question = (c == '?'); } 5482 } 5483 else { text.setLength(0); 5485 boolean iscomment = false; 5486 while (">/ \t\n\r".indexOf(c) == -1) { 5487 text.append((char) c); 5488 if ((text.length() == 3) && (text.charAt(0) == '!') && 5489 (text.charAt(1) == '-') && (text.charAt(2) == '-')) { 5490 int m = 0; 5491 while (true) { 5492 c = reader.read(); 5493 if (c == '-') { m++; } 5494 else if ((c == '>') && (m >= 2)) { break; } 5495 else { m = 0; } 5496 } 5497 iscomment = true; 5498 } 5499 c = reader.read(); 5500 } 5501 if (iscomment) { continue; } 5502 String tagname = text.toString(); 5503 parentlist = new Object [] { current, parentlist, tagname }; 5504 if (validate) { 5505 current = (current != null) ? 5506 addElement(current, tagname) : create(tagname); 5507 } else { 5508 if (dom) { 5509 Object parent = current; 5510 current = createImpl(tagname = tagname.intern()); 5511 if (parent != null) { 5512 insertItem(parent, tagname, current, -1); 5513 } 5515 } else { 5516 current = tagname; 5517 } 5518 } 5519 text.setLength(0); 5520 while (true) { 5521 boolean whitespace = false; 5522 while (" \t\n\r".indexOf(c) != -1) { 5523 c = reader.read(); 5524 whitespace = true; 5525 } 5526 if (c == '>') { 5527 if (!validate && !dom) { 5528 startElement((String ) current, attributelist); attributelist = null; 5529 } 5530 c = reader.read(); 5531 break; 5532 } 5533 else if (c == '/') { 5534 if ((c = reader.read()) != '>') { 5535 throw new IllegalArgumentException (); } 5537 if (!validate && !dom) { 5538 startElement((String ) current, attributelist); attributelist = null; 5539 endElement(); 5540 } 5541 if (parentlist[0] == null) { 5542 reader.close(); 5543 finishParse(methods, current, handler); 5544 return current; 5545 } 5546 current = parentlist[0]; 5547 parentlist = (Object []) parentlist[1]; 5548 c = reader.read(); 5549 break; 5550 } 5551 else if (whitespace) { 5552 while ("= \t\n\r".indexOf(c) == -1) { 5553 text.append((char) c); 5554 c = reader.read(); 5555 } 5556 String key = text.toString(); 5557 text.setLength(0); 5558 while (" \t\n\r".indexOf(c) != -1) c = reader.read(); 5559 if (c != '=') throw new IllegalArgumentException (); 5560 while (" \t\n\r".indexOf(c = reader.read()) != -1); 5561 char quote = (char) c; 5562 if ((c != '\"') && (c != '\'')) throw new IllegalArgumentException (); 5563 while (quote != (c = reader.read())) { 5564 if (c == '&') { 5565 StringBuffer eb = new StringBuffer (); 5566 while (';' != (c = reader.read())) { eb.append((char) c); } 5567 String entity = eb.toString(); 5568 if ("lt".equals(entity)) { text.append('<'); } 5569 else if ("gt".equals(entity)) { text.append('>'); } 5570 else if ("amp".equals(entity)) { text.append('&'); } 5571 else if ("quot".equals(entity)) { text.append('"'); } 5572 else if ("apos".equals(entity)) { text.append('\''); } 5573 else if (entity.startsWith("#")) { 5574 boolean hexa = (entity.charAt(1) == 'x'); 5575 text.append((char) Integer.parseInt(entity.substring(hexa ? 2 : 1), hexa ? 16 : 10)); 5576 } 5577 else throw new IllegalArgumentException ("unknown " + "entity " + entity); 5578 } 5579 else text.append((char) c); 5580 } 5581 if (validate) { 5582 addAttribute(current, key, text.toString(), methods); 5583 } else { 5584 if (dom) { 5585 set(current, key.intern(), text.toString()); 5586 } else { 5587 if (attributelist == null) { attributelist = new Hashtable(); } 5588 attributelist.put(key, text.toString()); 5589 } 5590 } 5591 text.setLength(0); 5593 c = reader.read(); 5594 } 5595 else throw new IllegalArgumentException (); 5596 } 5597 } 5598 } 5599 else { 5600 if (" \t\n\r".indexOf(c) != -1) { 5601 if ((text.length() > 0) && (text.charAt(text.length() - 1) != ' ')) { 5602 text.append(' '); 5603 } 5604 } 5605 else { 5606 text.append((char) c); 5607 } 5608 c = reader.read(); 5609 } 5610 } 5611 throw new IllegalArgumentException (); 5612 } 5613 finally { 5614 if (reader != null) { reader.close(); } 5615 } 5616 } 5617 5618 5621 private void finishParse(Vector methods, Object root, Object handler) { 5622 if (methods != null) { 5623 for (int i = 0; i < methods.size(); i += 3) { 5624 Object component = methods.elementAt(i); 5625 Object [] definition = (Object []) methods.elementAt(i + 1); 5626 String value = (String ) methods.elementAt(i + 2); 5627 5628 if ("method" == definition[0]) { 5629 Object [] method = getMethod(component, value, root, handler); 5630 if ("init" == definition[1]) { 5631 invokeImpl(method, null); 5632 } 5633 else { 5634 set(component, definition[1], method); 5635 } 5636 } 5637 else { Object reference = find(root, value); if (reference == null) throw new IllegalArgumentException (value + " not found"); 5640 set(component, definition[1], reference); 5641 } 5642 } 5643 } 5644 } 5645 5646 5653 private void addImpl(Object parent, Object component, int index) { 5654 String parentclass = getClass(parent); 5655 String classname = getClass(component); 5656 if ((("combobox" == parentclass) && ("choice" == classname)) || 5657 (("tabbedpane" == parentclass) && ("tab" == classname)) || 5658 (("list" == parentclass) && ("item" == classname)) || 5659 (("table" == parentclass) && ("row" == classname)) || 5660 (("header" == parentclass) && ("column" == classname)) || 5661 (("row" == parentclass) && ("cell" == classname)) || 5662 ((("tree" == parentclass) || ("node" == parentclass)) && ("node" == classname)) || 5663 (("menubar" == parentclass) && ("menu" == classname)) || 5664 ((("menu" == parentclass) || ("popupmenu" == parentclass)) && 5665 (("menu" == classname) || ("menuitem" == classname) || 5666 ("checkboxmenuitem" == classname) || ("separator" == classname))) || 5667 ((("panel" == parentclass) || ("desktop" == parentclass) || 5668 ("splitpane" == parentclass) || ("dialog" == parentclass) || 5669 ("tab" == parentclass)) && instance(classname, "component") && 5670 (classname != "popupmenu"))) { 5671 insertItem(parent, ":comp", component, index); 5672 set(component, ":parent", parent); 5673 } 5674 else if ((("table" == parentclass) && ("header" == classname)) || 5675 (("popupmenu" == classname) && instance(parentclass, "component"))) { 5676 set(parent, classname, component); 5677 set(component, ":parent", parent); 5678 } 5679 else throw new IllegalArgumentException (classname + " add " + parentclass); 5680 } 5681 5682 5685 private boolean instance(Object classname, Object extendclass) { 5686 if (classname == extendclass) { return true; } 5687 for (int i = 0; i < dtd.length; i += 3) { 5688 if (classname == dtd[i]) { 5689 return instance(dtd[i + 1], extendclass); 5690 } 5691 } 5692 return false; 5693 } 5694 5695 5698 private Object addElement(Object parent, String name) { 5699 Object component = create(name); 5700 addImpl(parent, component, -1); 5701 return component; 5702 } 5703 5704 5708 private void addAttribute(Object component, String key, String value, Vector lasts) { 5709 if ((resourcebundle != null) && value.startsWith("i18n.")) { 5711 value = resourcebundle.getString(value.substring(5)); 5712 } 5713 5714 Object [] definition = getDefinition(getClass(component), key, null); 5715 key = (String ) definition[1]; 5716 if ("string" == definition[0]) { 5717 setString(component, key, value, (String ) definition[3]); 5718 } 5719 else if ("choice" == definition[0]) { 5720 String [] values = (String []) definition[3]; 5721 setChoice(component, key, value, values, values[0]); 5722 } 5723 else if ("boolean" == definition[0]) { 5724 if ("true".equals(value)) { 5725 if (definition[3] == Boolean.FALSE) { 5726 set(component, key, Boolean.TRUE); 5727 } 5728 } 5729 else if ("false".equals(value)) { 5730 if (definition[3] == Boolean.TRUE) { 5731 set(component, key, Boolean.FALSE); 5732 } 5733 } 5734 else throw new IllegalArgumentException (value); 5735 } 5736 else if ("integer" == definition[0]) { 5737 set(component, key, Integer.valueOf(value)); 5738 } 5739 else if ("icon" == definition[0]) { 5740 set(component, key, getIcon(value)); 5741 } 5742 else if (("method" == definition[0]) || ("component" == definition[0])) { 5743 lasts.addElement(component); 5744 lasts.addElement(definition); 5745 lasts.addElement(value); 5746 } 5747 else if ("property" == definition[0]) { 5748 StringTokenizer st = new StringTokenizer(value, ";"); 5749 while (st.hasMoreTokens()) { 5750 String token = st.nextToken(); 5751 int equals = token.indexOf('='); 5752 if (equals == -1) { throw new IllegalArgumentException (token); } 5753 putProperty(component, token.substring(0, equals), token.substring(equals + 1)); 5754 } 5755 } 5756 else if ("font" == definition[0]) { 5757 String name = null; 5758 boolean bold = false; boolean italic = false; 5759 int size = 0; 5760 StringTokenizer st = new StringTokenizer(value); 5761 while (st.hasMoreTokens()) { 5762 String token = st.nextToken(); 5763 if ("bold".equalsIgnoreCase(token)) { bold = true; } 5764 else if ("italic".equalsIgnoreCase(token)) { italic = true; } 5765 else { 5766 try { 5767 size = Integer.parseInt(token); 5768 } catch (NumberFormatException nfe) { 5769 name = (name == null) ? token : (name + " " + token); 5770 } 5771 } 5772 } 5773 if (name == null) { name = font.getName(); } 5774 if (size == 0) { size = font.getSize(); } 5775 set(component, key, new Font(name, 5776 (bold ? Font.BOLD : 0) | (italic ? Font.ITALIC : 0), size)); 5777 } 5778 else if ("color" == definition[0]) { 5779 int color = 0; 5780 if (value.startsWith("#")) { color = Integer.parseInt(value.substring(1), 16); } 5781 else if (value.startsWith("0x")) { color = Integer.parseInt(value.substring(2), 16); } 5782 else { StringTokenizer st = new StringTokenizer(value, " \r\n\t,"); 5784 color = 0xff000000 | ((Integer.parseInt(st.nextToken()) & 0xff) << 16) | 5785 ((Integer.parseInt(st.nextToken()) & 0xff) << 8) | 5786 (Integer.parseInt(st.nextToken()) & 0xff); 5787 } 5788 set(component, key, new Color(color)); 5789 } 5790 else if ("keystroke" == definition[0]) { 5791 setKeystrokeImpl(component, key, value); 5792 } 5793 else if ("bean" == definition[0]) { 5794 try { 5795 Component bean = (Component) Class.forName(value).newInstance(); 5796 set(component, key, bean); 5797 } catch (Exception exc) { throw new IllegalArgumentException (value); } 5798 } 5799 else throw new IllegalArgumentException ((String ) definition[0]); 5800 } 5801 5802 5806 private static Object [] getDefinition(Object classname, String key, String type) { 5807 Object currentname = classname; 5808 while (classname != null) { 5809 for (int i = 0; i < dtd.length; i += 3) { 5810 if (dtd[i] == classname) { 5811 Object [][] attributes = (Object [][]) dtd[i + 2]; 5812 if (attributes != null) { 5813 for (int j = 0; j < attributes.length; j++) { 5814 if (attributes[j][1].equals(key)) { 5815 if ((type != null) && (type != attributes[j][0])) { 5816 throw new IllegalArgumentException (attributes[j][0].toString()); 5817 } 5818 return attributes[j]; 5819 } 5820 } 5821 } 5822 classname = dtd[i + 1]; 5823 break; 5824 } 5825 } 5826 } 5827 throw new IllegalArgumentException ("unknown " + key + " " + type + 5828 " for " + currentname); 5829 } 5830 5831 5833 5836 public void setString(Object component, String key, String value) { 5837 Object [] definition = getDefinition(getClass(component), key, "string"); 5838 if (setString(component, (String ) definition[1], 5839 value, (String ) definition[3])) { 5840 update(component, definition[2]); 5841 } 5842 } 5843 5844 5847 public String getString(Object component, String key) { 5848 return (String ) get(component, key, "string"); 5849 5850 } 5851 5852 5855 public void setChoice(Object component, String key, String value) { 5856 Object [] definition = getDefinition(getClass(component), key, "choice"); 5857 String [] values = (String []) definition[3]; 5858 if (setChoice(component, (String ) definition[1], 5859 value, values, values[0])) { 5860 update(component, definition[2]); 5861 } 5862 } 5863 5864 5867 public String getChoice(Object component, String key) { 5868 Object [] definition = getDefinition(getClass(component), key, "choice"); 5869 return getString(component, (String ) definition[1], 5870 ((String []) definition[3])[0]); 5871 } 5872 5873 5876 public void setBoolean(Object component, String key, boolean value) { 5877 Object [] definition = getDefinition(getClass(component), key, "boolean"); 5878 if (setBoolean(component, (String ) definition[1], 5879 value, (definition[3] == Boolean.TRUE))) { 5880 update(component, definition[2]); 5881 } 5882 } 5883 5884 5887 public boolean getBoolean(Object component, String key) { 5888 return get(component, key, "boolean") == Boolean.TRUE; 5889 } 5890 5891 5894 public void setInteger(Object component, String key, int value) { 5895 Object [] definition = getDefinition(getClass(component), key, "integer"); 5896 if (setInteger(component, (String ) definition[1], 5897 value, ((Integer ) definition[3]).intValue())) { 5898 update(component, definition[2]); 5899 } 5900 } 5901 5902 5905 public int getInteger(Object component, String key) { 5906 return ((Integer ) get(component, key, "integer")).intValue(); 5907 } 5908 5909 5912 public void setIcon(Object component, String key, Image icon) { 5913 Object [] definition = getDefinition(getClass(component), key, "icon"); 5914 if (set(component, definition[1], icon)) { 5915 update(component, definition[2]); 5916 } 5917 } 5918 5919 5922 public Image getIcon(Object component, String key) { 5923 return (Image) get(component, key, "icon"); 5924 } 5925 5926 5929 public void setKeystroke(Object component, String key, String value) { 5930 Object [] definition = getDefinition(getClass(component), key, "keystroke"); 5931 setKeystrokeImpl(component, (String ) definition[1], value); 5933 update(component, definition[2]); 5934 } 5935 5936 5943 public Component getComponent(Object component, String key) { 5944 return (Component) get(component, key, "bean"); 5945 } 5946 5947 5951 public void setFont(Object component, Font font) { setFont(component, "font", font); 5953 } 5954 5955 5961 public void setFont(Object component, String key, Font font) { 5962 Object [] definition = getDefinition(getClass(component), key, "font"); 5963 if (set(component, definition[1], font)) { 5964 update(component, definition[2]); 5965 } 5966 } 5967 5968 5981 public void setColor(Object component, String key, Color color) { 5982 Object [] definition = getDefinition(getClass(component), key, "color"); 5983 if (set(component, definition[1], color)) { 5984 update(component, definition[2]); 5985 } 5986 } 5987 5988 5995 public void setComponent(Object component, String key, Component bean) { 5996 Object [] definition = getDefinition(getClass(component), key, "bean"); 5997 if (set(component, definition[1], font)) { 5998 update(component, definition[2]); 5999 } 6000 } 6001 6002 6005 private void setKeystrokeImpl(Object component, String key, String value) { 6006 Long keystroke = null; 6007 if (value != null) { 6008 String token = value; 6009 try { 6010 int keycode = 0, modifiers = 0; 6011 StringTokenizer st = new StringTokenizer(value, " \r\n\t+"); 6012 while (st.hasMoreTokens()) { 6013 token = st.nextToken().toUpperCase(); 6014 try { 6015 modifiers = modifiers | InputEvent.class.getField(token + "_MASK").getInt(null); 6016 } catch (Exception exc) { keycode = KeyEvent.class.getField("VK_" + token).getInt(null); 6018 } 6019 } 6020 keystroke = new Long (((long) modifiers) << 32 | keycode); 6021 } catch (Exception exc) { throw new IllegalArgumentException (token); } 6022 } 6023 set(component, key, keystroke); 6024 } 6025 6026 6028 6031 public Object getWidget(Object component, String key) { 6032 if ("popupmenu".equals(key)) { return get(component, "popupmenu");} 6033 else if ("header".equals(key)) { return get(component, "header");} 6034 else throw new IllegalArgumentException (key); 6035 } 6036 6037 6040 private static Object get(Object component, String key, String type) { 6041 Object [] definition = getDefinition(getClass(component), key, type); 6042 Object value = get(component, definition[1]); 6043 return (value != null) ? value : definition[3]; 6044 } 6045 6046 6058 public void setMethod(Object component, String key, String value, Object root, Object handler) { 6059 key = (String ) getDefinition(getClass(component), key, "method")[1]; 6060 Object [] method = getMethod(component, value, root, handler); 6061 set(component, key, method); 6062 } 6063 6064 6075 private Object [] getMethod(Object component, String value, Object root, Object handler) { 6076 StringTokenizer st = new StringTokenizer(value, "(, \r\n\t)"); 6077 String methodname = st.nextToken(); 6078 int n = st.countTokens(); 6079 Object [] data = new Object [2 + 3 * n]; 6080 Class [] parametertypes = (n > 0) ? new Class [n] : null; 6081 for (int i = 0; i < n; i++) { 6082 String arg = st.nextToken(); 6083 if ("thinlet".equals(arg)) { 6084 data[2 + 3 * i] = "thinlet"; parametertypes[i] = Thinlet.class; 6086 } 6087 else { 6088 int dot = arg.indexOf('.'); 6089 String compname = (dot == -1) ? arg : arg.substring(0, dot); 6090 Object comp = null; 6091 String classname = null; 6092 if ("item".equals(compname)) { 6093 comp = "item"; 6094 String parentclass = getClass(component); 6095 if ("list" == parentclass) { classname = "item"; } 6096 else if ("tree" == parentclass) { classname = "node"; } 6097 else if ("table" == parentclass) { classname = "row"; } 6098 else if ("combobox" == parentclass) { classname = "choice"; } 6099 else if ("tabbedpane" == parentclass) { classname = "tab"; } 6100 else throw new IllegalArgumentException (parentclass + " has no item"); 6101 } 6102 else { 6103 comp = ("this".equals(compname)) ? component : find(root, compname); 6104 classname = getClass(comp); 6105 } 6106 data[2 + 3 * i] = comp; if (dot == -1) { 6108 parametertypes[i] = Object .class; } 6110 else { 6111 Object [] definition = getDefinition(classname, arg.substring(dot + 1), null); 6112 data[2 + 3 * i + 1] = definition[1]; data[2 + 3 * i + 2] = definition[3]; Object fieldclass = definition[0]; 6115 if ((fieldclass == "string") || (fieldclass == "choice")) { 6116 parametertypes[i] = String .class; 6117 } 6118 else if (fieldclass == "boolean") { 6119 parametertypes[i] = Boolean.TYPE; 6120 } 6121 else if (fieldclass == "integer") { 6122 parametertypes[i] = Integer.TYPE; 6123 } 6124 else if (fieldclass == "icon") { 6125 parametertypes[i] = Image.class; 6126 } 6127 else throw new IllegalArgumentException ((String ) fieldclass); 6128 } 6129 } 6130 } 6131 data[0] = handler; 6132 try { 6133 data[1] = handler.getClass().getMethod(methodname, parametertypes); 6134 return data; 6135 } catch (Exception exc) { 6136 throw new IllegalArgumentException (value + " " + exc.getMessage()); 6137 } 6138 } 6139 6140 6143 private void update(Object component, Object mode) { 6144 if ("parent" == mode) { 6145 component = getParent(component); 6146 mode = "validate"; 6147 } 6148 boolean firstpaint = true; 6149 int x = 0; int y = 0; int width = 0; int height = 0; 6150 while (component != null) { 6151 if (!getBoolean(component, "visible", true)) { break; } 6152 if ("paint" == mode) { Rectangle bounds = getRectangle(component, "bounds"); 6154 if (bounds == null) { return; } 6155 if (firstpaint) { 6156 x = bounds.x; y = bounds.y; 6157 width = Math.abs(bounds.width); height = bounds.height; 6158 firstpaint = false; 6159 } else { 6160 x += bounds.x; y += bounds.y; 6161 } 6162 if (component == content) { 6163 repaint(x, y, width, height); 6164 } 6165 } 6166 Object parent = getParent(component); 6167 String classname = getClass(parent); 6168 if ("combobox" == classname) { 6169 parent = get(parent, ":combolist"); 6170 } 6171 else if ("menu" == classname) { 6172 parent = get(parent, ":popup"); 6173 } 6174 else if (("paint" == mode) && ("tabbedpane" == classname)) { 6175 if (getItem(parent, getInteger(parent, "selected", 0)) != component) { break; } 6176 } 6177 if (("layout" == mode) || (("validate" == mode) && 6178 (("list" == classname) || ("table" == classname) || 6179 ("tree" == classname) || ("dialog" == classname) || (parent == content)))) { 6180 Rectangle bounds = getRectangle(parent, "bounds"); 6181 if (bounds == null) { return; } 6182 bounds.width = -1 * Math.abs(bounds.width); 6183 mode = "paint"; 6184 } 6185 component = parent; 6186 } 6187 } 6188 6189 6191 6194 private boolean setString(Object component, 6195 String key, String value, String defaultvalue) { 6196 if (allI18n && (langResource != null) && 6197 ((key == "text") || (key == "tooltip"))) { 6198 putProperty(component, "i18n." + key, null); } 6200 return set(component, key, value); } 6202 6203 6206 private String getString(Object component, 6207 String key, String defaultvalue) { 6208 Object value = get(component, key); 6209 return (value == null) ? defaultvalue : 6210 getI18NString(component, key, (String ) value); 6211 } 6212 6213 6253 public void setLangResource(ResourceBundle res) { langResource = res; 6255 doLayout(content); 6256 repaint(content); 6257 } 6258 6259 6262 public static ResourceBundle getLangResource() { return langResource; 6264 } 6265 6266 6272 public void setLangResourceDefault(ResourceBundle res) { langResourceDefault = res; 6274 if (langResource == null) setLangResource(res); 6275 } 6276 6277 6280 public static ResourceBundle getLangResourceDefault() { return langResourceDefault; 6282 } 6283 6284 6293 public void setAllI18n(boolean val) { allI18n = val; 6295 } 6296 6297 6300 private String getI18NString(Object component, String key, String text) { if (allI18n && (langResource != null) && 6302 ((key == "text") || (key == "tooltip")) && 6303 getBoolean(component, "i18n", true)) { 6304 String ikey = (String ) getProperty(component, "i18n." + key); 6305 if (!"__NONE__".equals(ikey)) { 6306 if (ikey == null) { putProperty(component, "i18n." + key, ikey = text); 6308 } 6309 try { 6310 return langResource.getString(ikey); 6311 } catch (Exception exc) { if (langResourceDefault != null) { 6313 try { 6314 return langResourceDefault.getString(ikey); 6315 } catch (Exception dexc) { 6316 putProperty(component, "i18n." + key, "__NONE__"); 6317 } 6318 } 6319 } 6320 } 6321 } 6322 return text; 6323 } 6324 6325 6329 private boolean setChoice(Object component, 6330 String key, String value, String [] values, String defaultvalue) { 6331 if (value == null) { 6332 return set(component, key, defaultvalue); 6333 } 6334 for (int i = 0; i < values.length; i++) { 6335 if (value.equals(values[i])) { 6336 return set(component, key, values[i]); 6337 } 6338 } 6339 throw new IllegalArgumentException ("unknown " + value + " for " + key); 6340 } 6341 6342 6345 private Image getIcon(Object component, String key, Image defaultvalue) { 6346 Object value = get(component, key); 6347 return (value == null) ? defaultvalue : (Image) value; 6348 } 6349 6350 6353 private boolean setBoolean(Object component, 6354 String key, boolean value, boolean defaultvalue) { 6355 return set(component, key, (value == defaultvalue) ? null : 6356 (value ? Boolean.TRUE : Boolean.FALSE)); 6357 } 6358 6359 6362 private boolean getBoolean(Object component, 6363 String key, boolean defaultvalue) { 6364 Object value = get(component, key); 6365 return (value == null) ? defaultvalue : ((Boolean ) value).booleanValue(); 6366 } 6367 6368 6371 private boolean setInteger(Object component, 6372 String key, int value, int defaultvalue) { 6373 return set(component, key, (value == defaultvalue) ? null : new Integer (value)); 6374 } 6375 6376 6379 private int getInteger(Object component, String key, int defaultvalue) { 6380 Object value = get(component, key); 6381 return (value == null) ? defaultvalue : ((Integer ) value).intValue(); 6382 } 6383 6384 6387 private void setRectangle(Object component, 6388 String key, int x, int y, int width, int height) { 6389 Rectangle rectangle = getRectangle(component, key); 6390 if (rectangle != null) { 6391 rectangle.x = x; rectangle.y = y; 6392 rectangle.width = width; rectangle.height = height; 6393 } 6394 else { 6395 set(component, key, new Rectangle(x, y, width, height)); 6396 } 6397 } 6398 6399 6402 private Rectangle getRectangle(Object component, String key) { 6403 return (Rectangle) get(component, key); 6404 } 6405 6406 6408 6415 public Image getIcon(String path) { 6416 return getIcon(path, true); 6417 } 6418 6419 6429 public Image getIcon(String path, boolean preload) { 6430 if ((path == null) || (path.length() == 0)) { 6431 return null; 6432 } 6433 Image image = null; try { 6435 URL url = getClass().getResource(path); if (url != null) { image = Toolkit.getDefaultToolkit().getImage(url); 6438 } 6439 } catch (Throwable e) {} 6440 if (image == null) { 6441 try { 6442 InputStream is = getClass().getResourceAsStream(path); 6443 if (is != null) { 6445 byte[] data = new byte[is.available()]; 6446 is.read(data, 0, data.length); 6447 image = getToolkit().createImage(data); 6448 is.close(); 6449 } 6450 else { image = Toolkit.getDefaultToolkit().getImage(new URL(path)); 6452 } 6453 } catch (Throwable e) {} 6454 } 6455 if (preload && (image != null)) { 6456 MediaTracker mediatracker = new MediaTracker(this); 6457 mediatracker.addImage(image, 1); 6458 try { 6459 mediatracker.waitForID(1, 5000); 6460 } catch (InterruptedException ie) { } 6461 } 6463 return image; 6464 } 6465 6466 6472 public boolean destroy() { 6473 return true; 6474 } 6475 6476 private static Object [] dtd; 6477 static { 6478 Integer integer_1 = new Integer (-1); 6479 Integer integer0 = new Integer (0); 6480 Integer integer1 = new Integer (1); 6481 String [] orientation = { "horizontal", "vertical" }; 6482 String [] leftcenterright = { "left", "center", "right" }; 6483 String [] selections = { "single", "interval", "multiple" }; dtd = new Object [] { 6485 "component", null, new Object [][] { 6486 { "string", "name", null, null }, 6487 { "boolean", "enabled", "paint", Boolean.TRUE }, 6488 { "boolean", "visible", "parent", Boolean.TRUE }, 6489 { "boolean", "i18n", "validate", Boolean.FALSE }, { "string", "tooltip", null, null }, 6491 { "font", "font", "validate", null }, 6492 { "color", "foreground", "paint", null }, 6493 { "color", "background", "paint", null }, 6494 { "integer", "width", "validate", integer0 }, 6495 { "integer", "height", "validate", integer0 }, 6496 { "integer", "colspan", "validate", integer1 }, 6497 { "integer", "rowspan", "validate", integer1 }, 6498 { "integer", "weightx", "validate", integer0 }, 6499 { "integer", "weighty", "validate", integer0 }, 6500 { "choice", "halign", "validate", 6501 new String [] { "fill", "center", "left", "right" } }, 6502 { "choice", "valign", "validate", 6503 new String [] { "fill", "center", "top", "bottom" } }, 6504 { "property", "property", null, null }, 6508 { "method", "init" }, 6509 { "method", "focuslost" }, 6510 { "method", "focusgained" } }, 6511 "label", "component", new Object [][] { 6512 { "string", "text", "validate", null }, 6513 { "icon", "icon", "validate", null }, 6514 { "choice", "alignment", "validate", leftcenterright }, 6515 { "integer", "mnemonic", "paint", integer_1 }, 6516 { "component", "for", null, null } }, 6517 "button", "label", new Object [][] { 6518 { "choice", "alignment", "validate", new String [] { "center", "left", "right" } }, 6519 { "method", "action" }, 6520 { "choice", "type", "paint", new String [] { "normal", "default", "cancel", "link" } } }, 6521 "checkbox", "label", new Object [][] { 6522 { "boolean", "selected", "paint", Boolean.FALSE }, { "string", "group", "paint", null }, { "method", "action" } }, 6525 "togglebutton", "checkbox", null, 6526 "combobox", "textfield", new Object [][] { 6527 { "icon", "icon", "validate", null }, 6528 { "integer", "selected", "layout", integer_1 } }, 6529 "choice", null, new Object [][] { 6530 { "string", "name", null, null }, 6531 { "boolean", "enabled", "paint", Boolean.TRUE }, 6532 { "boolean", "i18n", "validate", Boolean.FALSE }, { "string", "text", "parent", null }, 6534 { "icon", "icon", "parent", null }, 6535 { "choice", "alignment", "parent", leftcenterright }, 6536 { "string", "tooltip", null, null }, 6537 { "font", "font", "validate", null }, 6538 { "color", "foreground", "paint", null }, 6539 { "color", "background", "paint", null }, 6540 { "property", "property", null, null } }, 6541 "textfield", "component", new Object [][] { 6542 { "string", "text", "layout", "" }, 6543 { "integer", "columns", "validate", integer0 }, 6544 { "boolean", "editable", "paint", Boolean.TRUE }, 6545 { "integer", "start", "layout", integer0 }, 6546 { "integer", "end", "layout", integer0 }, 6547 { "method", "action" }, 6548 { "method", "insert" }, 6549 { "method", "remove" }, 6550 { "method", "caret" }, 6551 { "method", "perform" } }, 6552 "passwordfield", "textfield", null, 6553 "textarea", "textfield", new Object [][] { 6554 { "integer", "rows", "validate", integer0 }, 6555 { "boolean", "border", "validate", Boolean.TRUE }, 6556 { "boolean", "wrap", "layout", Boolean.FALSE } }, 6557 "tabbedpane", "component", new Object [][] { 6558 { "choice", "placement", "validate", 6559 new String [] { "top", "left", "bottom", "right", "stacked" } }, 6560 { "integer", "selected", "paint", integer0 }, 6561 { "method", "action" } }, "tab", "choice", new Object [][] { 6563 { "integer", "mnemonic", "paint", integer_1 } }, 6564 "panel", "component", new Object [][] { 6565 { "integer", "columns", "validate", integer0 }, 6566 { "integer", "top", "validate", integer0 }, 6567 { "integer", "left", "validate", integer0 }, 6568 { "integer", "bottom", "validate", integer0 }, 6569 { "integer", "right", "validate", integer0 }, 6570 { "integer", "gap", "validate", integer0 }, 6571 { "string", "text", "validate", null }, 6572 { "icon", "icon", "validate", null }, 6573 { "boolean", "border", "validate", Boolean.FALSE }, 6574 { "boolean", "scrollable", "validate", Boolean.FALSE } }, 6575 "desktop", "component", null, 6576 "dialog", "panel", new Object [][] { 6577 { "boolean", "modal", null, Boolean.FALSE }, 6578 { "boolean", "resizable", null, Boolean.FALSE }, 6579 { "boolean", "closable", "paint", Boolean.FALSE }, 6580 { "boolean", "maximizable", "paint", Boolean.FALSE }, 6581 { "boolean", "iconifiable", "paint", Boolean.FALSE } }, 6582 "spinbox", "textfield", new Object [][] { 6583 { "integer", "minimum", null, new Integer (Integer.MIN_VALUE) }, 6584 { "integer", "maximum", null, new Integer (Integer.MAX_VALUE) }, 6585 { "integer", "step", null, integer1 }, 6586 { "integer", "value", null, integer0 } }, "progressbar", "component", new Object [][] { 6588 { "choice", "orientation", "validate", orientation }, 6589 { "integer", "minimum", "paint", integer0 }, { "integer", "maximum", "paint", new Integer (100) }, 6591 { "integer", "value", "paint", integer0 } }, 6592 "slider", "progressbar", new Object [][] { 6594 { "integer", "unit", null, new Integer (5) }, 6595 { "integer", "block", null, new Integer (25) }, 6596 { "method", "action" } }, 6597 "splitpane", "component", new Object [][] { 6601 { "choice", "orientation", "validate", orientation }, 6602 { "integer", "divider", "layout", integer_1 } }, 6603 "list", "component", new Object [][] { 6604 { "choice", "selection", "paint", selections }, 6605 { "method", "action" }, 6606 { "method", "perform" }, 6607 { "boolean", "line", "validate", Boolean.TRUE } }, 6608 "item", "choice", new Object [][] { 6609 { "boolean", "selected", null, Boolean.FALSE } }, 6610 "table", "list", new Object [][] { 6611 }, 6615 "header", null, null, 6616 "column", "choice", new Object [][] { 6622 { "integer", "width", null, new Integer (80) }, 6623 { "choice", "sort", null, new String [] { "none", "ascent", "descent" } } }, 6624 "row", null, new Object [][] { 6625 { "boolean", "selected", null, Boolean.FALSE } }, 6626 "cell", "choice", null, 6627 "tree", "list", new Object [][] { 6628 { "boolean", "angle", null, Boolean.FALSE }, 6629 { "method", "expand" }, 6630 { "method", "collapse" } }, 6631 "node", "choice", new Object [][] { 6632 { "boolean", "selected", null, Boolean.FALSE }, 6633 { "boolean", "expanded", null, Boolean.TRUE } }, 6634 "separator", "component", null, 6635 "menubar", "component", new Object [][] { 6636 { "choice", "placement", "validate", new String [] { "top", "bottom" } } }, 6637 "menu", "choice", new Object [][] { 6638 { "integer", "mnemonic", "paint", integer_1 } }, 6639 "menuitem", "choice", new Object [][] { 6640 { "keystroke", "accelerator", null, null }, 6641 { "method", "action" }, 6642 { "integer", "mnemonic", "paint", integer_1 } }, 6643 "checkboxmenuitem", "menuitem", new Object [][] { 6644 { "boolean", "selected", "paint", Boolean.FALSE }, { "string", "group", "paint", null } }, "popupmenu", "component", new Object [][] { 6647 { "method", "menushown" } }, "bean", "component", new Object [][] { 6649 { "bean", "bean", null, null } } 6650 }; 6651 } 6652} | Popular Tags |