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