001 /* MultiTextUI.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.Point;
043 import java.awt.Rectangle;
044 import java.util.Iterator;
045 import java.util.Vector;
046
047 import javax.accessibility.Accessible;
048 import javax.swing.JComponent;
049 import javax.swing.LookAndFeel;
050 import javax.swing.UIManager;
051 import javax.swing.plaf.ComponentUI;
052 import javax.swing.plaf.TextUI;
053 import javax.swing.text.BadLocationException;
054 import javax.swing.text.EditorKit;
055 import javax.swing.text.JTextComponent;
056 import javax.swing.text.Position;
057 import javax.swing.text.View;
058 import javax.swing.text.Position.Bias;
059
060 /**
061 * A UI delegate that that coordinates multiple {@link TextUI}
062 * instances, one from the primary look and feel, and one or more from the
063 * auxiliary look and feel(s).
064 *
065 * @see UIManager#addAuxiliaryLookAndFeel(LookAndFeel)
066 */
067 public class MultiTextUI extends TextUI
068 {
069
070 /** A list of references to the actual component UIs. */
071 protected Vector uis;
072
073 /**
074 * Creates a new <code>MultiTextUI</code> instance.
075 *
076 * @see #createUI(JComponent)
077 */
078 public MultiTextUI()
079 {
080 uis = new Vector();
081 }
082
083 /**
084 * Creates a delegate object for the specified component. If any auxiliary
085 * look and feels support this component, a <code>MultiTextUI</code> is
086 * returned, otherwise the UI from the default look and feel is returned.
087 *
088 * @param target the component.
089 *
090 * @see MultiLookAndFeel#createUIs(ComponentUI, Vector, JComponent)
091 */
092 public static ComponentUI createUI(JComponent target)
093 {
094 MultiTextUI mui = new MultiTextUI();
095 return MultiLookAndFeel.createUIs(mui, mui.uis, target);
096 }
097
098 /**
099 * 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 }