1 /* MultiTextUI.java -- 2 Copyright (C) 2005 Free Software Foundation, Inc. 3 4 This file is part of GNU Classpath. 5 6 GNU Classpath is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2, or (at your option) 9 any later version. 10 11 GNU Classpath is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GNU Classpath; see the file COPYING. If not, write to the 18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19 02110-1301 USA. 20 21 Linking this library statically or dynamically with other modules is 22 making a combined work based on this library. Thus, the terms and 23 conditions of the GNU General Public License cover the whole 24 combination. 25 26 As a special exception, the copyright holders of this library give you 27 permission to link this library with independent modules to produce an 28 executable, regardless of the license terms of these independent 29 modules, and to copy and distribute the resulting executable under 30 terms of your choice, provided that you also meet, for each linked 31 independent module, the terms and conditions of the license of that 32 module. An independent module is a module which is not derived from 33 or based on this library. If you modify this library, you may extend 34 this exception to your version of the library, but you are not 35 obligated to do so. If you do not wish to do so, delete this 36 exception statement from your version. */ 37 38 package javax.swing.plaf.multi; 39 40 import java.awt.Dimension; 41 import java.awt.Graphics; 42 import java.awt.Point; 43 import java.awt.Rectangle; 44 import java.util.Iterator; 45 import java.util.Vector; 46 47 import javax.accessibility.Accessible; 48 import javax.swing.JComponent; 49 import javax.swing.LookAndFeel; 50 import javax.swing.UIManager; 51 import javax.swing.plaf.ComponentUI; 52 import javax.swing.plaf.TextUI; 53 import javax.swing.text.BadLocationException; 54 import javax.swing.text.EditorKit; 55 import javax.swing.text.JTextComponent; 56 import javax.swing.text.Position; 57 import javax.swing.text.View; 58 import javax.swing.text.Position.Bias; 59 60 /** 61 * A UI delegate that that coordinates multiple {@link TextUI} 62 * instances, one from the primary look and feel, and one or more from the 63 * auxiliary look and feel(s). 64 * 65 * @see UIManager#addAuxiliaryLookAndFeel(LookAndFeel) 66 */ 67 public class MultiTextUI extends TextUI 68 { 69 70 /** A list of references to the actual component UIs. */ 71 protected Vector uis; 72 73 /** 74 * Creates a new <code>MultiTextUI</code> instance. 75 * 76 * @see #createUI(JComponent) 77 */ MultiTextUI()78 public MultiTextUI() 79 { 80 uis = new Vector(); 81 } 82 83 /** 84 * Creates a delegate object for the specified component. If any auxiliary 85 * look and feels support this component, a <code>MultiTextUI</code> is 86 * returned, otherwise the UI from the default look and feel is returned. 87 * 88 * @param target the component. 89 * 90 * @see MultiLookAndFeel#createUIs(ComponentUI, Vector, JComponent) 91 */ createUI(JComponent target)92 public static ComponentUI createUI(JComponent target) 93 { 94 MultiTextUI mui = new MultiTextUI(); 95 return MultiLookAndFeel.createUIs(mui, mui.uis, target); 96 } 97 98 /** 99 * Calls the {@link ComponentUI#installUI(JComponent)} method for all 100 * the UI delegates managed by this <code>MultiTextUI</code>. 101 * 102 * @param c the component. 103 */ installUI(JComponent c)104 public void installUI(JComponent c) 105 { 106 Iterator iterator = uis.iterator(); 107 while (iterator.hasNext()) 108 { 109 ComponentUI ui = (ComponentUI) iterator.next(); 110 ui.installUI(c); 111 } 112 } 113 114 /** 115 * Calls the {@link ComponentUI#uninstallUI(JComponent)} method for all 116 * the UI delegates managed by this <code>MultiTextUI</code>. 117 * 118 * @param c the component. 119 */ uninstallUI(JComponent c)120 public void uninstallUI(JComponent c) 121 { 122 Iterator iterator = uis.iterator(); 123 while (iterator.hasNext()) 124 { 125 ComponentUI ui = (ComponentUI) iterator.next(); 126 ui.uninstallUI(c); 127 } 128 } 129 130 /** 131 * Returns an array containing the UI delegates managed by this 132 * <code>MultiTextUI</code>. The first item in the array is always 133 * the UI delegate from the installed default look and feel. 134 * 135 * @return An array of UI delegates. 136 */ getUIs()137 public ComponentUI[] getUIs() 138 { 139 return MultiLookAndFeel.uisToArray(uis); 140 } 141 142 /** 143 * Calls the {@link ComponentUI#contains(JComponent, int, int)} method for all 144 * the UI delegates managed by this <code>MultiTextUI</code>, 145 * returning the result for the UI delegate from the primary look and 146 * feel. 147 * 148 * @param c the component. 149 * @param x the x-coordinate. 150 * @param y the y-coordinate. 151 * 152 * @return <code>true</code> if the specified (x, y) coordinate falls within 153 * the bounds of the component as rendered by the UI delegate in the 154 * primary look and feel, and <code>false</code> otherwise. 155 */ contains(JComponent c, int x, int y)156 public boolean contains(JComponent c, int x, int y) 157 { 158 boolean result = false; 159 Iterator iterator = uis.iterator(); 160 // first UI delegate provides the return value 161 if (iterator.hasNext()) 162 { 163 ComponentUI ui = (ComponentUI) iterator.next(); 164 result = ui.contains(c, x, y); 165 } 166 // return values from auxiliary UI delegates are ignored 167 while (iterator.hasNext()) 168 { 169 ComponentUI ui = (ComponentUI) iterator.next(); 170 /* boolean ignored = */ ui.contains(c, x, y); 171 } 172 return result; 173 } 174 175 /** 176 * Calls the {@link ComponentUI#update(Graphics, JComponent)} method for all 177 * the UI delegates managed by this <code>MultiTextUI</code>. 178 * 179 * @param g the graphics device. 180 * @param c the component. 181 */ update(Graphics g, JComponent c)182 public void update(Graphics g, JComponent c) 183 { 184 Iterator iterator = uis.iterator(); 185 while (iterator.hasNext()) 186 { 187 ComponentUI ui = (ComponentUI) iterator.next(); 188 ui.update(g, c); 189 } 190 } 191 192 /** 193 * Calls the <code>paint(Graphics, JComponent)</code> method for all the UI 194 * delegates managed by this <code>MultiTextUI</code>. 195 * 196 * @param g the graphics device. 197 * @param c the component. 198 */ paint(Graphics g, JComponent c)199 public void paint(Graphics g, JComponent c) 200 { 201 Iterator iterator = uis.iterator(); 202 while (iterator.hasNext()) 203 { 204 ComponentUI ui = (ComponentUI) iterator.next(); 205 ui.paint(g, c); 206 } 207 } 208 209 /** 210 * Calls the {@link ComponentUI#getPreferredSize(JComponent)} method for all 211 * the UI delegates managed by this <code>MultiTextUI</code>, 212 * returning the preferred size for the UI delegate from the primary look and 213 * feel. 214 * 215 * @param c the component. 216 * 217 * @return The preferred size returned by the UI delegate from the primary 218 * look and feel. 219 */ getPreferredSize(JComponent c)220 public Dimension getPreferredSize(JComponent c) 221 { 222 Dimension result = null; 223 Iterator iterator = uis.iterator(); 224 // first UI delegate provides the return value 225 if (iterator.hasNext()) 226 { 227 ComponentUI ui = (ComponentUI) iterator.next(); 228 result = ui.getPreferredSize(c); 229 } 230 // return values from auxiliary UI delegates are ignored 231 while (iterator.hasNext()) 232 { 233 ComponentUI ui = (ComponentUI) iterator.next(); 234 /* Dimension ignored = */ ui.getPreferredSize(c); 235 } 236 return result; 237 } 238 239 /** 240 * Calls the {@link ComponentUI#getMinimumSize(JComponent)} method for all 241 * the UI delegates managed by this <code>MultiTextUI</code>, 242 * returning the minimum size for the UI delegate from the primary look and 243 * feel. 244 * 245 * @param c the component. 246 * 247 * @return The minimum size returned by the UI delegate from the primary 248 * look and feel. 249 */ getMinimumSize(JComponent c)250 public Dimension getMinimumSize(JComponent c) 251 { 252 Dimension result = null; 253 Iterator iterator = uis.iterator(); 254 // first UI delegate provides the return value 255 if (iterator.hasNext()) 256 { 257 ComponentUI ui = (ComponentUI) iterator.next(); 258 result = ui.getMinimumSize(c); 259 } 260 // return values from auxiliary UI delegates are ignored 261 while (iterator.hasNext()) 262 { 263 ComponentUI ui = (ComponentUI) iterator.next(); 264 /* Dimension ignored = */ ui.getMinimumSize(c); 265 } 266 return result; 267 } 268 269 /** 270 * Calls the {@link ComponentUI#getMaximumSize(JComponent)} method for all 271 * the UI delegates managed by this <code>MultiTextUI</code>, 272 * returning the maximum size for the UI delegate from the primary look and 273 * feel. 274 * 275 * @param c the component. 276 * 277 * @return The maximum size returned by the UI delegate from the primary 278 * look and feel. 279 */ getMaximumSize(JComponent c)280 public Dimension getMaximumSize(JComponent c) 281 { 282 Dimension result = null; 283 Iterator iterator = uis.iterator(); 284 // first UI delegate provides the return value 285 if (iterator.hasNext()) 286 { 287 ComponentUI ui = (ComponentUI) iterator.next(); 288 result = ui.getMaximumSize(c); 289 } 290 // return values from auxiliary UI delegates are ignored 291 while (iterator.hasNext()) 292 { 293 ComponentUI ui = (ComponentUI) iterator.next(); 294 /* Dimension ignored = */ ui.getMaximumSize(c); 295 } 296 return result; 297 } 298 299 /** 300 * Calls the {@link ComponentUI#getAccessibleChildrenCount(JComponent)} method 301 * for all the UI delegates managed by this <code>MultiTextUI</code>, 302 * returning the count for the UI delegate from the primary look and 303 * feel. 304 * 305 * @param c the component. 306 * 307 * @return The count returned by the UI delegate from the primary 308 * look and feel. 309 */ getAccessibleChildrenCount(JComponent c)310 public int getAccessibleChildrenCount(JComponent c) 311 { 312 int result = 0; 313 Iterator iterator = uis.iterator(); 314 // first UI delegate provides the return value 315 if (iterator.hasNext()) 316 { 317 ComponentUI ui = (ComponentUI) iterator.next(); 318 result = ui.getAccessibleChildrenCount(c); 319 } 320 // return values from auxiliary UI delegates are ignored 321 while (iterator.hasNext()) 322 { 323 ComponentUI ui = (ComponentUI) iterator.next(); 324 /* int ignored = */ ui.getAccessibleChildrenCount(c); 325 } 326 return result; 327 } 328 329 /** 330 * Calls the {@link ComponentUI#getAccessibleChild(JComponent, int)} method 331 * for all the UI delegates managed by this <code>MultiTextUI</code>, 332 * returning the child for the UI delegate from the primary look and 333 * feel. 334 * 335 * @param c the component 336 * @param i the child index. 337 * 338 * @return The child returned by the UI delegate from the primary 339 * look and feel. 340 */ getAccessibleChild(JComponent c, int i)341 public Accessible getAccessibleChild(JComponent c, int i) 342 { 343 Accessible result = null; 344 Iterator iterator = uis.iterator(); 345 // first UI delegate provides the return value 346 if (iterator.hasNext()) 347 { 348 ComponentUI ui = (ComponentUI) iterator.next(); 349 result = ui.getAccessibleChild(c, i); 350 } 351 // return values from auxiliary UI delegates are ignored 352 while (iterator.hasNext()) 353 { 354 ComponentUI ui = (ComponentUI) iterator.next(); 355 /* Accessible ignored = */ ui.getAccessibleChild(c, i); 356 } 357 return result; 358 } 359 360 /** 361 * Calls the {@link TextUI#modelToView(JTextComponent, int)} method for all 362 * the UI delegates managed by this <code>MultiTextUI</code>, 363 * returning the bounds for the UI delegate from the primary look and 364 * feel. 365 * 366 * @param tc the text component. 367 * 368 * @return The bounds returned by the UI delegate from the primary 369 * look and feel. 370 */ modelToView(JTextComponent tc, int pos)371 public Rectangle modelToView(JTextComponent tc, int pos) 372 throws BadLocationException 373 { 374 Rectangle result = null; 375 Iterator iterator = uis.iterator(); 376 // first UI delegate provides the return value 377 if (iterator.hasNext()) 378 { 379 TextUI ui = (TextUI) iterator.next(); 380 result = ui.modelToView(tc, pos); 381 } 382 // return values from auxiliary UI delegates are ignored 383 while (iterator.hasNext()) 384 { 385 TextUI ui = (TextUI) iterator.next(); 386 /* Rectangle ignored = */ ui.modelToView(tc, pos); 387 } 388 return result; 389 } 390 391 /** 392 * Calls the {@link TextUI#modelToView(JTextComponent, int, Position.Bias)} 393 * method for all the UI delegates managed by this <code>MultiTextUI</code>, 394 * returning the bounds for the UI delegate from the primary look and 395 * feel. 396 * 397 * @param tc the text component. 398 * 399 * @return The bounds returned by the UI delegate from the primary 400 * look and feel. 401 */ modelToView(JTextComponent tc, int pos, Bias bias)402 public Rectangle modelToView(JTextComponent tc, int pos, Bias bias) 403 throws BadLocationException 404 { 405 Rectangle result = null; 406 Iterator iterator = uis.iterator(); 407 // first UI delegate provides the return value 408 if (iterator.hasNext()) 409 { 410 TextUI ui = (TextUI) iterator.next(); 411 result = ui.modelToView(tc, pos, bias); 412 } 413 // return values from auxiliary UI delegates are ignored 414 while (iterator.hasNext()) 415 { 416 TextUI ui = (TextUI) iterator.next(); 417 /* Rectangle ignored = */ ui.modelToView(tc, pos, bias); 418 } 419 return result; 420 } 421 422 /** 423 * Calls the {@link TextUI#viewToModel(JTextComponent, Point)} method for all 424 * the UI delegates managed by this <code>MultiTextUI</code>, 425 * returning the position for the UI delegate from the primary look and 426 * feel. 427 * 428 * @param t the text component. 429 * @param pt the point. 430 * 431 * @return The position returned by the UI delegate from the primary 432 * look and feel. 433 */ viewToModel(JTextComponent t, Point pt)434 public int viewToModel(JTextComponent t, Point pt) 435 { 436 int result = 0; 437 Iterator iterator = uis.iterator(); 438 // first UI delegate provides the return value 439 if (iterator.hasNext()) 440 { 441 TextUI ui = (TextUI) iterator.next(); 442 result = ui.viewToModel(t, pt); 443 } 444 // return values from auxiliary UI delegates are ignored 445 while (iterator.hasNext()) 446 { 447 TextUI ui = (TextUI) iterator.next(); 448 /* int ignored = */ ui.viewToModel(t, pt); 449 } 450 return result; 451 } 452 453 /** 454 * Calls the {@link TextUI#viewToModel(JTextComponent, Point, Bias[])} method 455 * for all the UI delegates managed by this <code>MultiTextUI</code>, 456 * returning the position for the UI delegate from the primary look and 457 * feel. 458 * 459 * @param tc the text component. 460 * 461 * @return The position returned by the UI delegate from the primary 462 * look and feel. 463 */ viewToModel(JTextComponent tc, Point loc, Bias[] outBias)464 public int viewToModel(JTextComponent tc, Point loc, Bias[] outBias) 465 { 466 int result = 0; 467 Iterator iterator = uis.iterator(); 468 // first UI delegate provides the return value 469 if (iterator.hasNext()) 470 { 471 TextUI ui = (TextUI) iterator.next(); 472 result = ui.viewToModel(tc, loc, outBias); 473 } 474 // return values from auxiliary UI delegates are ignored 475 while (iterator.hasNext()) 476 { 477 TextUI ui = (TextUI) iterator.next(); 478 /* int ignored = */ ui.viewToModel(tc, loc, outBias); 479 } 480 return result; 481 } 482 483 /** 484 * Calls the {@link TextUI#getNextVisualPositionFrom(JTextComponent, int, 485 * Position.Bias, int, Position.Bias[])} method for all 486 * the UI delegates managed by this <code>MultiTextUI</code>, 487 * returning the position for the UI delegate from the primary look and 488 * feel. 489 * 490 * @param tc the text component. 491 * 492 * @return The position returned by the UI delegate from the primary 493 * look and feel. 494 */ getNextVisualPositionFrom(JTextComponent tc, int pos, Bias bias, int direction, Bias[] outBias)495 public int getNextVisualPositionFrom(JTextComponent tc, int pos, Bias bias, 496 int direction, Bias[] outBias) throws BadLocationException 497 { 498 int result = 0; 499 Iterator iterator = uis.iterator(); 500 // first UI delegate provides the return value 501 if (iterator.hasNext()) 502 { 503 TextUI ui = (TextUI) iterator.next(); 504 result = ui.getNextVisualPositionFrom(tc, pos, bias, direction, 505 outBias); 506 } 507 // return values from auxiliary UI delegates are ignored 508 while (iterator.hasNext()) 509 { 510 TextUI ui = (TextUI) iterator.next(); 511 /* int ignored = */ ui.getNextVisualPositionFrom(tc, pos, bias, 512 direction, outBias); 513 } 514 return result; 515 } 516 517 /** 518 * Calls the {@link TextUI#damageRange(JTextComponent, int, int)} method for 519 * all the UI delegates managed by this <code>MultiTextUI</code>. 520 * 521 * @param tc the component. 522 * @param start the start position. 523 * @param end the end position. 524 */ damageRange(JTextComponent tc, int start, int end)525 public void damageRange(JTextComponent tc, int start, int end) 526 { 527 Iterator iterator = uis.iterator(); 528 while (iterator.hasNext()) 529 { 530 TextUI ui = (TextUI) iterator.next(); 531 ui.damageRange(tc, start, end); 532 } 533 } 534 535 /** 536 * Calls the {@link TextUI#damageRange(JTextComponent, int, int, 537 * Position.Bias, Position.Bias)} method for all the UI delegates managed by 538 * this <code>MultiTextUI</code>. 539 * 540 * @param tc the component. 541 * @param start the start position. 542 * @param end the end position. 543 * @param startBias the start bias. 544 * @param endBias the end bias. 545 */ damageRange(JTextComponent tc, int start, int end, Bias startBias, Bias endBias)546 public void damageRange(JTextComponent tc, int start, int end, 547 Bias startBias, Bias endBias) 548 { 549 Iterator iterator = uis.iterator(); 550 while (iterator.hasNext()) 551 { 552 TextUI ui = (TextUI) iterator.next(); 553 ui.damageRange(tc, start, end, startBias, endBias); 554 } 555 } 556 557 /** 558 * Calls the {@link TextUI#getEditorKit(JTextComponent)} method for all 559 * the UI delegates managed by this <code>MultiTextUI</code>, 560 * returning the editor kit for the UI delegate from the primary look and 561 * feel. 562 * 563 * @param tc the text component. 564 * 565 * @return The editor kit returned by the UI delegate from the primary 566 * look and feel. 567 */ getEditorKit(JTextComponent tc)568 public EditorKit getEditorKit(JTextComponent tc) 569 { 570 EditorKit result = null; 571 Iterator iterator = uis.iterator(); 572 // first UI delegate provides the return value 573 if (iterator.hasNext()) 574 { 575 TextUI ui = (TextUI) iterator.next(); 576 result = ui.getEditorKit(tc); 577 } 578 // return values from auxiliary UI delegates are ignored 579 while (iterator.hasNext()) 580 { 581 TextUI ui = (TextUI) iterator.next(); 582 /* EditorKit ignored = */ ui.getEditorKit(tc); 583 } 584 return result; 585 } 586 587 /** 588 * Calls the {@link TextUI#getRootView(JTextComponent)} method for all 589 * the UI delegates managed by this <code>MultiTextUI</code>, 590 * returning the view for the UI delegate from the primary look and 591 * feel. 592 * 593 * @param tc the text component. 594 * 595 * @return The view returned by the UI delegate from the primary 596 * look and feel. 597 */ getRootView(JTextComponent tc)598 public View getRootView(JTextComponent tc) 599 { 600 View result = null; 601 Iterator iterator = uis.iterator(); 602 // first UI delegate provides the return value 603 if (iterator.hasNext()) 604 { 605 TextUI ui = (TextUI) iterator.next(); 606 result = ui.getRootView(tc); 607 } 608 // return values from auxiliary UI delegates are ignored 609 while (iterator.hasNext()) 610 { 611 TextUI ui = (TextUI) iterator.next(); 612 /* View ignored = */ ui.getRootView(tc); 613 } 614 return result; 615 } 616 617 } 618