Source for javax.swing.plaf.multi.MultiTextUI

   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:    */
  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:    */
  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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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: }