001 /* MultiTreeUI.java -- 002 Copyright (C) 2005 Free Software Foundation, Inc. 003 004 This file is part of GNU Classpath. 005 006 GNU Classpath is free software; you can redistribute it and/or modify 007 it under the terms of the GNU General Public License as published by 008 the Free Software Foundation; either version 2, or (at your option) 009 any later version. 010 011 GNU Classpath is distributed in the hope that it will be useful, but 012 WITHOUT ANY WARRANTY; without even the implied warranty of 013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 General Public License for more details. 015 016 You should have received a copy of the GNU General Public License 017 along with GNU Classpath; see the file COPYING. If not, write to the 018 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 019 02110-1301 USA. 020 021 Linking this library statically or dynamically with other modules is 022 making a combined work based on this library. Thus, the terms and 023 conditions of the GNU General Public License cover the whole 024 combination. 025 026 As a special exception, the copyright holders of this library give you 027 permission to link this library with independent modules to produce an 028 executable, regardless of the license terms of these independent 029 modules, and to copy and distribute the resulting executable under 030 terms of your choice, provided that you also meet, for each linked 031 independent module, the terms and conditions of the license of that 032 module. An independent module is a module which is not derived from 033 or based on this library. If you modify this library, you may extend 034 this exception to your version of the library, but you are not 035 obligated to do so. If you do not wish to do so, delete this 036 exception statement from your version. */ 037 038 package javax.swing.plaf.multi; 039 040 import java.awt.Dimension; 041 import java.awt.Graphics; 042 import java.awt.Rectangle; 043 import java.util.Iterator; 044 import java.util.Vector; 045 046 import javax.accessibility.Accessible; 047 import javax.swing.JComponent; 048 import javax.swing.JTree; 049 import javax.swing.LookAndFeel; 050 import javax.swing.UIManager; 051 import javax.swing.plaf.ComponentUI; 052 import javax.swing.plaf.TreeUI; 053 import javax.swing.tree.TreePath; 054 055 /** 056 * A UI delegate that that coordinates multiple {@link TreeUI} 057 * instances, one from the primary look and feel, and one or more from the 058 * auxiliary look and feel(s). 059 * 060 * @see UIManager#addAuxiliaryLookAndFeel(LookAndFeel) 061 */ 062 public class MultiTreeUI extends TreeUI 063 { 064 065 /** A list of references to the actual component UIs. */ 066 protected Vector uis; 067 068 /** 069 * Creates a new <code>MultiTreeUI</code> instance. 070 * 071 * @see #createUI(JComponent) 072 */ 073 public MultiTreeUI() 074 { 075 uis = new Vector(); 076 } 077 078 /** 079 * Creates a delegate object for the specified component. If any auxiliary 080 * look and feels support this component, a <code>MultiTreeUI</code> is 081 * returned, otherwise the UI from the default look and feel is returned. 082 * 083 * @param target the component. 084 * 085 * @see MultiLookAndFeel#createUIs(ComponentUI, Vector, JComponent) 086 */ 087 public static ComponentUI createUI(JComponent target) 088 { 089 MultiTreeUI mui = new MultiTreeUI(); 090 return MultiLookAndFeel.createUIs(mui, mui.uis, target); 091 } 092 093 /** 094 * Calls the {@link ComponentUI#installUI(JComponent)} method for all 095 * the UI delegates managed by this <code>MultiTreeUI</code>. 096 * 097 * @param c the component. 098 */ 099 public void installUI(JComponent c) 100 { 101 Iterator iterator = uis.iterator(); 102 while (iterator.hasNext()) 103 { 104 ComponentUI ui = (ComponentUI) iterator.next(); 105 ui.installUI(c); 106 } 107 } 108 109 /** 110 * Calls the {@link ComponentUI#uninstallUI(JComponent)} method for all 111 * the UI delegates managed by this <code>MultiTreeUI</code>. 112 * 113 * @param c the component. 114 */ 115 public void uninstallUI(JComponent c) 116 { 117 Iterator iterator = uis.iterator(); 118 while (iterator.hasNext()) 119 { 120 ComponentUI ui = (ComponentUI) iterator.next(); 121 ui.uninstallUI(c); 122 } 123 } 124 125 /** 126 * Returns an array containing the UI delegates managed by this 127 * <code>MultiTreeUI</code>. The first item in the array is always 128 * the UI delegate from the installed default look and feel. 129 * 130 * @return An array of UI delegates. 131 */ 132 public ComponentUI[] getUIs() 133 { 134 return MultiLookAndFeel.uisToArray(uis); 135 } 136 137 /** 138 * Calls the {@link ComponentUI#contains(JComponent, int, int)} method for all 139 * the UI delegates managed by this <code>MultiTreeUI</code>, 140 * returning the result for the UI delegate from the primary look and 141 * feel. 142 * 143 * @param c the component. 144 * @param x the x-coordinate. 145 * @param y the y-coordinate. 146 * 147 * @return <code>true</code> if the specified (x, y) coordinate falls within 148 * the bounds of the component as rendered by the UI delegate in the 149 * primary look and feel, and <code>false</code> otherwise. 150 */ 151 public boolean contains(JComponent c, int x, int y) 152 { 153 boolean result = false; 154 Iterator iterator = uis.iterator(); 155 // first UI delegate provides the return value 156 if (iterator.hasNext()) 157 { 158 ComponentUI ui = (ComponentUI) iterator.next(); 159 result = ui.contains(c, x, y); 160 } 161 // return values from auxiliary UI delegates are ignored 162 while (iterator.hasNext()) 163 { 164 ComponentUI ui = (ComponentUI) iterator.next(); 165 /* boolean ignored = */ ui.contains(c, x, y); 166 } 167 return result; 168 } 169 170 /** 171 * Calls the {@link ComponentUI#update(Graphics, JComponent)} method for all 172 * the UI delegates managed by this <code>MultiTreeUI</code>. 173 * 174 * @param g the graphics device. 175 * @param c the component. 176 */ 177 public void update(Graphics g, JComponent c) 178 { 179 Iterator iterator = uis.iterator(); 180 while (iterator.hasNext()) 181 { 182 ComponentUI ui = (ComponentUI) iterator.next(); 183 ui.update(g, c); 184 } 185 } 186 187 /** 188 * Calls the <code>paint(Graphics, JComponent)</code> method for all the UI 189 * delegates managed by this <code>MultiTreeUI</code>. 190 * 191 * @param g the graphics device. 192 * @param c the component. 193 */ 194 public void paint(Graphics g, JComponent c) 195 { 196 Iterator iterator = uis.iterator(); 197 while (iterator.hasNext()) 198 { 199 ComponentUI ui = (ComponentUI) iterator.next(); 200 ui.paint(g, c); 201 } 202 } 203 204 /** 205 * Calls the {@link ComponentUI#getPreferredSize(JComponent)} method for all 206 * the UI delegates managed by this <code>MultiTreeUI</code>, 207 * returning the preferred size for the UI delegate from the primary look and 208 * feel. 209 * 210 * @param c the component. 211 * 212 * @return The preferred size returned by the UI delegate from the primary 213 * look and feel. 214 */ 215 public Dimension getPreferredSize(JComponent c) 216 { 217 Dimension result = null; 218 Iterator iterator = uis.iterator(); 219 // first UI delegate provides the return value 220 if (iterator.hasNext()) 221 { 222 ComponentUI ui = (ComponentUI) iterator.next(); 223 result = ui.getPreferredSize(c); 224 } 225 // return values from auxiliary UI delegates are ignored 226 while (iterator.hasNext()) 227 { 228 ComponentUI ui = (ComponentUI) iterator.next(); 229 /* Dimension ignored = */ ui.getPreferredSize(c); 230 } 231 return result; 232 } 233 234 /** 235 * Calls the {@link ComponentUI#getMinimumSize(JComponent)} method for all 236 * the UI delegates managed by this <code>MultiTreeUI</code>, 237 * returning the minimum size for the UI delegate from the primary look and 238 * feel. 239 * 240 * @param c the component. 241 * 242 * @return The minimum size returned by the UI delegate from the primary 243 * look and feel. 244 */ 245 public Dimension getMinimumSize(JComponent c) 246 { 247 Dimension result = null; 248 Iterator iterator = uis.iterator(); 249 // first UI delegate provides the return value 250 if (iterator.hasNext()) 251 { 252 ComponentUI ui = (ComponentUI) iterator.next(); 253 result = ui.getMinimumSize(c); 254 } 255 // return values from auxiliary UI delegates are ignored 256 while (iterator.hasNext()) 257 { 258 ComponentUI ui = (ComponentUI) iterator.next(); 259 /* Dimension ignored = */ ui.getMinimumSize(c); 260 } 261 return result; 262 } 263 264 /** 265 * Calls the {@link ComponentUI#getMaximumSize(JComponent)} method for all 266 * the UI delegates managed by this <code>MultiTreeUI</code>, 267 * returning the maximum size for the UI delegate from the primary look and 268 * feel. 269 * 270 * @param c the component. 271 * 272 * @return The maximum size returned by the UI delegate from the primary 273 * look and feel. 274 */ 275 public Dimension getMaximumSize(JComponent c) 276 { 277 Dimension result = null; 278 Iterator iterator = uis.iterator(); 279 // first UI delegate provides the return value 280 if (iterator.hasNext()) 281 { 282 ComponentUI ui = (ComponentUI) iterator.next(); 283 result = ui.getMaximumSize(c); 284 } 285 // return values from auxiliary UI delegates are ignored 286 while (iterator.hasNext()) 287 { 288 ComponentUI ui = (ComponentUI) iterator.next(); 289 /* Dimension ignored = */ ui.getMaximumSize(c); 290 } 291 return result; 292 } 293 294 /** 295 * Calls the {@link ComponentUI#getAccessibleChildrenCount(JComponent)} method 296 * for all the UI delegates managed by this <code>MultiTreeUI</code>, 297 * returning the count for the UI delegate from the primary look and 298 * feel. 299 * 300 * @param c the component. 301 * 302 * @return The count returned by the UI delegate from the primary 303 * look and feel. 304 */ 305 public int getAccessibleChildrenCount(JComponent c) 306 { 307 int result = 0; 308 Iterator iterator = uis.iterator(); 309 // first UI delegate provides the return value 310 if (iterator.hasNext()) 311 { 312 ComponentUI ui = (ComponentUI) iterator.next(); 313 result = ui.getAccessibleChildrenCount(c); 314 } 315 // return values from auxiliary UI delegates are ignored 316 while (iterator.hasNext()) 317 { 318 ComponentUI ui = (ComponentUI) iterator.next(); 319 /* int ignored = */ ui.getAccessibleChildrenCount(c); 320 } 321 return result; 322 } 323 324 /** 325 * Calls the {@link ComponentUI#getAccessibleChild(JComponent, int)} method 326 * for all the UI delegates managed by this <code>MultiTreeUI</code>, 327 * returning the child for the UI delegate from the primary look and 328 * feel. 329 * 330 * @param c the component 331 * @param i the child index. 332 * 333 * @return The child returned by the UI delegate from the primary 334 * look and feel. 335 */ 336 public Accessible getAccessibleChild(JComponent c, int i) 337 { 338 Accessible result = null; 339 Iterator iterator = uis.iterator(); 340 // first UI delegate provides the return value 341 if (iterator.hasNext()) 342 { 343 ComponentUI ui = (ComponentUI) iterator.next(); 344 result = ui.getAccessibleChild(c, i); 345 } 346 // return values from auxiliary UI delegates are ignored 347 while (iterator.hasNext()) 348 { 349 ComponentUI ui = (ComponentUI) iterator.next(); 350 /* Accessible ignored = */ ui.getAccessibleChild(c, i); 351 } 352 return result; 353 } 354 355 /** 356 * Calls the {@link TreeUI#getPathBounds(JTree, TreePath)} method 357 * for all the UI delegates managed by this <code>MultiTreeUI</code>, 358 * returning the bounds for the UI delegate from the primary look and 359 * feel. 360 * 361 * @param tree the tree component. 362 * 363 * @return The bounds returned by the UI delegate from the primary 364 * look and feel. 365 */ 366 public Rectangle getPathBounds(JTree tree, TreePath path) 367 { 368 Rectangle result = null; 369 Iterator iterator = uis.iterator(); 370 // first UI delegate provides the return value 371 if (iterator.hasNext()) 372 { 373 TreeUI ui = (TreeUI) iterator.next(); 374 result = ui.getPathBounds(tree, path); 375 } 376 // return values from auxiliary UI delegates are ignored 377 while (iterator.hasNext()) 378 { 379 TreeUI ui = (TreeUI) iterator.next(); 380 /* Rectangle ignored = */ ui.getPathBounds(tree, path); 381 } 382 return result; 383 } 384 385 /** 386 * Calls the {@link TreeUI#getPathForRow(JTree, int)} method 387 * for all the UI delegates managed by this <code>MultiTreeUI</code>, 388 * returning the path for the UI delegate from the primary look and 389 * feel. 390 * 391 * @param tree the tree component. 392 * 393 * @return The path returned by the UI delegate from the primary 394 * look and feel. 395 */ 396 public TreePath getPathForRow(JTree tree, int row) 397 { 398 TreePath result = null; 399 Iterator iterator = uis.iterator(); 400 // first UI delegate provides the return value 401 if (iterator.hasNext()) 402 { 403 TreeUI ui = (TreeUI) iterator.next(); 404 result = ui.getPathForRow(tree, row); 405 } 406 // return values from auxiliary UI delegates are ignored 407 while (iterator.hasNext()) 408 { 409 TreeUI ui = (TreeUI) iterator.next(); 410 /* TreePath ignored = */ ui.getPathForRow(tree, row); 411 } 412 return result; 413 } 414 415 /** 416 * Calls the {@link TreeUI#getRowForPath(JTree, TreePath)} method 417 * for all the UI delegates managed by this <code>MultiTreeUI</code>, 418 * returning the row index for the UI delegate from the primary look and 419 * feel. 420 * 421 * @param tree the tree component. 422 * 423 * @return The row index returned by the UI delegate from the primary 424 * look and feel. 425 */ 426 public int getRowForPath(JTree tree, TreePath path) 427 { 428 int result = 0; 429 Iterator iterator = uis.iterator(); 430 // first UI delegate provides the return value 431 if (iterator.hasNext()) 432 { 433 TreeUI ui = (TreeUI) iterator.next(); 434 result = ui.getRowForPath(tree, path); 435 } 436 // return values from auxiliary UI delegates are ignored 437 while (iterator.hasNext()) 438 { 439 TreeUI ui = (TreeUI) iterator.next(); 440 /* int ignored = */ ui.getRowForPath(tree, path); 441 } 442 return result; 443 } 444 445 /** 446 * Calls the {@link TreeUI#getRowCount(JTree)} method 447 * for all the UI delegates managed by this <code>MultiTreeUI</code>, 448 * returning the count for the UI delegate from the primary look and 449 * feel. 450 * 451 * @param tree the tree component. 452 * 453 * @return The count returned by the UI delegate from the primary 454 * look and feel. 455 */ 456 public int getRowCount(JTree tree) 457 { 458 int result = 0; 459 Iterator iterator = uis.iterator(); 460 // first UI delegate provides the return value 461 if (iterator.hasNext()) 462 { 463 TreeUI ui = (TreeUI) iterator.next(); 464 result = ui.getRowCount(tree); 465 } 466 // return values from auxiliary UI delegates are ignored 467 while (iterator.hasNext()) 468 { 469 TreeUI ui = (TreeUI) iterator.next(); 470 /* int ignored = */ ui.getRowCount(tree); 471 } 472 return result; 473 } 474 475 /** 476 * Calls the {@link TreeUI#getClosestPathForLocation(JTree, int, int)} method 477 * for all the UI delegates managed by this <code>MultiTreeUI</code>, 478 * returning the path for the UI delegate from the primary look and 479 * feel. 480 * 481 * @param tree the tree component. 482 * 483 * @return The path returned by the UI delegate from the primary 484 * look and feel. 485 */ 486 public TreePath getClosestPathForLocation(JTree tree, int x, int y) 487 { 488 TreePath result = null; 489 Iterator iterator = uis.iterator(); 490 // first UI delegate provides the return value 491 if (iterator.hasNext()) 492 { 493 TreeUI ui = (TreeUI) iterator.next(); 494 result = ui.getClosestPathForLocation(tree, x, y); 495 } 496 // return values from auxiliary UI delegates are ignored 497 while (iterator.hasNext()) 498 { 499 TreeUI ui = (TreeUI) iterator.next(); 500 /* TreePath ignored = */ ui.getClosestPathForLocation(tree, x, y); 501 } 502 return result; 503 } 504 505 /** 506 * Calls the {@link TreeUI#isEditing(JTree)} method for all 507 * the UI delegates managed by this <code>MultiTreeUI</code>, 508 * returning the result for the UI delegate from the primary look and 509 * feel. 510 * 511 * @param tree the tree component. 512 * 513 * @return The result returned by the UI delegate from the primary 514 * look and feel. 515 */ 516 public boolean isEditing(JTree tree) 517 { 518 boolean result = false; 519 Iterator iterator = uis.iterator(); 520 // first UI delegate provides the return value 521 if (iterator.hasNext()) 522 { 523 TreeUI ui = (TreeUI) iterator.next(); 524 result = ui.isEditing(tree); 525 } 526 // return values from auxiliary UI delegates are ignored 527 while (iterator.hasNext()) 528 { 529 TreeUI ui = (TreeUI) iterator.next(); 530 /* boolean ignored = */ ui.isEditing(tree); 531 } 532 return result; 533 } 534 535 /** 536 * Calls the {@link TreeUI#stopEditing(JTree)} method for all 537 * the UI delegates managed by this <code>MultiTreeUI</code>, 538 * returning the result for the UI delegate from the primary look and 539 * feel. 540 * 541 * @param tree the tree component. 542 * 543 * @return The result returned by the UI delegate from the primary 544 * look and feel. 545 */ 546 public boolean stopEditing(JTree tree) 547 { 548 boolean result = false; 549 Iterator iterator = uis.iterator(); 550 // first UI delegate provides the return value 551 if (iterator.hasNext()) 552 { 553 TreeUI ui = (TreeUI) iterator.next(); 554 result = ui.stopEditing(tree); 555 } 556 // return values from auxiliary UI delegates are ignored 557 while (iterator.hasNext()) 558 { 559 TreeUI ui = (TreeUI) iterator.next(); 560 /* boolean ignored = */ ui.stopEditing(tree); 561 } 562 return result; 563 } 564 565 /** 566 * Calls the {@link TreeUI#cancelEditing(JTree)} method for 567 * all the UI delegates managed by this <code>MultiTreeUI</code>. 568 * 569 * @param tree the tree component. 570 */ 571 public void cancelEditing(JTree tree) 572 { 573 Iterator iterator = uis.iterator(); 574 while (iterator.hasNext()) 575 { 576 TreeUI ui = (TreeUI) iterator.next(); 577 ui.cancelEditing(tree); 578 } 579 } 580 581 /** 582 * Calls the {@link TreeUI#startEditingAtPath(JTree, TreePath)} method for 583 * all the UI delegates managed by this <code>MultiTreeUI</code>. 584 * 585 * @param tree the tree component. 586 * @param path the path. 587 */ 588 public void startEditingAtPath(JTree tree, TreePath path) 589 { 590 Iterator iterator = uis.iterator(); 591 while (iterator.hasNext()) 592 { 593 TreeUI ui = (TreeUI) iterator.next(); 594 ui.startEditingAtPath(tree, path); 595 } 596 } 597 598 /** 599 * Calls the {@link TreeUI#getEditingPath(JTree)} method for all 600 * the UI delegates managed by this <code>MultiTreeUI</code>, 601 * returning the path for the UI delegate from the primary look and 602 * feel. 603 * 604 * @param tree the tree component. 605 * 606 * @return The path returned by the UI delegate from the primary 607 * look and feel. 608 */ 609 public TreePath getEditingPath(JTree tree) 610 { 611 TreePath result = null; 612 Iterator iterator = uis.iterator(); 613 // first UI delegate provides the return value 614 if (iterator.hasNext()) 615 { 616 TreeUI ui = (TreeUI) iterator.next(); 617 result = ui.getEditingPath(tree); 618 } 619 // return values from auxiliary UI delegates are ignored 620 while (iterator.hasNext()) 621 { 622 TreeUI ui = (TreeUI) iterator.next(); 623 /* TreePath ignored = */ ui.getEditingPath(tree); 624 } 625 return result; 626 } 627 628 }