OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [javax/] [swing/] [JComponent.java] - Blame information for rev 772

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 772 jeremybenn
/* JComponent.java -- Every component in swing inherits from this class.
2
   Copyright (C) 2002, 2004, 2005, 2006,  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
 
39
package javax.swing;
40
 
41
import gnu.java.lang.CPStringBuilder;
42
 
43
import java.applet.Applet;
44
import java.awt.AWTEvent;
45
import java.awt.Color;
46
import java.awt.Component;
47
import java.awt.Container;
48
import java.awt.Dimension;
49
import java.awt.EventQueue;
50
import java.awt.FocusTraversalPolicy;
51
import java.awt.Font;
52
import java.awt.Graphics;
53
import java.awt.Image;
54
import java.awt.Insets;
55
import java.awt.Point;
56
import java.awt.Rectangle;
57
import java.awt.Window;
58
import java.awt.dnd.DropTarget;
59
import java.awt.event.ActionEvent;
60
import java.awt.event.ActionListener;
61
import java.awt.event.ContainerEvent;
62
import java.awt.event.ContainerListener;
63
import java.awt.event.FocusEvent;
64
import java.awt.event.FocusListener;
65
import java.awt.event.KeyEvent;
66
import java.awt.event.MouseEvent;
67
import java.awt.peer.LightweightPeer;
68
import java.beans.PropertyChangeEvent;
69
import java.beans.PropertyChangeListener;
70
import java.beans.PropertyVetoException;
71
import java.beans.VetoableChangeListener;
72
import java.beans.VetoableChangeSupport;
73
import java.io.Serializable;
74
import java.util.ArrayList;
75
import java.util.EventListener;
76
import java.util.Hashtable;
77
import java.util.Locale;
78
import java.util.Set;
79
 
80
import javax.accessibility.Accessible;
81
import javax.accessibility.AccessibleContext;
82
import javax.accessibility.AccessibleExtendedComponent;
83
import javax.accessibility.AccessibleKeyBinding;
84
import javax.accessibility.AccessibleRole;
85
import javax.accessibility.AccessibleState;
86
import javax.accessibility.AccessibleStateSet;
87
import javax.swing.border.Border;
88
import javax.swing.border.CompoundBorder;
89
import javax.swing.border.TitledBorder;
90
import javax.swing.event.AncestorEvent;
91
import javax.swing.event.AncestorListener;
92
import javax.swing.event.EventListenerList;
93
import javax.swing.plaf.ComponentUI;
94
 
95
/**
96
 * The base class of all Swing components.
97
 * It contains generic methods to manage events, properties and sizes. Actual
98
 * drawing of the component is channeled to a look-and-feel class that is
99
 * implemented elsewhere.
100
 *
101
 * @author Ronald Veldema (rveldema&064;cs.vu.nl)
102
 * @author Graydon Hoare (graydon&064;redhat.com)
103
 */
104
public abstract class JComponent extends Container implements Serializable
105
{
106
  private static final long serialVersionUID = -7908749299918704233L;
107
 
108
  /**
109
   * The accessible context of this <code>JComponent</code>.
110
   */
111
  protected AccessibleContext accessibleContext;
112
 
113
  /**
114
   * Basic accessibility support for <code>JComponent</code> derived
115
   * widgets.
116
   */
117
  public abstract class AccessibleJComponent
118
    extends AccessibleAWTContainer
119
    implements AccessibleExtendedComponent
120
  {
121
    /**
122
     * Receives notification if the focus on the JComponent changes and
123
     * fires appropriate PropertyChangeEvents to listeners registered with
124
     * the AccessibleJComponent.
125
     */
126
    protected class AccessibleFocusHandler
127
      implements FocusListener
128
    {
129
      /**
130
       * Creates a new AccessibleFocusHandler.
131
       */
132
      protected AccessibleFocusHandler()
133
      {
134
        // Nothing to do here.
135
      }
136
 
137
      /**
138
       * Receives notification when the JComponent gained focus and fires
139
       * a PropertyChangeEvent to listeners registered on the
140
       * AccessibleJComponent with a property name of
141
       * {@link AccessibleContext#ACCESSIBLE_STATE_PROPERTY} and a new value
142
       * of {@link AccessibleState#FOCUSED}.
143
       */
144
      public void focusGained(FocusEvent event)
145
      {
146
        AccessibleJComponent.this.firePropertyChange
147
          (AccessibleContext.ACCESSIBLE_STATE_PROPERTY, null,
148
           AccessibleState.FOCUSED);
149
      }
150
 
151
      /**
152
       * Receives notification when the JComponent lost focus and fires
153
       * a PropertyChangeEvent to listeners registered on the
154
       * AccessibleJComponent with a property name of
155
       * {@link AccessibleContext#ACCESSIBLE_STATE_PROPERTY} and an old value
156
       * of {@link AccessibleState#FOCUSED}.
157
       */
158
      public void focusLost(FocusEvent valevent)
159
      {
160
        AccessibleJComponent.this.firePropertyChange
161
          (AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
162
           AccessibleState.FOCUSED, null);
163
      }
164
    }
165
 
166
    /**
167
     * Receives notification if there are child components are added or removed
168
     * from the JComponent and fires appropriate PropertyChangeEvents to
169
     * interested listeners on the AccessibleJComponent.
170
     */
171
    protected class AccessibleContainerHandler
172
      implements ContainerListener
173
    {
174
      /**
175
       * Creates a new AccessibleContainerHandler.
176
       */
177
      protected AccessibleContainerHandler()
178
      {
179
        // Nothing to do here.
180
      }
181
 
182
      /**
183
       * Receives notification when a child component is added to the
184
       * JComponent and fires a PropertyChangeEvent on listeners registered
185
       * with the AccessibleJComponent with a property name of
186
       * {@link AccessibleContext#ACCESSIBLE_CHILD_PROPERTY}.
187
       *
188
       * @param event the container event
189
       */
190
      public void componentAdded(ContainerEvent event)
191
      {
192
        Component c = event.getChild();
193
        if (c != null && c instanceof Accessible)
194
          {
195
            AccessibleContext childCtx = c.getAccessibleContext();
196
            AccessibleJComponent.this.firePropertyChange
197
              (AccessibleContext.ACCESSIBLE_CHILD_PROPERTY, null, childCtx);
198
          }
199
      }
200
 
201
      /**
202
       * Receives notification when a child component is removed from the
203
       * JComponent and fires a PropertyChangeEvent on listeners registered
204
       * with the AccessibleJComponent with a property name of
205
       * {@link AccessibleContext#ACCESSIBLE_CHILD_PROPERTY}.
206
       *
207
       * @param event the container event
208
       */
209
      public void componentRemoved(ContainerEvent event)
210
      {
211
        Component c = event.getChild();
212
        if (c != null && c instanceof Accessible)
213
          {
214
            AccessibleContext childCtx = c.getAccessibleContext();
215
            AccessibleJComponent.this.firePropertyChange
216
              (AccessibleContext.ACCESSIBLE_CHILD_PROPERTY, childCtx, null);
217
          }
218
      }
219
    }
220
 
221
    private static final long serialVersionUID = -7047089700479897799L;
222
 
223
    /**
224
     * Receives notification when a child component is added to the
225
     * JComponent and fires a PropertyChangeEvent on listeners registered
226
     * with the AccessibleJComponent.
227
     *
228
     * @specnote AccessibleAWTContainer has a protected field with the same
229
     *           name. Looks like a bug or nasty misdesign to me.
230
     */
231
    protected ContainerListener accessibleContainerHandler;
232
 
233
    /**
234
     * Receives notification if the focus on the JComponent changes and
235
     * fires appropriate PropertyChangeEvents to listeners registered with
236
     * the AccessibleJComponent.
237
     *
238
     * @specnote AccessibleAWTComponent has a protected field
239
     *           accessibleAWTFocusHandler. Looks like a bug or nasty misdesign
240
     *           to me.
241
     */
242
    protected FocusListener accessibleFocusHandler;
243
 
244
    /**
245
     * Creates a new AccessibleJComponent.
246
     */
247
    protected AccessibleJComponent()
248
    {
249
      // Nothing to do here.
250
    }
251
 
252
    /**
253
     * Adds a property change listener to the list of registered listeners.
254
     *
255
     * This sets up the {@link #accessibleContainerHandler} and
256
     * {@link #accessibleFocusHandler} fields and calls
257
     * <code>super.addPropertyChangeListener(listener)</code>.
258
     *
259
     * @param listener the listener to add
260
     */
261
    public void addPropertyChangeListener(PropertyChangeListener listener)
262
    {
263
      // Tests seem to indicate that this method also sets up the other two
264
      // handlers.
265
      if (accessibleContainerHandler == null)
266
        {
267
          accessibleContainerHandler = new AccessibleContainerHandler();
268
          addContainerListener(accessibleContainerHandler);
269
        }
270
      if (accessibleFocusHandler == null)
271
        {
272
          accessibleFocusHandler = new AccessibleFocusHandler();
273
          addFocusListener(accessibleFocusHandler);
274
        }
275
      super.addPropertyChangeListener(listener);
276
    }
277
 
278
    /**
279
     * Removes a property change listener from the list of registered listeners.
280
     *
281
     * This uninstalls the {@link #accessibleContainerHandler} and
282
     * {@link #accessibleFocusHandler} fields and calls
283
     * <code>super.removePropertyChangeListener(listener)</code>.
284
     *
285
     * @param listener the listener to remove
286
     */
287
    public void removePropertyChangeListener(PropertyChangeListener listener)
288
    {
289
      // Tests seem to indicate that this method also resets the other two
290
      // handlers.
291
      if (accessibleContainerHandler != null)
292
        {
293
          removeContainerListener(accessibleContainerHandler);
294
          accessibleContainerHandler = null;
295
        }
296
      if (accessibleFocusHandler != null)
297
        {
298
          removeFocusListener(accessibleFocusHandler);
299
          accessibleFocusHandler = null;
300
        }
301
      super.removePropertyChangeListener(listener);
302
    }
303
 
304
    /**
305
     * Returns the number of accessible children of this object.
306
     *
307
     * @return  the number of accessible children of this object
308
     */
309
    public int getAccessibleChildrenCount()
310
    {
311
      // TODO: The functionality should be performed in the superclass.
312
      // Find out why this is overridden. However, it is very well possible
313
      // that this is left over from times when there was no such superclass
314
      // method.
315
      return super.getAccessibleChildrenCount();
316
    }
317
 
318
    /**
319
     * Returns the accessible child component at index <code>i</code>.
320
     *
321
     * @param i the index of the accessible child to return
322
     *
323
     * @return the accessible child component at index <code>i</code>
324
     */
325
    public Accessible getAccessibleChild(int i)
326
    {
327
      // TODO: The functionality should be performed in the superclass.
328
      // Find out why this is overridden. However, it is very well possible
329
      // that this is left over from times when there was no such superclass
330
      // method.
331
      return super.getAccessibleChild(i);
332
    }
333
 
334
    /**
335
     * Returns the accessible state set of this component.
336
     *
337
     * @return the accessible state set of this component
338
     */
339
    public AccessibleStateSet getAccessibleStateSet()
340
    {
341
      // Note: While the java.awt.Component has an 'opaque' property, it
342
      // seems that it is not added to the accessible state set there, even
343
      // if this property is true. However, it is handled for JComponent, so
344
      // we add it here.
345
      AccessibleStateSet state = super.getAccessibleStateSet();
346
      if (isOpaque())
347
        state.add(AccessibleState.OPAQUE);
348
      return state;
349
    }
350
 
351
    /**
352
     * Returns the localized name for this object. Generally this should
353
     * almost never return {@link Component#getName()} since that is not
354
     * a localized name. If the object is some kind of text component (like
355
     * a menu item), then the value of the object may be returned. Also, if
356
     * the object has a tooltip, the value of the tooltip may also be
357
     * appropriate.
358
     *
359
     * @return the localized name for this object or <code>null</code> if this
360
     *         object has no name
361
     */
362
    public String getAccessibleName()
363
    {
364
      String name = super.getAccessibleName();
365
 
366
      // There are two fallbacks provided by the JComponent in the case the
367
      // superclass returns null:
368
      // - If the component is inside a titled border, then it inherits the
369
      //   name from the border title.
370
      // - If the component is not inside a titled border but has a label
371
      //   (via JLabel.setLabelFor()), then it gets the name from the label's
372
      //   accessible context.
373
 
374
      if (name == null)
375
        {
376
          name = getTitledBorderText();
377
        }
378
 
379
      if (name == null)
380
        {
381
          Object l = getClientProperty(JLabel.LABEL_PROPERTY);
382
          if (l instanceof Accessible)
383
            {
384
              AccessibleContext labelCtx =
385
                ((Accessible) l).getAccessibleContext();
386
              name = labelCtx.getAccessibleName();
387
            }
388
        }
389
 
390
      return name;
391
    }
392
 
393
    /**
394
     * Returns the localized description of this object.
395
     *
396
     * @return the localized description of this object or <code>null</code>
397
     *         if this object has no description
398
     */
399
    public String getAccessibleDescription()
400
    {
401
      // There are two fallbacks provided by the JComponent in the case the
402
      // superclass returns null:
403
      // - If the component has a tooltip, then inherit the description from
404
      //   the tooltip.
405
      // - If the component is not inside a titled border but has a label
406
      //   (via JLabel.setLabelFor()), then it gets the name from the label's
407
      //   accessible context.
408
      String descr = super.getAccessibleDescription();
409
 
410
      if (descr == null)
411
        {
412
          descr = getToolTipText();
413
        }
414
 
415
      if (descr == null)
416
        {
417
          Object l = getClientProperty(JLabel.LABEL_PROPERTY);
418
          if (l instanceof Accessible)
419
            {
420
              AccessibleContext labelCtx =
421
                ((Accessible) l).getAccessibleContext();
422
              descr = labelCtx.getAccessibleName();
423
            }
424
        }
425
 
426
      return descr;
427
    }
428
 
429
    /**
430
     * Returns the accessible role of this component.
431
     *
432
     * @return the accessible role of this component
433
     *
434
     * @see AccessibleRole
435
     */
436
    public AccessibleRole getAccessibleRole()
437
    {
438
      return AccessibleRole.SWING_COMPONENT;
439
    }
440
 
441
    /**
442
     * Recursivly searches a border hierarchy (starting at <code>border) for
443
     * a titled border and returns the title if one is found, <code>null</code>
444
     * otherwise.
445
     *
446
     * @param border the border to start search from
447
     *
448
     * @return the border title of a possibly found titled border
449
     */
450
    protected String getBorderTitle(Border border)
451
    {
452
      String title = null;
453
      if (border instanceof CompoundBorder)
454
        {
455
          CompoundBorder compound = (CompoundBorder) border;
456
          Border inner = compound.getInsideBorder();
457
          title = getBorderTitle(inner);
458
          if (title == null)
459
            {
460
              Border outer = compound.getOutsideBorder();
461
              title = getBorderTitle(outer);
462
            }
463
        }
464
      else if (border instanceof TitledBorder)
465
        {
466
          TitledBorder titled = (TitledBorder) border;
467
          title = titled.getTitle();
468
        }
469
      return title;
470
    }
471
 
472
    /**
473
     * Returns the tooltip text for this accessible component.
474
     *
475
     * @return the tooltip text for this accessible component
476
     */
477
    public String getToolTipText()
478
    {
479
      return JComponent.this.getToolTipText();
480
    }
481
 
482
    /**
483
     * Returns the title of the border of this accessible component if
484
     * this component has a titled border, otherwise returns <code>null</code>.
485
     *
486
     * @return the title of the border of this accessible component if
487
     *         this component has a titled border, otherwise returns
488
     *         <code>null</code>
489
     */
490
    public String getTitledBorderText()
491
    {
492
      return getBorderTitle(getBorder());
493
    }
494
 
495
    /**
496
     * Returns the keybindings associated with this accessible component or
497
     * <code>null</code> if the component does not support key bindings.
498
     *
499
     * @return the keybindings associated with this accessible component
500
     */
501
    public AccessibleKeyBinding getAccessibleKeyBinding()
502
    {
503
      // The reference implementation seems to always return null here,
504
      // independent of the key bindings of the JComponent. So do we.
505
      return null;
506
    }
507
  }
508
 
509
  /**
510
   * A value between 0.0 and 1.0 indicating the preferred horizontal
511
   * alignment of the component, relative to its siblings. The values
512
   * {@link #LEFT_ALIGNMENT}, {@link #CENTER_ALIGNMENT}, and {@link
513
   * #RIGHT_ALIGNMENT} can also be used, as synonyms for <code>0.0</code>,
514
   * <code>0.5</code>, and <code>1.0</code>, respectively. Not all layout
515
   * managers use this property.
516
   *
517
   * @see #getAlignmentX
518
   * @see #setAlignmentX
519
   * @see javax.swing.OverlayLayout
520
   * @see javax.swing.BoxLayout
521
   */
522
  float alignmentX = -1.0F;
523
 
524
  /**
525
   * A value between 0.0 and 1.0 indicating the preferred vertical
526
   * alignment of the component, relative to its siblings. The values
527
   * {@link #TOP_ALIGNMENT}, {@link #CENTER_ALIGNMENT}, and {@link
528
   * #BOTTOM_ALIGNMENT} can also be used, as synonyms for <code>0.0</code>,
529
   * <code>0.5</code>, and <code>1.0</code>, respectively. Not all layout
530
   * managers use this property.
531
   *
532
   * @see #getAlignmentY
533
   * @see #setAlignmentY
534
   * @see javax.swing.OverlayLayout
535
   * @see javax.swing.BoxLayout
536
   */
537
  float alignmentY = -1.0F;
538
 
539
  /**
540
   * The border painted around this component.
541
   *
542
   * @see #paintBorder
543
   */
544
  Border border;
545
 
546
  /**
547
   * The popup menu for the component.
548
   *
549
   * @see #getComponentPopupMenu()
550
   * @see #setComponentPopupMenu(JPopupMenu)
551
   */
552
  JPopupMenu componentPopupMenu;
553
 
554
  /**
555
   * A flag that controls whether the {@link #getComponentPopupMenu()} method
556
   * looks to the component's parent when the <code>componentPopupMenu</code>
557
   * field is <code>null</code>.
558
   */
559
  boolean inheritsPopupMenu;
560
 
561
  /**
562
   * <p>Whether to double buffer this component when painting. This flag
563
   * should generally be <code>true</code>, to ensure good painting
564
   * performance.</p>
565
   *
566
   * <p>All children of a double buffered component are painted into the
567
   * double buffer automatically, so only the top widget in a window needs
568
   * to be double buffered.</p>
569
   *
570
   * @see #setDoubleBuffered
571
   * @see #isDoubleBuffered
572
   * @see #paint
573
   */
574
  boolean doubleBuffered = true;
575
 
576
  /**
577
   * A set of flags indicating which debugging graphics facilities should
578
   * be enabled on this component. The values should be a combination of
579
   * {@link DebugGraphics#NONE_OPTION}, {@link DebugGraphics#LOG_OPTION},
580
   * {@link DebugGraphics#FLASH_OPTION}, or {@link
581
   * DebugGraphics#BUFFERED_OPTION}.
582
   *
583
   * @see #setDebugGraphicsOptions
584
   * @see #getDebugGraphicsOptions
585
   * @see DebugGraphics
586
   * @see #getComponentGraphics
587
   */
588
  int debugGraphicsOptions;
589
 
590
  /**
591
   * <p>This property controls two independent behaviors simultaneously.</p>
592
   *
593
   * <p>First, it controls whether to fill the background of this widget
594
   * when painting its body. This affects calls to {@link
595
   * JComponent#paintComponent}, which in turn calls {@link
596
   * ComponentUI#update} on the component's {@link #ui} property. If the
597
   * component is opaque during this call, the background will be filled
598
   * before calling {@link ComponentUI#paint}. This happens merely as a
599
   * convenience; you may fill the component's background yourself too,
600
   * but there is no need to do so if you will be filling with the same
601
   * color.</p>
602
   *
603
   * <p>Second, it the opaque property informs swing's repaint system
604
   * whether it will be necessary to paint the components "underneath" this
605
   * component, in Z-order. If the component is opaque, it is considered to
606
   * completely occlude components "underneath" it, so they will not be
607
   * repainted along with the opaque component.</p>
608
   *
609
   * <p>The default value for this property is <code>false</code>, but most
610
   * components will want to set it to <code>true</code> when installing UI
611
   * defaults in {@link ComponentUI#installUI}.</p>
612
   *
613
   * @see #setOpaque
614
   * @see #isOpaque
615
   * @see #paintComponent
616
   */
617
  boolean opaque = false;
618
 
619
  /**
620
   * The user interface delegate for this component. Event delivery and
621
   * repainting of the component are usually delegated to this object.
622
   *
623
   * @see #setUI
624
   * @see #getUIClassID
625
   * @see #updateUI
626
   */
627
  protected ComponentUI ui;
628
 
629
  /**
630
   * A hint to the focus system that this component should or should not
631
   * get focus. If this is <code>false</code>, swing will not try to
632
   * request focus on this component; if <code>true</code>, swing might
633
   * try to request focus, but the request might fail. Thus it is only
634
   * a hint guiding swing's behavior.
635
   *
636
   * @see #requestFocus()
637
   * @see #isRequestFocusEnabled
638
   * @see #setRequestFocusEnabled
639
   */
640
  boolean requestFocusEnabled;
641
 
642
  /**
643
   * Flag indicating behavior of this component when the mouse is dragged
644
   * outside the component and the mouse <em>stops moving</em>. If
645
   * <code>true</code>, synthetic mouse events will be delivered on regular
646
   * timed intervals, continuing off in the direction the mouse exited the
647
   * component, until the mouse is released or re-enters the component.
648
   *
649
   * @see #setAutoscrolls
650
   * @see #getAutoscrolls
651
   */
652
  boolean autoscrolls = false;
653
 
654
  /**
655
   * Indicates whether the current paint call is already double buffered or
656
   * not.
657
   */
658
  static boolean paintingDoubleBuffered = false;
659
 
660
  /**
661
   * Indicates whether we are calling paintDoubleBuffered() from
662
   * paintImmadiately (RepaintManager) or from paint() (AWT refresh).
663
   */
664
  static boolean isRepainting = false;
665
 
666
  /**
667
   * Listeners for events other than {@link PropertyChangeEvent} are
668
   * handled by this listener list. PropertyChangeEvents are handled in
669
   * {@link #changeSupport}.
670
   */
671
  protected EventListenerList listenerList = new EventListenerList();
672
 
673
  /**
674
   * Handles VetoableChangeEvents.
675
   */
676
  private VetoableChangeSupport vetoableChangeSupport;
677
 
678
  /**
679
   * Storage for "client properties", which are key/value pairs associated
680
   * with this component by a "client", such as a user application or a
681
   * layout manager. This is lazily constructed when the component gets its
682
   * first client property.
683
   */
684
  private Hashtable clientProperties;
685
 
686
  private InputMap inputMap_whenFocused;
687
  private InputMap inputMap_whenAncestorOfFocused;
688
  private ComponentInputMap inputMap_whenInFocusedWindow;
689
  private ActionMap actionMap;
690
  /** @since 1.3 */
691
  private boolean verifyInputWhenFocusTarget = true;
692
  private InputVerifier inputVerifier;
693
 
694
  private TransferHandler transferHandler;
695
 
696
  /**
697
   * Indicates if this component is currently painting a tile or not.
698
   */
699
  private boolean paintingTile;
700
 
701
  /**
702
   * A temporary buffer used for fast dragging of components.
703
   */
704
  private Image dragBuffer;
705
 
706
  /**
707
   * Indicates if the dragBuffer is already initialized.
708
   */
709
  private boolean dragBufferInitialized;
710
 
711
  /**
712
   * A cached Rectangle object to be reused. Be careful when you use that,
713
   * so that it doesn't get modified in another context within the same
714
   * method call chain.
715
   */
716
  private static transient Rectangle rectCache;
717
 
718
  /**
719
   * The default locale of the component.
720
   *
721
   * @see #getDefaultLocale
722
   * @see #setDefaultLocale
723
   */
724
  private static Locale defaultLocale;
725
 
726
  public static final String TOOL_TIP_TEXT_KEY = "ToolTipText";
727
 
728
  /**
729
   * Constant used to indicate that no condition has been assigned to a
730
   * particular action.
731
   *
732
   * @see #registerKeyboardAction(ActionListener, KeyStroke, int)
733
   */
734
  public static final int UNDEFINED_CONDITION = -1;
735
 
736
  /**
737
   * Constant used to indicate that an action should be performed only when
738
   * the component has focus.
739
   *
740
   * @see #registerKeyboardAction(ActionListener, KeyStroke, int)
741
   */
742
  public static final int WHEN_FOCUSED = 0;
743
 
744
  /**
745
   * Constant used to indicate that an action should be performed only when
746
   * the component is an ancestor of the component which has focus.
747
   *
748
   * @see #registerKeyboardAction(ActionListener, KeyStroke, int)
749
   */
750
  public static final int WHEN_ANCESTOR_OF_FOCUSED_COMPONENT = 1;
751
 
752
  /**
753
   * Constant used to indicate that an action should be performed only when
754
   * the component is in the window which has focus.
755
   *
756
   * @see #registerKeyboardAction(ActionListener, KeyStroke, int)
757
   */
758
  public static final int WHEN_IN_FOCUSED_WINDOW = 2;
759
 
760
 
761
  /**
762
   * Used to optimize painting. This is set in paintImmediately2() to specify
763
   * the exact component path to be painted by paintChildren.
764
   */
765
  Component paintChild;
766
 
767
  /**
768
   * Indicates if the opaque property has been set by a client program or by
769
   * the UI.
770
   *
771
   * @see #setUIProperty(String, Object)
772
   * @see LookAndFeel#installProperty(JComponent, String, Object)
773
   */
774
  private boolean clientOpaqueSet = false;
775
 
776
  /**
777
   * Indicates if the autoscrolls property has been set by a client program or
778
   * by the UI.
779
   *
780
   * @see #setUIProperty(String, Object)
781
   * @see LookAndFeel#installProperty(JComponent, String, Object)
782
   */
783
  private boolean clientAutoscrollsSet = false;
784
 
785
  /**
786
   * Creates a new <code>JComponent</code> instance.
787
   */
788
  public JComponent()
789
  {
790
    super();
791
    setDropTarget(new DropTarget());
792
    setLocale(getDefaultLocale());
793
    debugGraphicsOptions = DebugGraphics.NONE_OPTION;
794
    setRequestFocusEnabled(true);
795
  }
796
 
797
  /**
798
   * Helper to lazily construct and return the client properties table.
799
   *
800
   * @return The current client properties table
801
   *
802
   * @see #clientProperties
803
   * @see #getClientProperty
804
   * @see #putClientProperty
805
   */
806
  private Hashtable getClientProperties()
807
  {
808
    if (clientProperties == null)
809
      clientProperties = new Hashtable();
810
    return clientProperties;
811
  }
812
 
813
  /**
814
   * Get a client property associated with this component and a particular
815
   * key.
816
   *
817
   * @param key The key with which to look up the client property
818
   *
819
   * @return A client property associated with this object and key
820
   *
821
   * @see #clientProperties
822
   * @see #getClientProperties
823
   * @see #putClientProperty
824
   */
825
  public final Object getClientProperty(Object key)
826
  {
827
    return getClientProperties().get(key);
828
  }
829
 
830
  /**
831
   * Add a client property <code>value</code> to this component, associated
832
   * with <code>key</code>. If there is an existing client property
833
   * associated with <code>key</code>, it will be replaced.  A
834
   * {@link PropertyChangeEvent} is sent to registered listeners (with the
835
   * name of the property being <code>key.toString()</code>).
836
   *
837
   * @param key The key of the client property association to add
838
   * @param value The value of the client property association to add
839
   *
840
   * @see #clientProperties
841
   * @see #getClientProperties
842
   * @see #getClientProperty
843
   */
844
  public final void putClientProperty(Object key, Object value)
845
  {
846
    Hashtable t = getClientProperties();
847
    Object old = t.get(key);
848
    if (value != null)
849
      t.put(key, value);
850
    else
851
      t.remove(key);
852
 
853
    // When both old and new value are null, no event is fired. This is
854
    // different from what firePropertyChange() normally does, so we add this
855
    // check here.
856
    if (old != null || value != null)
857
      firePropertyChange(key.toString(), old, value);
858
  }
859
 
860
  /**
861
   * Unregister an <code>AncestorListener</code>.
862
   *
863
   * @param listener The listener to unregister
864
   *
865
   * @see #addAncestorListener
866
   */
867
  public void removeAncestorListener(AncestorListener listener)
868
  {
869
    listenerList.remove(AncestorListener.class, listener);
870
  }
871
 
872
  /**
873
   * Unregister a <code>VetoableChangeChangeListener</code>.
874
   *
875
   * @param listener The listener to unregister
876
   *
877
   * @see #addVetoableChangeListener
878
   */
879
  public void removeVetoableChangeListener(VetoableChangeListener listener)
880
  {
881
    if (vetoableChangeSupport != null)
882
      vetoableChangeSupport.removeVetoableChangeListener(listener);
883
  }
884
 
885
  /**
886
   * Register an <code>AncestorListener</code>.
887
   *
888
   * @param listener The listener to register
889
   *
890
   * @see #removeVetoableChangeListener
891
   */
892
  public void addAncestorListener(AncestorListener listener)
893
  {
894
    listenerList.add(AncestorListener.class, listener);
895
  }
896
 
897
  /**
898
   * Register a <code>VetoableChangeListener</code>.
899
   *
900
   * @param listener The listener to register
901
   *
902
   * @see #removeVetoableChangeListener
903
   * @see #listenerList
904
   */
905
  public void addVetoableChangeListener(VetoableChangeListener listener)
906
  {
907
    // Lazily instantiate this, it's rarely needed.
908
    if (vetoableChangeSupport == null)
909
      vetoableChangeSupport = new VetoableChangeSupport(this);
910
    vetoableChangeSupport.addVetoableChangeListener(listener);
911
  }
912
 
913
  /**
914
   * Returns all registered {@link EventListener}s of the given
915
   * <code>listenerType</code>.
916
   *
917
   * @param listenerType the class of listeners to filter (<code>null</code>
918
   *                     not permitted).
919
   *
920
   * @return An array of registered listeners.
921
   *
922
   * @throws ClassCastException if <code>listenerType</code> does not implement
923
   *                            the {@link EventListener} interface.
924
   * @throws NullPointerException if <code>listenerType</code> is
925
   *                              <code>null</code>.
926
   *
927
   * @see #getAncestorListeners()
928
   * @see #listenerList
929
   *
930
   * @since 1.3
931
   */
932
  public <T extends EventListener> T[] getListeners(Class<T> listenerType)
933
  {
934
    if (listenerType == PropertyChangeListener.class)
935
      return (T[]) getPropertyChangeListeners();
936
    else if (listenerType == VetoableChangeListener.class)
937
      return (T[]) getVetoableChangeListeners();
938
    else
939
      return listenerList.getListeners(listenerType);
940
  }
941
 
942
  /**
943
   * Return all registered <code>AncestorListener</code> objects.
944
   *
945
   * @return The set of <code>AncestorListener</code> objects in {@link
946
   * #listenerList}
947
   */
948
  public AncestorListener[] getAncestorListeners()
949
  {
950
    return (AncestorListener[]) getListeners(AncestorListener.class);
951
  }
952
 
953
  /**
954
   * Return all registered <code>VetoableChangeListener</code> objects.
955
   *
956
   * @return An array of the <code>VetoableChangeListener</code> objects
957
   *     registered with this component (possibly empty but never
958
   *     <code>null</code>).
959
   *
960
   * @since 1.4
961
   */
962
  public VetoableChangeListener[] getVetoableChangeListeners()
963
  {
964
    return vetoableChangeSupport == null ? new VetoableChangeListener[0]
965
        : vetoableChangeSupport.getVetoableChangeListeners();
966
  }
967
 
968
  /**
969
   * Call {@link VetoableChangeListener#vetoableChange} on all listeners
970
   * registered to listen to a given property. Any method which changes
971
   * the specified property of this component should call this method.
972
   *
973
   * @param propertyName The property which changed
974
   * @param oldValue The old value of the property
975
   * @param newValue The new value of the property
976
   *
977
   * @throws PropertyVetoException if the change was vetoed by a listener
978
   *
979
   * @see #addVetoableChangeListener
980
   * @see #removeVetoableChangeListener
981
   */
982
  protected void fireVetoableChange(String propertyName, Object oldValue,
983
                                    Object newValue)
984
    throws PropertyVetoException
985
  {
986
    if (vetoableChangeSupport != null)
987
      vetoableChangeSupport.fireVetoableChange(propertyName, oldValue, newValue);
988
  }
989
 
990
 
991
  /**
992
   * Fires a property change for a primitive integer property.
993
   *
994
   * @param property the name of the property
995
   * @param oldValue the old value of the property
996
   * @param newValue the new value of the property
997
   *
998
   * @specnote This method is implemented in
999
   *           {@link Component#firePropertyChange(String, int, int)}. It is
1000
   *           only here because it is specified to be public, whereas the
1001
   *           Component method is protected.
1002
   */
1003
  public void firePropertyChange(String property, int oldValue, int newValue)
1004
  {
1005
    super.firePropertyChange(property, oldValue, newValue);
1006
  }
1007
 
1008
  /**
1009
   * Fires a property change for a primitive boolean property.
1010
   *
1011
   * @param property the name of the property
1012
   * @param oldValue the old value of the property
1013
   * @param newValue the new value of the property
1014
   *
1015
   * @specnote This method is implemented in
1016
   *           {@link Component#firePropertyChange(String, boolean, boolean)}.
1017
   *           It is only here because it is specified to be public, whereas
1018
   *           the Component method is protected.
1019
   */
1020
  public void firePropertyChange(String property, boolean oldValue,
1021
                                 boolean newValue)
1022
  {
1023
    super.firePropertyChange(property, oldValue, newValue);
1024
  }
1025
 
1026
  /**
1027
   * Get the value of the accessibleContext property for this component.
1028
   *
1029
   * @return the current value of the property
1030
   */
1031
  public AccessibleContext getAccessibleContext()
1032
  {
1033
    return null;
1034
  }
1035
 
1036
  /**
1037
   * Get the value of the {@link #alignmentX} property.
1038
   *
1039
   * @return The current value of the property.
1040
   *
1041
   * @see #setAlignmentX
1042
   * @see #alignmentY
1043
   */
1044
  public float getAlignmentX()
1045
  {
1046
    float ret = alignmentX;
1047
    if (alignmentX < 0)
1048
      // alignment has not been set explicitly.
1049
      ret = super.getAlignmentX();
1050
 
1051
    return ret;
1052
  }
1053
 
1054
  /**
1055
   * Get the value of the {@link #alignmentY} property.
1056
   *
1057
   * @return The current value of the property.
1058
   *
1059
   * @see #setAlignmentY
1060
   * @see #alignmentX
1061
   */
1062
  public float getAlignmentY()
1063
  {
1064
    float ret = alignmentY;
1065
    if (alignmentY < 0)
1066
      // alignment has not been set explicitly.
1067
      ret = super.getAlignmentY();
1068
 
1069
    return ret;
1070
  }
1071
 
1072
  /**
1073
   * Get the current value of the {@link #autoscrolls} property.
1074
   *
1075
   * @return The current value of the property
1076
   */
1077
  public boolean getAutoscrolls()
1078
  {
1079
    return autoscrolls;
1080
  }
1081
 
1082
  /**
1083
   * Set the value of the {@link #border} property.
1084
   *
1085
   * @param newBorder The new value of the property
1086
   *
1087
   * @see #getBorder
1088
   */
1089
  public void setBorder(Border newBorder)
1090
  {
1091
    Border oldBorder = getBorder();
1092
    if (oldBorder == newBorder)
1093
      return;
1094
 
1095
    border = newBorder;
1096
    firePropertyChange("border", oldBorder, newBorder);
1097
    repaint();
1098
  }
1099
 
1100
  /**
1101
   * Get the value of the {@link #border} property.
1102
   *
1103
   * @return The property's current value
1104
   *
1105
   * @see #setBorder
1106
   */
1107
  public Border getBorder()
1108
  {
1109
    return border;
1110
  }
1111
 
1112
  /**
1113
   * Get the component's current bounding box. If a rectangle is provided,
1114
   * use this as the return value (adjusting its fields in place);
1115
   * otherwise (of <code>null</code> is provided) return a new {@link
1116
   * Rectangle}.
1117
   *
1118
   * @param rv Optional return value to use
1119
   *
1120
   * @return A rectangle bounding the component
1121
   */
1122
  public Rectangle getBounds(Rectangle rv)
1123
  {
1124
    if (rv == null)
1125
      return new Rectangle(getX(), getY(), getWidth(), getHeight());
1126
    else
1127
      {
1128
        rv.setBounds(getX(), getY(), getWidth(), getHeight());
1129
        return rv;
1130
      }
1131
  }
1132
 
1133
  /**
1134
   * Prepares a graphics context for painting this object. If {@link
1135
   * #debugGraphicsOptions} is not equal to {@link
1136
   * DebugGraphics#NONE_OPTION}, produce a new {@link DebugGraphics} object
1137
   * wrapping the parameter. Otherwise configure the parameter with this
1138
   * component's foreground color and font.
1139
   *
1140
   * @param g The graphics context to wrap or configure
1141
   *
1142
   * @return A graphics context to paint this object with
1143
   *
1144
   * @see #debugGraphicsOptions
1145
   * @see #paint
1146
   */
1147
  protected Graphics getComponentGraphics(Graphics g)
1148
  {
1149
    Graphics g2 = g;
1150
    int options = getDebugGraphicsOptions();
1151
    if (options != DebugGraphics.NONE_OPTION)
1152
      {
1153
        if (!(g2 instanceof DebugGraphics))
1154
          g2 = new DebugGraphics(g);
1155
        DebugGraphics dg = (DebugGraphics) g2;
1156
        dg.setDebugOptions(dg.getDebugOptions() | options);
1157
      }
1158
    g2.setFont(this.getFont());
1159
    g2.setColor(this.getForeground());
1160
    return g2;
1161
  }
1162
 
1163
  /**
1164
   * Get the value of the {@link #debugGraphicsOptions} property.
1165
   *
1166
   * @return The current value of the property.
1167
   *
1168
   * @see #setDebugGraphicsOptions
1169
   * @see #debugGraphicsOptions
1170
   */
1171
  public int getDebugGraphicsOptions()
1172
  {
1173
    String option = System.getProperty("gnu.javax.swing.DebugGraphics");
1174
    int options = debugGraphicsOptions;
1175
    if (option != null && option.length() != 0)
1176
      {
1177
        if (options < 0)
1178
          options = 0;
1179
 
1180
        if (option.equals("LOG"))
1181
          options |= DebugGraphics.LOG_OPTION;
1182
        else if (option.equals("FLASH"))
1183
          options |= DebugGraphics.FLASH_OPTION;
1184
      }
1185
    return options;
1186
  }
1187
 
1188
  /**
1189
   * Get the component's insets, which are calculated from
1190
   * the {@link #border} property. If the border is <code>null</code>,
1191
   * calls {@link Container#getInsets}.
1192
   *
1193
   * @return The component's current insets
1194
   */
1195
  public Insets getInsets()
1196
  {
1197
    if (border == null)
1198
      return super.getInsets();
1199
    return getBorder().getBorderInsets(this);
1200
  }
1201
 
1202
  /**
1203
   * Get the component's insets, which are calculated from the {@link
1204
   * #border} property. If the border is <code>null</code>, calls {@link
1205
   * Container#getInsets}. The passed-in {@link Insets} value will be
1206
   * used as the return value, if possible.
1207
   *
1208
   * @param insets Return value object to reuse, if possible
1209
   *
1210
   * @return The component's current insets
1211
   */
1212
  public Insets getInsets(Insets insets)
1213
  {
1214
    Insets t = getInsets();
1215
 
1216
    if (insets == null)
1217
      return t;
1218
 
1219
    insets.left = t.left;
1220
    insets.right = t.right;
1221
    insets.top = t.top;
1222
    insets.bottom = t.bottom;
1223
    return insets;
1224
  }
1225
 
1226
  /**
1227
   * Get the component's location. The passed-in {@link Point} value
1228
   * will be used as the return value, if possible.
1229
   *
1230
   * @param rv Return value object to reuse, if possible
1231
   *
1232
   * @return The component's current location
1233
   */
1234
  public Point getLocation(Point rv)
1235
  {
1236
    if (rv == null)
1237
      return new Point(getX(), getY());
1238
 
1239
    rv.setLocation(getX(), getY());
1240
    return rv;
1241
  }
1242
 
1243
  /**
1244
   * Get the component's maximum size. If the <code>maximumSize</code> property
1245
   * has been explicitly set, it is returned. If the <code>maximumSize</code>
1246
   * property has not been set but the {@link #ui} property has been, the
1247
   * result of {@link ComponentUI#getMaximumSize} is returned. If neither
1248
   * property has been set, the result of {@link Container#getMaximumSize}
1249
   * is returned.
1250
   *
1251
   * @return the maximum size of the component
1252
   *
1253
   * @see Component#setMaximumSize
1254
   * @see Component#getMaximumSize()
1255
   * @see Component#isMaximumSizeSet()
1256
   * @see ComponentUI#getMaximumSize(JComponent)
1257
   */
1258
  public Dimension getMaximumSize()
1259
  {
1260
    Dimension size = null;
1261
    if (isMaximumSizeSet())
1262
      size = super.getMaximumSize();
1263
    else
1264
      {
1265
        if (ui != null)
1266
          size = ui.getMaximumSize(this);
1267
        if (size == null)
1268
          size = super.getMaximumSize();
1269
      }
1270
    return size;
1271
  }
1272
 
1273
  /**
1274
   * Get the component's minimum size. If the <code>minimumSize</code> property
1275
   * has been explicitly set, it is returned. If the <code>minimumSize</code>
1276
   * property has not been set but the {@link #ui} property has been, the
1277
   * result of {@link ComponentUI#getMinimumSize} is returned. If neither
1278
   * property has been set, the result of {@link Container#getMinimumSize}
1279
   * is returned.
1280
   *
1281
   * @return The minimum size of the component
1282
   *
1283
   * @see Component#setMinimumSize
1284
   * @see Component#getMinimumSize()
1285
   * @see Component#isMinimumSizeSet()
1286
   * @see ComponentUI#getMinimumSize(JComponent)
1287
   */
1288
  public Dimension getMinimumSize()
1289
  {
1290
    Dimension size = null;
1291
    if (isMinimumSizeSet())
1292
      size = super.getMinimumSize();
1293
    else
1294
      {
1295
        if (ui != null)
1296
          size = ui.getMinimumSize(this);
1297
        if (size == null)
1298
          size = super.getMinimumSize();
1299
      }
1300
    return size;
1301
  }
1302
 
1303
  /**
1304
   * Get the component's preferred size. If the <code>preferredSize</code>
1305
   * property has been explicitly set, it is returned. If the
1306
   * <code>preferredSize</code> property has not been set but the {@link #ui}
1307
   * property has been, the result of {@link ComponentUI#getPreferredSize} is
1308
   * returned. If neither property has been set, the result of {@link
1309
   * Container#getPreferredSize} is returned.
1310
   *
1311
   * @return The preferred size of the component
1312
   *
1313
   * @see Component#setPreferredSize
1314
   * @see Component#getPreferredSize()
1315
   * @see Component#isPreferredSizeSet()
1316
   * @see ComponentUI#getPreferredSize(JComponent)
1317
   */
1318
  public Dimension getPreferredSize()
1319
  {
1320
    Dimension size = null;
1321
    if (isPreferredSizeSet())
1322
      size = super.getPreferredSize();
1323
    else
1324
      {
1325
        if (ui != null)
1326
          size = ui.getPreferredSize(this);
1327
        if (size == null)
1328
          size = super.getPreferredSize();
1329
      }
1330
    return size;
1331
  }
1332
 
1333
  /**
1334
   * Return the value of the <code>nextFocusableComponent</code> property.
1335
   *
1336
   * @return The current value of the property, or <code>null</code>
1337
   * if none has been set.
1338
   *
1339
   * @deprecated See {@link java.awt.FocusTraversalPolicy}
1340
   */
1341
  public Component getNextFocusableComponent()
1342
  {
1343
    Container focusRoot = this;
1344
    if (! this.isFocusCycleRoot())
1345
      focusRoot = getFocusCycleRootAncestor();
1346
 
1347
    FocusTraversalPolicy policy  = focusRoot.getFocusTraversalPolicy();
1348
    return policy.getComponentAfter(focusRoot, this);
1349
  }
1350
 
1351
  /**
1352
   * Return the set of {@link KeyStroke} objects which are registered
1353
   * to initiate actions on this component.
1354
   *
1355
   * @return An array of the registered keystrokes (possibly empty but never
1356
   *     <code>null</code>).
1357
   */
1358
  public KeyStroke[] getRegisteredKeyStrokes()
1359
  {
1360
    KeyStroke[] ks0;
1361
    KeyStroke[] ks1;
1362
    KeyStroke[] ks2;
1363
    if (inputMap_whenFocused != null)
1364
      ks0 = inputMap_whenFocused.keys();
1365
    else
1366
      ks0 = new KeyStroke[0];
1367
    if (inputMap_whenAncestorOfFocused != null)
1368
      ks1 = inputMap_whenAncestorOfFocused.keys();
1369
    else
1370
      ks1 = new KeyStroke[0];
1371
    if (inputMap_whenInFocusedWindow != null)
1372
      ks2 = inputMap_whenInFocusedWindow.keys();
1373
    else
1374
      ks2 = new KeyStroke[0];
1375
    int count = ks0.length + ks1.length + ks2.length;
1376
    KeyStroke[] result = new KeyStroke[count];
1377
    System.arraycopy(ks0, 0, result, 0, ks0.length);
1378
    System.arraycopy(ks1, 0, result, ks0.length, ks1.length);
1379
    System.arraycopy(ks2, 0, result, ks0.length + ks1.length, ks2.length);
1380
    return result;
1381
  }
1382
 
1383
  /**
1384
   * Returns the first ancestor of this component which is a {@link JRootPane}.
1385
   * Equivalent to calling <code>SwingUtilities.getRootPane(this);</code>.
1386
   *
1387
   * @return An ancestral JRootPane, or <code>null</code> if none exists.
1388
   */
1389
  public JRootPane getRootPane()
1390
  {
1391
    JRootPane p = SwingUtilities.getRootPane(this);
1392
    return p;
1393
  }
1394
 
1395
  /**
1396
   * Get the component's size. The passed-in {@link Dimension} value
1397
   * will be used as the return value, if possible.
1398
   *
1399
   * @param rv Return value object to reuse, if possible
1400
   *
1401
   * @return The component's current size
1402
   */
1403
  public Dimension getSize(Dimension rv)
1404
  {
1405
    if (rv == null)
1406
      return new Dimension(getWidth(), getHeight());
1407
    else
1408
      {
1409
        rv.setSize(getWidth(), getHeight());
1410
        return rv;
1411
      }
1412
  }
1413
 
1414
  /**
1415
   * Return the <code>toolTip</code> property of this component, creating it and
1416
   * setting it if it is currently <code>null</code>. This method can be
1417
   * overridden in subclasses which wish to control the exact form of
1418
   * tooltip created.
1419
   *
1420
   * @return The current toolTip
1421
   */
1422
  public JToolTip createToolTip()
1423
  {
1424
    JToolTip toolTip = new JToolTip();
1425
    toolTip.setComponent(this);
1426
    return toolTip;
1427
  }
1428
 
1429
  /**
1430
   * Return the location at which the <code>toolTipText</code> property should
1431
   * be displayed, when triggered by a particular mouse event.
1432
   *
1433
   * @param event The event the tooltip is being presented in response to
1434
   *
1435
   * @return The point at which to display a tooltip, or <code>null</code>
1436
   *     if swing is to choose a default location.
1437
   */
1438
  public Point getToolTipLocation(MouseEvent event)
1439
  {
1440
    return null;
1441
  }
1442
 
1443
  /**
1444
   * Set the tooltip text for this component. If a non-<code>null</code>
1445
   * value is set, this component is registered in the
1446
   * <code>ToolTipManager</code> in order to turn on tooltips for this
1447
   * component. If a <code>null</code> value is set, tooltips are turne off
1448
   * for this component.
1449
   *
1450
   * @param text the tooltip text for this component
1451
   *
1452
   * @see #getToolTipText()
1453
   * @see #getToolTipText(MouseEvent)
1454
   */
1455
  public void setToolTipText(String text)
1456
  {
1457
    String old = getToolTipText();
1458
    putClientProperty(TOOL_TIP_TEXT_KEY, text);
1459
    ToolTipManager ttm = ToolTipManager.sharedInstance();
1460
    if (text == null)
1461
      ttm.unregisterComponent(this);
1462
    else if (old == null)
1463
      ttm.registerComponent(this);
1464
  }
1465
 
1466
  /**
1467
   * Returns the current tooltip text for this component, or <code>null</code>
1468
   * if none has been set.
1469
   *
1470
   * @return the current tooltip text for this component, or <code>null</code>
1471
   *         if none has been set
1472
   *
1473
   * @see #setToolTipText
1474
   * @see #getToolTipText(MouseEvent)
1475
   */
1476
  public String getToolTipText()
1477
  {
1478
    return (String) getClientProperty(TOOL_TIP_TEXT_KEY);
1479
  }
1480
 
1481
  /**
1482
   * Returns the tooltip text for this component for a particular mouse
1483
   * event. This can be used to support context sensitive tooltips that can
1484
   * change with the mouse location. By default this returns the static
1485
   * tooltip text returned by {@link #getToolTipText()}.
1486
   *
1487
   * @param event the mouse event which triggered the tooltip
1488
   *
1489
   * @return the tooltip text for this component for a particular mouse
1490
   *         event
1491
   *
1492
   * @see #setToolTipText
1493
   * @see #getToolTipText()
1494
   */
1495
  public String getToolTipText(MouseEvent event)
1496
  {
1497
    return getToolTipText();
1498
  }
1499
 
1500
  /**
1501
   * Returns the flag that controls whether or not the component inherits its
1502
   * parent's popup menu when no popup menu is specified for this component.
1503
   *
1504
   * @return A boolean.
1505
   *
1506
   * @since 1.5
1507
   *
1508
   * @see #setInheritsPopupMenu(boolean)
1509
   */
1510
  public boolean getInheritsPopupMenu()
1511
  {
1512
    return inheritsPopupMenu;
1513
  }
1514
 
1515
  /**
1516
   * Sets the flag that controls whether or not the component inherits its
1517
   * parent's popup menu when no popup menu is specified for this component.
1518
   * This is a bound property with the property name 'inheritsPopupMenu'.
1519
   *
1520
   * @param inherit  the new flag value.
1521
   *
1522
   * @since 1.5
1523
   *
1524
   * @see #getInheritsPopupMenu()
1525
   */
1526
  public void setInheritsPopupMenu(boolean inherit)
1527
  {
1528
    if (inheritsPopupMenu != inherit)
1529
      {
1530
        inheritsPopupMenu = inherit;
1531
        this.firePropertyChange("inheritsPopupMenu", ! inherit, inherit);
1532
      }
1533
  }
1534
 
1535
  /**
1536
   * Returns the popup menu for this component.  If the popup menu is
1537
   * <code>null</code> AND the {@link #getInheritsPopupMenu()} method returns
1538
   * <code>true</code>, this method will return the parent's popup menu (if it
1539
   * has one).
1540
   *
1541
   * @return The popup menu (possibly <code>null</code>.
1542
   *
1543
   * @since 1.5
1544
   *
1545
   * @see #setComponentPopupMenu(JPopupMenu)
1546
   * @see #getInheritsPopupMenu()
1547
   */
1548
  public JPopupMenu getComponentPopupMenu()
1549
  {
1550
    if (componentPopupMenu == null && getInheritsPopupMenu())
1551
      {
1552
        Container parent = getParent();
1553
        if (parent instanceof JComponent)
1554
          return ((JComponent) parent).getComponentPopupMenu();
1555
        else
1556
          return null;
1557
      }
1558
    else
1559
      return componentPopupMenu;
1560
  }
1561
 
1562
  /**
1563
   * Sets the popup menu for this component (this is a bound property with
1564
   * the property name 'componentPopupMenu').
1565
   *
1566
   * @param popup  the popup menu (<code>null</code> permitted).
1567
   *
1568
   * @since 1.5
1569
   *
1570
   * @see #getComponentPopupMenu()
1571
   */
1572
  public void setComponentPopupMenu(JPopupMenu popup)
1573
  {
1574
    if (componentPopupMenu != popup)
1575
      {
1576
        JPopupMenu old = componentPopupMenu;
1577
        componentPopupMenu = popup;
1578
        firePropertyChange("componentPopupMenu", old, popup);
1579
      }
1580
  }
1581
 
1582
  /**
1583
   * Return the top level ancestral container (usually a {@link
1584
   * java.awt.Window} or {@link java.applet.Applet}) which this component is
1585
   * contained within, or <code>null</code> if no ancestors exist.
1586
   *
1587
   * @return The top level container, if it exists
1588
   */
1589
  public Container getTopLevelAncestor()
1590
  {
1591
    Container c = getParent();
1592
    for (Container peek = c; peek != null; peek = peek.getParent())
1593
      c = peek;
1594
    return c;
1595
  }
1596
 
1597
  /**
1598
   * Compute the component's visible rectangle, which is defined
1599
   * recursively as either the component's bounds, if it has no parent, or
1600
   * the intersection of the component's bounds with the visible rectangle
1601
   * of its parent.
1602
   *
1603
   * @param rect The return value slot to place the visible rectangle in
1604
   */
1605
  public void computeVisibleRect(Rectangle rect)
1606
  {
1607
    Component c = getParent();
1608
    if (c != null && c instanceof JComponent)
1609
      {
1610
        ((JComponent) c).computeVisibleRect(rect);
1611
        rect.translate(-getX(), -getY());
1612
        rect = SwingUtilities.computeIntersection(0, 0, getWidth(),
1613
                                                  getHeight(), rect);
1614
      }
1615
    else
1616
      rect.setRect(0, 0, getWidth(), getHeight());
1617
  }
1618
 
1619
  /**
1620
   * Return the component's visible rectangle in a new {@link Rectangle},
1621
   * rather than via a return slot.
1622
   *
1623
   * @return the component's visible rectangle
1624
   *
1625
   * @see #computeVisibleRect(Rectangle)
1626
   */
1627
  public Rectangle getVisibleRect()
1628
  {
1629
    Rectangle r = new Rectangle();
1630
    computeVisibleRect(r);
1631
    return r;
1632
  }
1633
 
1634
  /**
1635
   * <p>Requests that this component receive input focus, giving window
1636
   * focus to the top level ancestor of this component. Only works on
1637
   * displayable, focusable, visible components.</p>
1638
   *
1639
   * <p>This method should not be called by clients; it is intended for
1640
   * focus implementations. Use {@link Component#requestFocus()} instead.</p>
1641
   *
1642
   * @see Component#requestFocus()
1643
   */
1644
  public void grabFocus()
1645
  {
1646
    requestFocus();
1647
  }
1648
 
1649
  /**
1650
   * Get the value of the {@link #doubleBuffered} property.
1651
   *
1652
   * @return The property's current value
1653
   */
1654
  public boolean isDoubleBuffered()
1655
  {
1656
    return doubleBuffered;
1657
  }
1658
 
1659
  /**
1660
   * Return <code>true</code> if the provided component has no native peer;
1661
   * in other words, if it is a "lightweight component".
1662
   *
1663
   * @param c The component to test for lightweight-ness
1664
   *
1665
   * @return Whether or not the component is lightweight
1666
   */
1667
  public static boolean isLightweightComponent(Component c)
1668
  {
1669
    return c.getPeer() instanceof LightweightPeer;
1670
  }
1671
 
1672
  /**
1673
   * Return <code>true</code> if you wish this component to manage its own
1674
   * focus. In particular: if you want this component to be sent
1675
   * <code>TAB</code> and <code>SHIFT+TAB</code> key events, and to not
1676
   * have its children considered as focus transfer targets. If
1677
   * <code>true</code>, focus traversal around this component changes to
1678
   * <code>CTRL+TAB</code> and <code>CTRL+SHIFT+TAB</code>.
1679
   *
1680
   * @return <code>true</code> if you want this component to manage its own
1681
   *     focus, otherwise (by default) <code>false</code>
1682
   *
1683
   * @deprecated 1.4 Use {@link Component#setFocusTraversalKeys(int, Set)} and
1684
   *     {@link Container#setFocusCycleRoot(boolean)} instead
1685
   */
1686
  public boolean isManagingFocus()
1687
  {
1688
    return false;
1689
  }
1690
 
1691
  /**
1692
   * Return the current value of the {@link #opaque} property.
1693
   *
1694
   * @return The current property value
1695
   */
1696
  public boolean isOpaque()
1697
  {
1698
    return opaque;
1699
  }
1700
 
1701
  /**
1702
   * Return <code>true</code> if the component can guarantee that none of its
1703
   * children will overlap in Z-order. This is a hint to the painting system.
1704
   * The default is to return <code>true</code>, but some components such as
1705
   * {@link JLayeredPane} should override this to return <code>false</code>.
1706
   *
1707
   * @return Whether the component tiles its children
1708
   */
1709
  public boolean isOptimizedDrawingEnabled()
1710
  {
1711
    return true;
1712
  }
1713
 
1714
  /**
1715
   * Return <code>true</code> if this component is currently painting a tile,
1716
   * this means that paint() is called again on another child component. This
1717
   * method returns <code>false</code> if this component does not paint a tile
1718
   * or if the last tile is currently painted.
1719
   *
1720
   * @return whether the component is painting a tile
1721
   */
1722
  public boolean isPaintingTile()
1723
  {
1724
    return paintingTile;
1725
  }
1726
 
1727
  /**
1728
   * Get the value of the {@link #requestFocusEnabled} property.
1729
   *
1730
   * @return The current value of the property
1731
   */
1732
  public boolean isRequestFocusEnabled()
1733
  {
1734
    return requestFocusEnabled;
1735
  }
1736
 
1737
  /**
1738
   * Return <code>true</code> if this component is a validation root; this
1739
   * will cause calls to {@link #invalidate()} in this component's children
1740
   * to be "captured" at this component, and not propagate to its parents.
1741
   * For most components this should return <code>false</code>, but some
1742
   * components such as {@link JViewport} will want to return
1743
   * <code>true</code>.
1744
   *
1745
   * @return Whether this component is a validation root
1746
   */
1747
  public boolean isValidateRoot()
1748
  {
1749
    return false;
1750
  }
1751
 
1752
  /**
1753
   * <p>Paint the component. This is a delicate process, and should only be
1754
   * called from the repaint thread, under control of the {@link
1755
   * RepaintManager}. Client code should usually call {@link #repaint()} to
1756
   * trigger painting.</p>
1757
   *
1758
   * <p>The body of the <code>paint</code> call involves calling {@link
1759
   * #paintComponent}, {@link #paintBorder}, and {@link #paintChildren} in
1760
   * order. If you want to customize painting behavior, you should override
1761
   * one of these methods rather than <code>paint</code>.</p>
1762
   *
1763
   * <p>For more details on the painting sequence, see <a
1764
   * href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">
1765
   * this article</a>.</p>
1766
   *
1767
   * @param g The graphics context to paint with
1768
   *
1769
   * @see #paintImmediately(Rectangle)
1770
   */
1771
  public void paint(Graphics g)
1772
  {
1773
    RepaintManager rm = RepaintManager.currentManager(this);
1774
    // We do a little stunt act here to switch on double buffering if it's
1775
    // not already on. If we are not already doublebuffered, then we jump
1776
    // into the method paintDoubleBuffered, which turns on the double buffer
1777
    // and then calls paint(g) again. In the second call we go into the else
1778
    // branch of this if statement and actually paint things to the double
1779
    // buffer. When this method completes, the call stack unwinds back to
1780
    // paintDoubleBuffered, where the buffer contents is finally drawn to the
1781
    // screen.
1782
    if (!paintingDoubleBuffered && isDoubleBuffered()
1783
        && rm.isDoubleBufferingEnabled())
1784
      {
1785
        Rectangle clip = g.getClipBounds();
1786
        paintDoubleBuffered(clip.x, clip.y, clip.width, clip.height);
1787
      }
1788
    else
1789
      {
1790
        if (getClientProperty("bufferedDragging") != null
1791
            && dragBuffer == null)
1792
          {
1793
            initializeDragBuffer();
1794
          }
1795
        else if (getClientProperty("bufferedDragging") == null
1796
            && dragBuffer != null)
1797
          {
1798
            dragBuffer = null;
1799
          }
1800
 
1801
        Rectangle clip = g.getClipBounds();
1802
        int clipX, clipY, clipW, clipH;
1803
        if (clip == null)
1804
          {
1805
            clipX = 0;
1806
            clipY = 0;
1807
            clipW = getWidth();
1808
            clipH = getHeight();
1809
          }
1810
        else
1811
          {
1812
            clipX = clip.x;
1813
            clipY = clip.y;
1814
            clipW = clip.width;
1815
            clipH = clip.height;
1816
          }
1817
        if (dragBuffer != null && dragBufferInitialized)
1818
          {
1819
            g.drawImage(dragBuffer, 0, 0, this);
1820
          }
1821
        else
1822
          {
1823
            Graphics g2 = getComponentGraphics(g);
1824
            if (! isOccupiedByChild(clipX, clipY, clipW, clipH))
1825
              {
1826
                paintComponent(g2);
1827
                paintBorder(g2);
1828
              }
1829
            paintChildren(g2);
1830
          }
1831
      }
1832
  }
1833
 
1834
  /**
1835
   * Determines if a region of this component is completely occupied by
1836
   * an opaque child component, in which case we don't need to bother
1837
   * painting this component at all.
1838
   *
1839
   * @param x the area, x coordinate
1840
   * @param y the area, y coordinate
1841
   * @param w the area, width
1842
   * @param h the area, height
1843
   *
1844
   * @return <code>true</code> if the specified area is completely covered
1845
   *         by a child component, <code>false</code> otherwise
1846
   */
1847
  private boolean isOccupiedByChild(int x, int y, int w, int h)
1848
  {
1849
    boolean occupied = false;
1850
    int count = getComponentCount();
1851
    for (int i = 0; i < count; i++)
1852
      {
1853
        Component child = getComponent(i);
1854
        int cx = child.getX();
1855
        int cy = child.getY();
1856
        int cw = child.getWidth();
1857
        int ch = child.getHeight();
1858
        if (child.isVisible() && x >= cx && x + w <= cx + cw && y >= cy
1859
            && y + h <= cy + ch)
1860
          {
1861
            occupied = child.isOpaque();
1862
            break;
1863
          }
1864
      }
1865
    return occupied;
1866
  }
1867
 
1868
  /**
1869
   * Initializes the drag buffer by creating a new image and painting this
1870
   * component into it.
1871
   */
1872
  private void initializeDragBuffer()
1873
  {
1874
    dragBufferInitialized = false;
1875
    // Allocate new dragBuffer if the current one is too small.
1876
    if (dragBuffer == null || dragBuffer.getWidth(this) < getWidth()
1877
        || dragBuffer.getHeight(this) < getHeight())
1878
      {
1879
        dragBuffer = createImage(getWidth(), getHeight());
1880
      }
1881
    Graphics g = dragBuffer.getGraphics();
1882
    paint(g);
1883
    g.dispose();
1884
    dragBufferInitialized = true;
1885
  }
1886
 
1887
  /**
1888
   * Paint the component's border. This usually means calling {@link
1889
   * Border#paintBorder} on the {@link #border} property, if it is
1890
   * non-<code>null</code>. You may override this if you wish to customize
1891
   * border painting behavior. The border is painted after the component's
1892
   * body, but before the component's children.
1893
   *
1894
   * @param g The graphics context with which to paint the border
1895
   *
1896
   * @see #paint
1897
   * @see #paintChildren
1898
   * @see #paintComponent
1899
   */
1900
  protected void paintBorder(Graphics g)
1901
  {
1902
    if (getBorder() != null)
1903
      getBorder().paintBorder(this, g, 0, 0, getWidth(), getHeight());
1904
  }
1905
 
1906
  /**
1907
   * Paint the component's children. This usually means calling {@link
1908
   * Container#paint}, which recursively calls {@link #paint} on any of the
1909
   * component's children, with appropriate changes to coordinate space and
1910
   * clipping region. You may override this if you wish to customize
1911
   * children painting behavior. The children are painted after the
1912
   * component's body and border.
1913
   *
1914
   * @param g The graphics context with which to paint the children
1915
   *
1916
   * @see #paint
1917
   * @see #paintBorder
1918
   * @see #paintComponent
1919
   */
1920
  protected void paintChildren(Graphics g)
1921
  {
1922
    if (getComponentCount() > 0)
1923
      {
1924
        // Need to lock the tree to avoid problems with AWT and concurrency.
1925
        synchronized (getTreeLock())
1926
          {
1927
            // Fast forward to the child to paint, if set by
1928
            // paintImmediately2()
1929
            int i = getComponentCount() - 1;
1930
            if (paintChild != null && paintChild.isOpaque())
1931
              {
1932
                for (; i >= 0 && getComponent(i) != paintChild; i--)
1933
                  ;
1934
              }
1935
            for (; i >= 0; i--)
1936
              {
1937
                Component child = getComponent(i);
1938
                if (child != null && child.isLightweight()
1939
                    && child.isVisible())
1940
                  {
1941
                    int cx = child.getX();
1942
                    int cy = child.getY();
1943
                    int cw = child.getWidth();
1944
                    int ch = child.getHeight();
1945
                    if (g.hitClip(cx, cy, cw, ch))
1946
                      {
1947
                        if ((! isOptimizedDrawingEnabled()) && i > 0)
1948
                          {
1949
                            // Check if the child is completely obscured.
1950
                            Rectangle clip = g.getClipBounds(); // A copy.
1951
                            SwingUtilities.computeIntersection(cx, cy, cw, ch,
1952
                                                               clip);
1953
                            if (isCompletelyObscured(i, clip.x, clip.y,
1954
                                                     clip.width, clip.height))
1955
                              continue; // Continues the for-loop.
1956
                          }
1957
                        Graphics cg = g.create(cx, cy, cw, ch);
1958
                        cg.setColor(child.getForeground());
1959
                        cg.setFont(child.getFont());
1960
                        try
1961
                          {
1962
                            child.paint(cg);
1963
                          }
1964
                        finally
1965
                          {
1966
                            cg.dispose();
1967
                          }
1968
                      }
1969
                  }
1970
              }
1971
          }
1972
      }
1973
  }
1974
 
1975
  /**
1976
   * Determines if a region of a child component is completely obscured by one
1977
   * of its siblings.
1978
   *
1979
   * @param index the index of the child component
1980
   * @param x the region to check, x coordinate
1981
   * @param y the region to check, y coordinate
1982
   * @param w the region to check, width
1983
   * @param h the region to check, height
1984
   *
1985
   * @return <code>true</code> if the region is completely obscured by a
1986
   *         sibling, <code>false</code> otherwise
1987
   */
1988
  private boolean isCompletelyObscured(int index, int x, int y, int w, int h)
1989
  {
1990
    boolean obscured = false;
1991
    for (int i = index - 1; i >= 0 && obscured == false; i--)
1992
      {
1993
        Component sib = getComponent(i);
1994
        if (sib.isVisible())
1995
          {
1996
            Rectangle sibRect = sib.getBounds(rectCache);
1997
            if (sib.isOpaque() && x >= sibRect.x
1998
                && (x + w) <= (sibRect.x + sibRect.width)
1999
                && y >= sibRect.y
2000
                && (y + h) <= (sibRect.y + sibRect.height))
2001
              {
2002
                obscured = true;
2003
              }
2004
          }
2005
      }
2006
    return obscured;
2007
  }
2008
 
2009
  /**
2010
   * Checks if a component/rectangle is partially obscured by one of its
2011
   * siblings.
2012
   * Note that this doesn't check for completely obscured, this is
2013
   * done by isCompletelyObscured() and should probably also be checked.
2014
   *
2015
   * @param i the component index from which to start searching
2016
   * @param x the x coordinate of the rectangle to check
2017
   * @param y the y coordinate of the rectangle to check
2018
   * @param w the width of the rectangle to check
2019
   * @param h the height of the rectangle to check
2020
   *
2021
   * @return <code>true</code> if the rectangle is partially obscured
2022
   */
2023
  private boolean isPartiallyObscured(int i, int x, int y, int w, int h)
2024
  {
2025
    boolean obscured = false;
2026
    for (int j = i - 1; j >= 0 && ! obscured; j--)
2027
      {
2028
        Component sibl = getComponent(j);
2029
        if (sibl.isVisible())
2030
          {
2031
            Rectangle rect = sibl.getBounds(rectCache);
2032
            if (!(x + w <= rect.x)
2033
                  || (y + h <= rect.y)
2034
                  || (x >= rect.x + rect.width)
2035
                  || (y >= rect.y + rect.height))
2036
              obscured = true;
2037
          }
2038
      }
2039
    return obscured;
2040
  }
2041
 
2042
  /**
2043
   * Paint the component's body. This usually means calling {@link
2044
   * ComponentUI#update} on the {@link #ui} property of the component, if
2045
   * it is non-<code>null</code>. You may override this if you wish to
2046
   * customize the component's body-painting behavior. The component's body
2047
   * is painted first, before the border and children.
2048
   *
2049
   * @param g The graphics context with which to paint the body
2050
   *
2051
   * @see #paint
2052
   * @see #paintBorder
2053
   * @see #paintChildren
2054
   */
2055
  protected void paintComponent(Graphics g)
2056
  {
2057
    if (ui != null)
2058
      {
2059
        Graphics g2 = g.create();
2060
        try
2061
          {
2062
            ui.update(g2, this);
2063
          }
2064
        finally
2065
          {
2066
            g2.dispose();
2067
          }
2068
      }
2069
  }
2070
 
2071
  /**
2072
   * A variant of {@link #paintImmediately(Rectangle)} which takes
2073
   * integer parameters.
2074
   *
2075
   * @param x The left x coordinate of the dirty region
2076
   * @param y The top y coordinate of the dirty region
2077
   * @param w The width of the dirty region
2078
   * @param h The height of the dirty region
2079
   */
2080
  public void paintImmediately(int x, int y, int w, int h)
2081
  {
2082
    // Find opaque parent and call paintImmediately2() on it.
2083
    if (isShowing())
2084
      {
2085
        Component c = this;
2086
        Component p;
2087
        while (c != null && ! c.isOpaque())
2088
          {
2089
            p = c.getParent();
2090
            if (p != null)
2091
              {
2092
                x += c.getX();
2093
                y += c.getY();
2094
                c = p;
2095
              }
2096
          }
2097
        if (c instanceof JComponent)
2098
          ((JComponent) c).paintImmediately2(x, y, w, h);
2099
        else
2100
          c.repaint(x, y, w, h);
2101
      }
2102
  }
2103
 
2104
  /**
2105
   * Transform the provided dirty rectangle for this component into the
2106
   * appropriate ancestral {@link JRootPane} and call {@link #paint} on
2107
   * that root pane. This method is called from the {@link RepaintManager}
2108
   * and should always be called within the painting thread.
2109
   *
2110
   * <p>This method will acquire a double buffer from the {@link
2111
   * RepaintManager} if the component's {@link #doubleBuffered} property is
2112
   * <code>true</code> and the <code>paint</code> call is the
2113
   * <em>first</em> recursive <code>paint</code> call inside swing.</p>
2114
   *
2115
   * <p>The method will also modify the provided {@link Graphics} context
2116
   * via the {@link #getComponentGraphics} method. If you want to customize
2117
   * the graphics object used for painting, you should override that method
2118
   * rather than <code>paint</code>.</p>
2119
   *
2120
   * @param r The dirty rectangle to paint
2121
   */
2122
  public void paintImmediately(Rectangle r)
2123
  {
2124
    paintImmediately(r.x, r.y, r.width, r.height);
2125
  }
2126
 
2127
  /**
2128
   * Performs the actual work of paintImmediatly on the repaint root.
2129
   *
2130
   * @param x the area to be repainted, X coordinate
2131
   * @param y the area to be repainted, Y coordinate
2132
   */
2133
  void paintImmediately2(int x, int y, int w, int h)
2134
  {
2135
    // Optimization for components that are always painted on top.
2136
    boolean onTop = onTop() && isOpaque();
2137
 
2138
    // Fetch the RepaintManager.
2139
    RepaintManager rm = RepaintManager.currentManager(this);
2140
 
2141
    // The painting clip;
2142
    int paintX = x;
2143
    int paintY = y;
2144
    int paintW = w;
2145
    int paintH = h;
2146
 
2147
    // If we should paint buffered or not.
2148
    boolean haveBuffer = false;
2149
 
2150
    // The component that is finally triggered for painting.
2151
    JComponent paintRoot = this;
2152
 
2153
    // Stores the component and all its parents. This will be used to limit
2154
    // the actually painted components in paintChildren by setting
2155
    // the field paintChild.
2156
    int pIndex = -1;
2157
    int pCount = 0;
2158
    ArrayList components = new ArrayList();
2159
 
2160
    // Offset to subtract from the paintRoot rectangle when painting.
2161
    int offsX = 0;
2162
    int offsY = 0;
2163
 
2164
    // The current component and its child.
2165
    Component child;
2166
    Container c;
2167
 
2168
    // Find appropriate paint root.
2169
    for (c = this, child = null;
2170
         c != null && ! (c instanceof Window) && ! (c instanceof Applet);
2171
         child = c, c = c.getParent())
2172
      {
2173
        JComponent jc = c instanceof JComponent ? (JComponent) c : null;
2174
        components.add(c);
2175
        if (! onTop && jc != null  && ! jc.isOptimizedDrawingEnabled())
2176
          {
2177
            // Indicates whether we reset the paint root to be the current
2178
            // component.
2179
            boolean updatePaintRoot = false;
2180
 
2181
            // Check obscured state of the child.
2182
            // Generally, we have 3 cases here:
2183
            // 1. Not obscured. No need to paint from the parent.
2184
            // 2. Partially obscured. Paint from the parent.
2185
            // 3. Completely obscured. No need to paint anything.
2186
            if (c != this)
2187
              {
2188
                if (jc.isPaintRoot())
2189
                  updatePaintRoot = true;
2190
                else
2191
                  {
2192
                    int count = c.getComponentCount();
2193
                    int i = 0;
2194
                    for (; i < count && c.getComponent(i) != child; i++)
2195
                      ;
2196
 
2197
                    if (jc.isCompletelyObscured(i, paintX, paintY, paintW,
2198
                                                paintH))
2199
                      return; // No need to paint anything.
2200
                    else if (jc.isPartiallyObscured(i, paintX, paintY, paintW,
2201
                                                    paintH))
2202
                      updatePaintRoot = true;
2203
 
2204
                  }
2205
              }
2206
            if (updatePaintRoot)
2207
              {
2208
                // Paint from parent.
2209
                paintRoot = jc;
2210
                pIndex = pCount;
2211
                offsX = 0;
2212
                offsY = 0;
2213
                haveBuffer = false;
2214
              }
2215
          }
2216
        pCount++;
2217
        // Check if component is double buffered.
2218
        if (rm.isDoubleBufferingEnabled() && jc != null
2219
            && jc.isDoubleBuffered())
2220
          {
2221
            haveBuffer = true;
2222
          }
2223
 
2224
        // Clip the paint region with the parent.
2225
        if (! onTop)
2226
          {
2227
            paintX = Math.max(0, paintX);
2228
            paintY = Math.max(0, paintY);
2229
            paintW = Math.min(c.getWidth(), paintW + paintX) - paintX;
2230
            paintH = Math.min(c.getHeight(), paintH + paintY) - paintY;
2231
            int dx = c.getX();
2232
            int dy = c.getY();
2233
            paintX += dx;
2234
            paintY += dy;
2235
            offsX += dx;
2236
            offsY += dy;
2237
          }
2238
      }
2239
    if (c != null && c.getPeer() != null && paintW > 0 && paintH > 0)
2240
      {
2241
        isRepainting = true;
2242
        paintX -= offsX;
2243
        paintY -= offsY;
2244
 
2245
        // Set the painting path so that paintChildren paints only what we
2246
        // want.
2247
        if (paintRoot != this)
2248
          {
2249
            for (int i = pIndex; i > 0; i--)
2250
              {
2251
                Component paintParent = (Component) components.get(i);
2252
                if (paintParent instanceof JComponent)
2253
                  ((JComponent) paintParent).paintChild =
2254
                    (Component) components.get(i - 1);
2255
              }
2256
          }
2257
 
2258
        // Actually trigger painting.
2259
        if (haveBuffer)
2260
          paintRoot.paintDoubleBuffered(paintX, paintY, paintW, paintH);
2261
        else
2262
          {
2263
            Graphics g = paintRoot.getGraphics();
2264
            try
2265
              {
2266
                g.setClip(paintX, paintY, paintW, paintH);
2267
                paintRoot.paint(g);
2268
              }
2269
            finally
2270
              {
2271
                g.dispose();
2272
              }
2273
          }
2274
 
2275
        // Reset the painting path.
2276
        if (paintRoot != this)
2277
          {
2278
            for (int i = pIndex; i > 0; i--)
2279
              {
2280
                Component paintParent = (Component) components.get(i);
2281
                if (paintParent instanceof JComponent)
2282
                  ((JComponent) paintParent).paintChild = null;
2283
              }
2284
          }
2285
 
2286
        isRepainting = false;
2287
      }
2288
  }
2289
 
2290
  /**
2291
   * Returns <code>true</code> if the component is guaranteed to be painted
2292
   * on top of others. This returns false by default and is overridden by
2293
   * components like JMenuItem, JPopupMenu and JToolTip to return true for
2294
   * added efficiency.
2295
   *
2296
   * @return <code>true</code> if the component is guaranteed to be painted
2297
   *         on top of others
2298
   */
2299
  boolean onTop()
2300
  {
2301
    return false;
2302
  }
2303
 
2304
  /**
2305
   * This returns true when a component needs to force itself as a paint
2306
   * origin. This is used for example in JViewport to make sure that it
2307
   * gets to update its backbuffer.
2308
   *
2309
   * @return true when a component needs to force itself as a paint
2310
   *         origin
2311
   */
2312
  boolean isPaintRoot()
2313
  {
2314
    return false;
2315
  }
2316
 
2317
  /**
2318
   * Performs double buffered repainting.
2319
   */
2320
  private void paintDoubleBuffered(int x, int y, int w, int h)
2321
  {
2322
    RepaintManager rm = RepaintManager.currentManager(this);
2323
 
2324
    // Paint on the offscreen buffer.
2325
    Component root = SwingUtilities.getRoot(this);
2326
    Image buffer = rm.getVolatileOffscreenBuffer(this, root.getWidth(),
2327
                                                 root.getHeight());
2328
 
2329
    // The volatile offscreen buffer may be null when that's not supported
2330
    // by the AWT backend. Fall back to normal backbuffer in this case.
2331
    if (buffer == null)
2332
      buffer = rm.getOffscreenBuffer(this, root.getWidth(), root.getHeight());
2333
 
2334
    //Rectangle targetClip = SwingUtilities.convertRectangle(this, r, root);
2335
    Graphics g2 = buffer.getGraphics();
2336
    clipAndTranslateGraphics(root, this, g2);
2337
    g2.clipRect(x, y, w, h);
2338
    g2 = getComponentGraphics(g2);
2339
    paintingDoubleBuffered = true;
2340
    try
2341
      {
2342
        if (isRepainting) // Called from paintImmediately, go through paint().
2343
          paint(g2);
2344
        else // Called from paint() (AWT refresh), don't call it again.
2345
          {
2346
            paintComponent(g2);
2347
            paintBorder(g2);
2348
            paintChildren(g2);
2349
          }
2350
      }
2351
    finally
2352
      {
2353
        paintingDoubleBuffered = false;
2354
        g2.dispose();
2355
      }
2356
 
2357
    // Paint the buffer contents on screen.
2358
    rm.commitBuffer(this, x, y, w, h);
2359
  }
2360
 
2361
  /**
2362
   * Clips and translates the Graphics instance for painting on the double
2363
   * buffer. This has to be done, so that it reflects the component clip of the
2364
   * target component.
2365
   *
2366
   * @param root the root component (top-level container usually)
2367
   * @param target the component to be painted
2368
   * @param g the Graphics instance
2369
   */
2370
  private void clipAndTranslateGraphics(Component root, Component target,
2371
                                        Graphics g)
2372
  {
2373
    Component parent = target;
2374
    int deltaX = 0;
2375
    int deltaY = 0;
2376
    while (parent != root)
2377
      {
2378
        deltaX += parent.getX();
2379
        deltaY += parent.getY();
2380
        parent = parent.getParent();
2381
      }
2382
    g.translate(deltaX, deltaY);
2383
    g.clipRect(0, 0, target.getWidth(), target.getHeight());
2384
  }
2385
 
2386
  /**
2387
   * Performs normal painting without double buffering.
2388
   *
2389
   * @param r the area that should be repainted
2390
   */
2391
  void paintSimple(Rectangle r)
2392
  {
2393
    Graphics g = getGraphics();
2394
    Graphics g2 = getComponentGraphics(g);
2395
    g2.setClip(r);
2396
    paint(g2);
2397
    g2.dispose();
2398
    if (g != g2)
2399
      g.dispose();
2400
  }
2401
 
2402
  /**
2403
   * Return a string representation for this component, for use in
2404
   * debugging.
2405
   *
2406
   * @return A string describing this component.
2407
   */
2408
  protected String paramString()
2409
  {
2410
    CPStringBuilder sb = new CPStringBuilder();
2411
    sb.append(super.paramString());
2412
    sb.append(",alignmentX=").append(getAlignmentX());
2413
    sb.append(",alignmentY=").append(getAlignmentY());
2414
    sb.append(",border=");
2415
    if (getBorder() != null)
2416
      sb.append(getBorder());
2417
    sb.append(",maximumSize=");
2418
    if (getMaximumSize() != null)
2419
      sb.append(getMaximumSize());
2420
    sb.append(",minimumSize=");
2421
    if (getMinimumSize() != null)
2422
      sb.append(getMinimumSize());
2423
    sb.append(",preferredSize=");
2424
    if (getPreferredSize() != null)
2425
      sb.append(getPreferredSize());
2426
    return sb.toString();
2427
  }
2428
 
2429
  /**
2430
   * A variant of {@link
2431
   * #registerKeyboardAction(ActionListener,String,KeyStroke,int)} which
2432
   * provides <code>null</code> for the command name.
2433
   *
2434
   * @param act  the action listener to notify when the keystroke occurs.
2435
   * @param stroke  the key stroke.
2436
   * @param cond  the condition (one of {@link #WHEN_FOCUSED},
2437
   *     {@link #WHEN_IN_FOCUSED_WINDOW} and
2438
   *     {@link #WHEN_ANCESTOR_OF_FOCUSED_COMPONENT}).
2439
   */
2440
  public void registerKeyboardAction(ActionListener act,
2441
                                     KeyStroke stroke,
2442
                                     int cond)
2443
  {
2444
    registerKeyboardAction(act, null, stroke, cond);
2445
  }
2446
 
2447
  /*
2448
   * There is some charmingly undocumented behavior sun seems to be using
2449
   * to simulate the old register/unregister keyboard binding API. It's not
2450
   * clear to me why this matters, but we shall endeavour to follow suit.
2451
   *
2452
   * Two main thing seem to be happening when you do registerKeyboardAction():
2453
   *
2454
   *  - no actionMap() entry gets created, just an entry in inputMap()
2455
   *
2456
   *  - the inputMap() entry is a proxy class which invokes the the
2457
   *  binding's actionListener as a target, and which clobbers the command
2458
   *  name sent in the ActionEvent, providing the binding command name
2459
   *  instead.
2460
   *
2461
   * This much you can work out just by asking the input and action maps
2462
   * what they contain after making bindings, and watching the event which
2463
   * gets delivered to the recipient. Beyond that, it seems to be a
2464
   * sun-private solution so I will only immitate it as much as it matters
2465
   * to external observers.
2466
   */
2467
  private static class ActionListenerProxy
2468
    extends AbstractAction
2469
  {
2470
    ActionListener target;
2471
    String bindingCommandName;
2472
 
2473
    public ActionListenerProxy(ActionListener li,
2474
                               String cmd)
2475
    {
2476
      target = li;
2477
      bindingCommandName = cmd;
2478
    }
2479
 
2480
    public void actionPerformed(ActionEvent e)
2481
    {
2482
      ActionEvent derivedEvent = new ActionEvent(e.getSource(),
2483
                                                 e.getID(),
2484
                                                 bindingCommandName,
2485
                                                 e.getModifiers());
2486
      target.actionPerformed(derivedEvent);
2487
    }
2488
  }
2489
 
2490
 
2491
  /**
2492
   * An obsolete method to register a keyboard action on this component.
2493
   * You should use <code>getInputMap</code> and <code>getActionMap</code>
2494
   * to fetch mapping tables from keystrokes to commands, and commands to
2495
   * actions, respectively, and modify those mappings directly.
2496
   *
2497
   * @param act The action to be registered
2498
   * @param cmd The command to deliver in the delivered {@link
2499
   *     java.awt.event.ActionEvent}
2500
   * @param stroke The keystroke to register on
2501
   * @param cond One of the values {@link #UNDEFINED_CONDITION},
2502
   *     {@link #WHEN_ANCESTOR_OF_FOCUSED_COMPONENT}, {@link #WHEN_FOCUSED}, or
2503
   *     {@link #WHEN_IN_FOCUSED_WINDOW}, indicating the condition which must
2504
   *     be met for the action to be fired
2505
   *
2506
   * @see #unregisterKeyboardAction
2507
   * @see #getConditionForKeyStroke
2508
   * @see #resetKeyboardActions
2509
   */
2510
  public void registerKeyboardAction(ActionListener act,
2511
                                     String cmd,
2512
                                     KeyStroke stroke,
2513
                                     int cond)
2514
  {
2515
    ActionListenerProxy proxy = new ActionListenerProxy(act, cmd);
2516
    getInputMap(cond).put(stroke, proxy);
2517
    getActionMap().put(proxy, proxy);
2518
  }
2519
 
2520
  /**
2521
   * Sets the input map for the given condition.
2522
   *
2523
   * @param condition  the condition (one of {@link #WHEN_FOCUSED},
2524
   *     {@link #WHEN_IN_FOCUSED_WINDOW} and
2525
   *     {@link #WHEN_ANCESTOR_OF_FOCUSED_COMPONENT}).
2526
   * @param map  the map.
2527
   *
2528
   * @throws IllegalArgumentException if <code>condition</code> is not one of
2529
   *     the specified values.
2530
   */
2531
  public final void setInputMap(int condition, InputMap map)
2532
  {
2533
    enableEvents(AWTEvent.KEY_EVENT_MASK);
2534
    switch (condition)
2535
      {
2536
      case WHEN_FOCUSED:
2537
        inputMap_whenFocused = map;
2538
        break;
2539
 
2540
      case WHEN_ANCESTOR_OF_FOCUSED_COMPONENT:
2541
        inputMap_whenAncestorOfFocused = map;
2542
        break;
2543
 
2544
      case WHEN_IN_FOCUSED_WINDOW:
2545
        if (map != null && !(map instanceof ComponentInputMap))
2546
            throw new
2547
              IllegalArgumentException("WHEN_IN_FOCUSED_WINDOW " +
2548
                                       "InputMap must be a ComponentInputMap");
2549
        inputMap_whenInFocusedWindow = (ComponentInputMap)map;
2550
        break;
2551
 
2552
      case UNDEFINED_CONDITION:
2553
      default:
2554
        throw new IllegalArgumentException();
2555
      }
2556
  }
2557
 
2558
  /**
2559
   * Returns the input map associated with this component for the given
2560
   * state/condition.
2561
   *
2562
   * @param condition  the state (one of {@link #WHEN_FOCUSED},
2563
   *     {@link #WHEN_ANCESTOR_OF_FOCUSED_COMPONENT} and
2564
   *     {@link #WHEN_IN_FOCUSED_WINDOW}).
2565
   *
2566
   * @return The input map.
2567
   * @throws IllegalArgumentException if <code>condition</code> is not one of
2568
   *             the specified values.
2569
   * @since 1.3
2570
   */
2571
  public final InputMap getInputMap(int condition)
2572
  {
2573
    enableEvents(AWTEvent.KEY_EVENT_MASK);
2574
    switch (condition)
2575
      {
2576
      case WHEN_FOCUSED:
2577
        if (inputMap_whenFocused == null)
2578
          inputMap_whenFocused = new InputMap();
2579
        return inputMap_whenFocused;
2580
 
2581
      case WHEN_ANCESTOR_OF_FOCUSED_COMPONENT:
2582
        if (inputMap_whenAncestorOfFocused == null)
2583
          inputMap_whenAncestorOfFocused = new InputMap();
2584
        return inputMap_whenAncestorOfFocused;
2585
 
2586
      case WHEN_IN_FOCUSED_WINDOW:
2587
        if (inputMap_whenInFocusedWindow == null)
2588
          inputMap_whenInFocusedWindow = new ComponentInputMap(this);
2589
        return inputMap_whenInFocusedWindow;
2590
 
2591
      case UNDEFINED_CONDITION:
2592
      default:
2593
        throw new IllegalArgumentException("Invalid 'condition' argument: "
2594
                                           + condition);
2595
      }
2596
  }
2597
 
2598
  /**
2599
   * Returns the input map associated with this component for the
2600
   * {@link #WHEN_FOCUSED} state.
2601
   *
2602
   * @return The input map.
2603
   *
2604
   * @since 1.3
2605
   * @see #getInputMap(int)
2606
   */
2607
  public final InputMap getInputMap()
2608
  {
2609
    return getInputMap(WHEN_FOCUSED);
2610
  }
2611
 
2612
  public final ActionMap getActionMap()
2613
  {
2614
    if (actionMap == null)
2615
      actionMap = new ActionMap();
2616
    return actionMap;
2617
  }
2618
 
2619
  public final void setActionMap(ActionMap map)
2620
  {
2621
    actionMap = map;
2622
  }
2623
 
2624
  /**
2625
   * Return the condition that determines whether a registered action
2626
   * occurs in response to the specified keystroke.
2627
   *
2628
   * As of 1.3 KeyStrokes can be registered with multiple simultaneous
2629
   * conditions.
2630
   *
2631
   * @param ks The keystroke to return the condition of
2632
   *
2633
   * @return One of the values {@link #UNDEFINED_CONDITION}, {@link
2634
   *     #WHEN_ANCESTOR_OF_FOCUSED_COMPONENT}, {@link #WHEN_FOCUSED}, or {@link
2635
   *     #WHEN_IN_FOCUSED_WINDOW}
2636
   *
2637
   * @see #registerKeyboardAction(ActionListener, KeyStroke, int)
2638
   * @see #unregisterKeyboardAction
2639
   * @see #resetKeyboardActions
2640
   */
2641
  public int getConditionForKeyStroke(KeyStroke ks)
2642
  {
2643
    if (inputMap_whenFocused != null
2644
        && inputMap_whenFocused.get(ks) != null)
2645
      return WHEN_FOCUSED;
2646
    else if (inputMap_whenAncestorOfFocused != null
2647
             && inputMap_whenAncestorOfFocused.get(ks) != null)
2648
      return WHEN_ANCESTOR_OF_FOCUSED_COMPONENT;
2649
    else if (inputMap_whenInFocusedWindow != null
2650
             && inputMap_whenInFocusedWindow.get(ks) != null)
2651
      return WHEN_IN_FOCUSED_WINDOW;
2652
    else
2653
      return UNDEFINED_CONDITION;
2654
  }
2655
 
2656
  /**
2657
   * Get the ActionListener (typically an {@link Action} object) which is
2658
   * associated with a particular keystroke.
2659
   *
2660
   * @param ks The keystroke to retrieve the action of
2661
   *
2662
   * @return The action associated with the specified keystroke
2663
   */
2664
  public ActionListener getActionForKeyStroke(KeyStroke ks)
2665
  {
2666
    Object key = getInputMap(JComponent.WHEN_FOCUSED).get(ks);
2667
    if (key == null)
2668
      key = getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).get(ks);
2669
    if (key == null)
2670
      key = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).get(ks);
2671
    if (key != null)
2672
      {
2673
        if (key instanceof ActionListenerProxy)
2674
          return ((ActionListenerProxy) key).target;
2675
        else
2676
          return getActionMap().get(key);
2677
      }
2678
    return null;
2679
  }
2680
 
2681
  /**
2682
   * A hook for subclasses which want to customize event processing.
2683
   */
2684
  protected void processComponentKeyEvent(KeyEvent e)
2685
  {
2686
    // This method does nothing, it is meant to be overridden by subclasses.
2687
  }
2688
 
2689
  /**
2690
   * Override the default key dispatch system from Component to hook into
2691
   * the swing {@link InputMap} / {@link ActionMap} system.
2692
   *
2693
   * See <a
2694
   * href="http://java.sun.com/products/jfc/tsc/special_report/kestrel/keybindings.html">
2695
   * this report</a> for more details, it's somewhat complex.
2696
   */
2697
  protected void processKeyEvent(KeyEvent e)
2698
  {
2699
    // let the AWT event processing send KeyEvents to registered listeners
2700
    super.processKeyEvent(e);
2701
    processComponentKeyEvent(e);
2702
 
2703
    if (e.isConsumed())
2704
      return;
2705
 
2706
    // Input maps are checked in this order:
2707
    // 1. The focused component's WHEN_FOCUSED map is checked.
2708
    // 2. The focused component's WHEN_ANCESTOR_OF_FOCUSED_COMPONENT map.
2709
    // 3. The WHEN_ANCESTOR_OF_FOCUSED_COMPONENT maps of the focused
2710
    //    component's parent, then its parent's parent, and so on.
2711
    //    Note: Input maps for disabled components are skipped.
2712
    // 4. The WHEN_IN_FOCUSED_WINDOW maps of all the enabled components in
2713
    //    the focused window are searched.
2714
 
2715
    KeyStroke keyStroke = KeyStroke.getKeyStrokeForEvent(e);
2716
    boolean pressed = e.getID() == KeyEvent.KEY_PRESSED;
2717
 
2718
    if (processKeyBinding(keyStroke, e, WHEN_FOCUSED, pressed))
2719
      {
2720
        // This is step 1 from above comment.
2721
        e.consume();
2722
        return;
2723
      }
2724
    else if (processKeyBinding
2725
             (keyStroke, e, WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, pressed))
2726
      {
2727
        // This is step 2 from above comment.
2728
        e.consume();
2729
        return;
2730
      }
2731
 
2732
    // This is step 3 from above comment.
2733
    Container current = getParent();
2734
    while (current != null)
2735
      {
2736
        // If current is a JComponent, see if it handles the event in its
2737
        // WHEN_ANCESTOR_OF_FOCUSED_COMPONENT maps.
2738
        if ((current instanceof JComponent) &&
2739
            ((JComponent)current).processKeyBinding
2740
            (keyStroke, e,WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, pressed))
2741
          {
2742
            e.consume();
2743
            return;
2744
          }
2745
 
2746
        // Stop when we've tried a top-level container and it didn't handle it
2747
        if (current instanceof Window || current instanceof Applet)
2748
          break;
2749
 
2750
        // Move up the hierarchy
2751
        current = current.getParent();
2752
      }
2753
 
2754
    // Current being null means the JComponent does not currently have a
2755
    // top-level ancestor, in which case we don't need to check
2756
    // WHEN_IN_FOCUSED_WINDOW bindings.
2757
    if (current == null || e.isConsumed())
2758
      return;
2759
 
2760
    // This is step 4 from above comment.  KeyboardManager maintains mappings
2761
    // related to WHEN_IN_FOCUSED_WINDOW bindings so that we don't have to
2762
    // traverse the containment hierarchy each time.
2763
    if (KeyboardManager.getManager().processKeyStroke(current, keyStroke, e))
2764
      e.consume();
2765
  }
2766
 
2767
  protected boolean processKeyBinding(KeyStroke ks,
2768
                                      KeyEvent e,
2769
                                      int condition,
2770
                                      boolean pressed)
2771
  {
2772
    if (isEnabled())
2773
      {
2774
        Action act = null;
2775
        Object cmd = null;
2776
        InputMap map = getInputMap(condition);
2777
        if (map != null)
2778
          {
2779
            cmd = map.get(ks);
2780
            if (cmd != null)
2781
              {
2782
                if (cmd instanceof ActionListenerProxy)
2783
                  act = (Action) cmd;
2784
                else
2785
                  act = getActionMap().get(cmd);
2786
              }
2787
          }
2788
        if (act != null && act.isEnabled())
2789
          {
2790
            // Need to synchronize here so we don't get in trouble with
2791
            // our __command__ hack.
2792
            synchronized (act)
2793
              {
2794
                // We add the command as value to the action, so that
2795
                // the action can later determine the command with which it
2796
                // was called. This is undocumented, but shouldn't affect
2797
                // compatibility. It allows us to use only one Action instance
2798
                // to do the work for all components of one type, instead of
2799
                // having loads of small Actions. This effectivly saves startup
2800
                // time of Swing.
2801
                act.putValue("__command__", cmd);
2802
                return SwingUtilities.notifyAction(act, ks, e, this,
2803
                                                   e.getModifiers());
2804
              }
2805
          }
2806
      }
2807
    return false;
2808
  }
2809
 
2810
  /**
2811
   * Remove a keyboard action registry.
2812
   *
2813
   * @param aKeyStroke The keystroke to unregister
2814
   *
2815
   * @see #registerKeyboardAction(ActionListener, KeyStroke, int)
2816
   * @see #getConditionForKeyStroke
2817
   * @see #resetKeyboardActions
2818
   */
2819
  public void unregisterKeyboardAction(KeyStroke aKeyStroke)
2820
  {
2821
    ActionMap am = getActionMap();
2822
    // This loops through the conditions WHEN_FOCUSED,
2823
    // WHEN_ANCESTOR_OF_FOCUSED_COMPONENT and WHEN_IN_FOCUSED_WINDOW.
2824
    for (int cond = 0; cond < 3; cond++)
2825
      {
2826
        InputMap im = getInputMap(cond);
2827
        if (im != null)
2828
          {
2829
            Object action = im.get(aKeyStroke);
2830
            if (action != null && am != null)
2831
              am.remove(action);
2832
            im.remove(aKeyStroke);
2833
          }
2834
      }
2835
  }
2836
 
2837
 
2838
  /**
2839
   * Reset all keyboard action registries.
2840
   *
2841
   * @see #registerKeyboardAction(ActionListener, KeyStroke, int)
2842
   * @see #unregisterKeyboardAction
2843
   * @see #getConditionForKeyStroke
2844
   */
2845
  public void resetKeyboardActions()
2846
  {
2847
    if (inputMap_whenFocused != null)
2848
      inputMap_whenFocused.clear();
2849
    if (inputMap_whenAncestorOfFocused != null)
2850
      inputMap_whenAncestorOfFocused.clear();
2851
    if (inputMap_whenInFocusedWindow != null)
2852
      inputMap_whenInFocusedWindow.clear();
2853
    if (actionMap != null)
2854
      actionMap.clear();
2855
  }
2856
 
2857
  /**
2858
   * Mark the described region of this component as dirty in the current
2859
   * {@link RepaintManager}. This will queue an asynchronous repaint using
2860
   * the system painting thread in the near future.
2861
   *
2862
   * @param tm ignored
2863
   * @param x coordinate of the region to mark as dirty
2864
   * @param y coordinate of the region to mark as dirty
2865
   * @param width dimension of the region to mark as dirty
2866
   * @param height dimension of the region to mark as dirty
2867
   */
2868
  public void repaint(long tm, int x, int y, int width, int height)
2869
  {
2870
     RepaintManager.currentManager(this).addDirtyRegion(this, x, y, width,
2871
                                                        height);
2872
  }
2873
 
2874
  /**
2875
   * Mark the described region of this component as dirty in the current
2876
   * {@link RepaintManager}. This will queue an asynchronous repaint using
2877
   * the system painting thread in the near future.
2878
   *
2879
   * @param r The rectangle to mark as dirty
2880
   */
2881
  public void repaint(Rectangle r)
2882
  {
2883
    RepaintManager.currentManager(this).addDirtyRegion(this, r.x, r.y, r.width,
2884
                                                       r.height);
2885
  }
2886
 
2887
  /**
2888
   * Request focus on the default component of this component's {@link
2889
   * FocusTraversalPolicy}.
2890
   *
2891
   * @return The result of {@link #requestFocus()}
2892
   *
2893
   * @deprecated Use {@link #requestFocus()} on the default component provided
2894
   *     from the {@link FocusTraversalPolicy} instead.
2895
   */
2896
  public boolean requestDefaultFocus()
2897
  {
2898
    return false;
2899
  }
2900
 
2901
  /**
2902
   * Queue a an invalidation and revalidation of this component, using
2903
   * {@link RepaintManager#addInvalidComponent}.
2904
   */
2905
  public void revalidate()
2906
  {
2907
    // As long as we don't have a parent we don't need to do any layout, since
2908
    // this is done anyway as soon as we get connected to a parent.
2909
    if (getParent() == null)
2910
      return;
2911
 
2912
    if (! EventQueue.isDispatchThread())
2913
      SwingUtilities.invokeLater(new Runnable()
2914
        {
2915
          public void run()
2916
          {
2917
            revalidate();
2918
          }
2919
        });
2920
    else
2921
      {
2922
        invalidate();
2923
        RepaintManager.currentManager(this).addInvalidComponent(this);
2924
      }
2925
  }
2926
 
2927
  /**
2928
   * Calls <code>scrollRectToVisible</code> on the component's parent.
2929
   * Components which can service this call should override.
2930
   *
2931
   * @param r The rectangle to make visible
2932
   */
2933
  public void scrollRectToVisible(Rectangle r)
2934
  {
2935
    // Search nearest JComponent.
2936
    int xOffs = getX();
2937
    int yOffs = getY();
2938
    Component p;
2939
    for (p = getParent(); p != null && ! (p instanceof JComponent);
2940
         p = p.getParent())
2941
      {
2942
        xOffs += p.getX();
2943
        yOffs += p.getY();
2944
      }
2945
    if (p != null)
2946
      {
2947
        r.x += xOffs;
2948
        r.y += yOffs;
2949
        JComponent jParent = (JComponent) p;
2950
        jParent.scrollRectToVisible(r);
2951
        r.x -= xOffs;
2952
        r.y -= yOffs;
2953
      }
2954
  }
2955
 
2956
  /**
2957
   * Set the value of the {@link #alignmentX} property.
2958
   *
2959
   * @param a The new value of the property
2960
   */
2961
  public void setAlignmentX(float a)
2962
  {
2963
    if (a < 0.0F)
2964
      alignmentX = 0.0F;
2965
    else if (a > 1.0)
2966
      alignmentX = 1.0F;
2967
    else
2968
      alignmentX = a;
2969
  }
2970
 
2971
  /**
2972
   * Set the value of the {@link #alignmentY} property.
2973
   *
2974
   * @param a The new value of the property
2975
   */
2976
  public void setAlignmentY(float a)
2977
  {
2978
    if (a < 0.0F)
2979
      alignmentY = 0.0F;
2980
    else if (a > 1.0)
2981
      alignmentY = 1.0F;
2982
    else
2983
      alignmentY = a;
2984
  }
2985
 
2986
  /**
2987
   * Set the value of the {@link #autoscrolls} property.
2988
   *
2989
   * @param a The new value of the property
2990
   */
2991
  public void setAutoscrolls(boolean a)
2992
  {
2993
    autoscrolls = a;
2994
    clientAutoscrollsSet = true;
2995
  }
2996
 
2997
  /**
2998
   * Set the value of the {@link #debugGraphicsOptions} property.
2999
   *
3000
   * @param debugOptions The new value of the property
3001
   */
3002
  public void setDebugGraphicsOptions(int debugOptions)
3003
  {
3004
    debugGraphicsOptions = debugOptions;
3005
  }
3006
 
3007
  /**
3008
   * Set the value of the {@link #doubleBuffered} property.
3009
   *
3010
   * @param db The new value of the property
3011
   */
3012
  public void setDoubleBuffered(boolean db)
3013
  {
3014
    doubleBuffered = db;
3015
  }
3016
 
3017
  /**
3018
   * Set the value of the <code>enabled</code> property.
3019
   *
3020
   * @param enable The new value of the property
3021
   */
3022
  public void setEnabled(boolean enable)
3023
  {
3024
    if (enable == isEnabled())
3025
      return;
3026
    super.setEnabled(enable);
3027
    firePropertyChange("enabled", !enable, enable);
3028
    repaint();
3029
  }
3030
 
3031
  /**
3032
   * Set the value of the <code>font</code> property.
3033
   *
3034
   * @param f The new value of the property
3035
   */
3036
  public void setFont(Font f)
3037
  {
3038
    if (f == getFont())
3039
      return;
3040
    super.setFont(f);
3041
    revalidate();
3042
    repaint();
3043
  }
3044
 
3045
  /**
3046
   * Set the value of the <code>background</code> property.
3047
   *
3048
   * @param bg The new value of the property
3049
   */
3050
  public void setBackground(Color bg)
3051
  {
3052
    if (bg == getBackground())
3053
      return;
3054
    super.setBackground(bg);
3055
    repaint();
3056
  }
3057
 
3058
  /**
3059
   * Set the value of the <code>foreground</code> property.
3060
   *
3061
   * @param fg The new value of the property
3062
   */
3063
  public void setForeground(Color fg)
3064
  {
3065
    if (fg == getForeground())
3066
      return;
3067
    super.setForeground(fg);
3068
    repaint();
3069
  }
3070
 
3071
  /**
3072
   * Set the specified component to be the next component in the
3073
   * focus cycle, overriding the {@link FocusTraversalPolicy} for
3074
   * this component.
3075
   *
3076
   * @param aComponent The component to set as the next focusable
3077
   *
3078
   * @deprecated Use FocusTraversalPolicy instead
3079
   */
3080
  public void setNextFocusableComponent(Component aComponent)
3081
  {
3082
    Container focusRoot = this;
3083
    if (! this.isFocusCycleRoot())
3084
      focusRoot = getFocusCycleRootAncestor();
3085
 
3086
    FocusTraversalPolicy policy  = focusRoot.getFocusTraversalPolicy();
3087
    if (policy instanceof CompatibilityFocusTraversalPolicy)
3088
      {
3089
        policy = new CompatibilityFocusTraversalPolicy(policy);
3090
        focusRoot.setFocusTraversalPolicy(policy);
3091
      }
3092
    CompatibilityFocusTraversalPolicy p =
3093
      (CompatibilityFocusTraversalPolicy) policy;
3094
 
3095
    Component old = getNextFocusableComponent();
3096
    if (old != null)
3097
      {
3098
        p.removeNextFocusableComponent(this, old);
3099
      }
3100
 
3101
    if (aComponent != null)
3102
      {
3103
        p.addNextFocusableComponent(this, aComponent);
3104
      }
3105
  }
3106
 
3107
  /**
3108
   * Set the value of the {@link #requestFocusEnabled} property.
3109
   *
3110
   * @param e The new value of the property
3111
   */
3112
  public void setRequestFocusEnabled(boolean e)
3113
  {
3114
    requestFocusEnabled = e;
3115
  }
3116
 
3117
  /**
3118
   * Get the value of the {@link #transferHandler} property.
3119
   *
3120
   * @return The current value of the property
3121
   *
3122
   * @see #setTransferHandler
3123
   */
3124
 
3125
  public TransferHandler getTransferHandler()
3126
  {
3127
    return transferHandler;
3128
  }
3129
 
3130
  /**
3131
   * Set the value of the {@link #transferHandler} property.
3132
   *
3133
   * @param newHandler The new value of the property
3134
   *
3135
   * @see #getTransferHandler
3136
   */
3137
 
3138
  public void setTransferHandler(TransferHandler newHandler)
3139
  {
3140
    if (transferHandler == newHandler)
3141
      return;
3142
 
3143
    TransferHandler oldHandler = transferHandler;
3144
    transferHandler = newHandler;
3145
    firePropertyChange("transferHandler", oldHandler, newHandler);
3146
  }
3147
 
3148
  /**
3149
   * Set if the component should paint all pixels withing its bounds.
3150
   * If this property is set to false, the component expects the cleared
3151
   * background.
3152
   *
3153
   * @param isOpaque if true, paint all pixels. If false, expect the clean
3154
   * background.
3155
   *
3156
   * @see ComponentUI#update
3157
   */
3158
  public void setOpaque(boolean isOpaque)
3159
  {
3160
    boolean oldOpaque = opaque;
3161
    opaque = isOpaque;
3162
    clientOpaqueSet = true;
3163
    firePropertyChange("opaque", oldOpaque, opaque);
3164
  }
3165
 
3166
  /**
3167
   * Set the value of the visible property.
3168
   *
3169
   * If the value is changed, then the AncestorListeners of this component
3170
   * and all its children (recursivly) are notified.
3171
   *
3172
   * @param v The new value of the property
3173
   */
3174
  public void setVisible(boolean v)
3175
  {
3176
    // No need to do anything if the actual value doesn't change.
3177
    if (isVisible() == v)
3178
      return;
3179
 
3180
    super.setVisible(v);
3181
 
3182
    // Notify AncestorListeners.
3183
    if (v == true)
3184
      fireAncestorEvent(this, AncestorEvent.ANCESTOR_ADDED);
3185
    else
3186
      fireAncestorEvent(this, AncestorEvent.ANCESTOR_REMOVED);
3187
 
3188
    Container parent = getParent();
3189
    if (parent != null)
3190
      parent.repaint(getX(), getY(), getWidth(), getHeight());
3191
    revalidate();
3192
  }
3193
 
3194
  /**
3195
   * Call {@link #paint}.
3196
   *
3197
   * @param g The graphics context to paint into
3198
   */
3199
  public void update(Graphics g)
3200
  {
3201
    paint(g);
3202
  }
3203
 
3204
  /**
3205
   * Get the value of the UIClassID property. This property should be a key
3206
   * in the {@link UIDefaults} table managed by {@link UIManager}, the
3207
   * value of which is the name of a class to load for the component's
3208
   * {@link #ui} property.
3209
   *
3210
   * @return A "symbolic" name which will map to a class to use for the
3211
   * component's UI, such as <code>"ComponentUI"</code>
3212
   *
3213
   * @see #setUI
3214
   * @see #updateUI
3215
   */
3216
  public String getUIClassID()
3217
  {
3218
    return "ComponentUI";
3219
  }
3220
 
3221
  /**
3222
   * Install a new UI delegate as the component's {@link #ui} property. In
3223
   * the process, this will call {@link ComponentUI#uninstallUI} on any
3224
   * existing value for the {@link #ui} property, and {@link
3225
   * ComponentUI#installUI} on the new UI delegate.
3226
   *
3227
   * @param newUI The new UI delegate to install
3228
   *
3229
   * @see #updateUI
3230
   * @see #getUIClassID
3231
   */
3232
  protected void setUI(ComponentUI newUI)
3233
  {
3234
    if (ui != null)
3235
      ui.uninstallUI(this);
3236
 
3237
    ComponentUI oldUI = ui;
3238
    ui = newUI;
3239
 
3240
    if (ui != null)
3241
      ui.installUI(this);
3242
 
3243
    firePropertyChange("UI", oldUI, newUI);
3244
    revalidate();
3245
    repaint();
3246
  }
3247
 
3248
  /**
3249
   * This method should be overridden in subclasses. In JComponent, the
3250
   * method does nothing. In subclasses, it should a UI delegate
3251
   * (corresponding to the symbolic name returned from {@link
3252
   * #getUIClassID}) from the {@link UIManager}, and calls {@link #setUI}
3253
   * with the new delegate.
3254
   */
3255
  public void updateUI()
3256
  {
3257
    // Nothing to do here.
3258
  }
3259
 
3260
  /**
3261
   * Returns the locale used as the default for all new components.  The
3262
   * default value is {@link Locale#getDefault()} (that is, the platform
3263
   * default locale).
3264
   *
3265
   * @return The locale (never <code>null</code>).
3266
   *
3267
   * @see #setDefaultLocale(Locale)
3268
   */
3269
  public static Locale getDefaultLocale()
3270
  {
3271
    if (defaultLocale == null)
3272
      defaultLocale = Locale.getDefault();
3273
    return defaultLocale;
3274
  }
3275
 
3276
  /**
3277
   * Sets the locale to be used as the default for all new components.  If this
3278
   * is set to <code>null</code>, the {@link #getDefaultLocale()} method will
3279
   * return the platform default locale.
3280
   *
3281
   * @param l  the locale (<code>null</code> permitted).
3282
   */
3283
  public static void setDefaultLocale(Locale l)
3284
  {
3285
    defaultLocale = l;
3286
  }
3287
 
3288
  /**
3289
   * Returns the currently set input verifier for this component.
3290
   *
3291
   * @return the input verifier, or <code>null</code> if none
3292
   */
3293
  public InputVerifier getInputVerifier()
3294
  {
3295
    return inputVerifier;
3296
  }
3297
 
3298
  /**
3299
   * Sets the input verifier to use by this component.
3300
   *
3301
   * @param verifier the input verifier, or <code>null</code>
3302
   */
3303
  public void setInputVerifier(InputVerifier verifier)
3304
  {
3305
    InputVerifier oldVerifier = inputVerifier;
3306
    inputVerifier = verifier;
3307
    firePropertyChange("inputVerifier", oldVerifier, verifier);
3308
  }
3309
 
3310
  /**
3311
   * @since 1.3
3312
   */
3313
  public boolean getVerifyInputWhenFocusTarget()
3314
  {
3315
    return verifyInputWhenFocusTarget;
3316
  }
3317
 
3318
  /**
3319
   * @since 1.3
3320
   */
3321
  public void setVerifyInputWhenFocusTarget(boolean verifyInputWhenFocusTarget)
3322
  {
3323
    if (this.verifyInputWhenFocusTarget == verifyInputWhenFocusTarget)
3324
      return;
3325
 
3326
    this.verifyInputWhenFocusTarget = verifyInputWhenFocusTarget;
3327
    firePropertyChange("verifyInputWhenFocusTarget",
3328
                       ! verifyInputWhenFocusTarget,
3329
                       verifyInputWhenFocusTarget);
3330
  }
3331
 
3332
  /**
3333
   * Requests that this component gets the input focus if the
3334
   * requestFocusEnabled property is set to <code>true</code>.
3335
   * This also means that this component's top-level window becomes
3336
   * the focused window, if that is not already the case.
3337
   *
3338
   * The preconditions that have to be met to become a focus owner is that
3339
   * the component must be displayable, visible and focusable.
3340
   *
3341
   * Note that this signals only a request for becoming focused. There are
3342
   * situations in which it is not possible to get the focus. So developers
3343
   * should not assume that the component has the focus until it receives
3344
   * a {@link java.awt.event.FocusEvent} with a value of
3345
   * {@link java.awt.event.FocusEvent#FOCUS_GAINED}.
3346
   *
3347
   * @see Component#requestFocus()
3348
   */
3349
  public void requestFocus()
3350
  {
3351
    if (isRequestFocusEnabled())
3352
      super.requestFocus();
3353
  }
3354
 
3355
  /**
3356
   * This method is overridden to make it public so that it can be used
3357
   * by look and feel implementations.
3358
   *
3359
   * You should not use this method directly. Instead you are strongly
3360
   * encouraged to call {@link #requestFocus()} or
3361
   * {@link #requestFocusInWindow()} instead.
3362
   *
3363
   * @param temporary if the focus change is temporary
3364
   *
3365
   * @return <code>false</code> if the focus change request will definitly
3366
   *     fail, <code>true</code> if it will likely succeed
3367
   *
3368
   * @see Component#requestFocus(boolean)
3369
   *
3370
   * @since 1.4
3371
   */
3372
  public boolean requestFocus(boolean temporary)
3373
  {
3374
    return super.requestFocus(temporary);
3375
  }
3376
 
3377
  /**
3378
   * Requests that this component gets the input focus if the top level
3379
   * window that contains this component has the focus and the
3380
   * requestFocusEnabled property is set to <code>true</code>.
3381
   *
3382
   * The preconditions that have to be met to become a focus owner is that
3383
   * the component must be displayable, visible and focusable.
3384
   *
3385
   * Note that this signals only a request for becoming focused. There are
3386
   * situations in which it is not possible to get the focus. So developers
3387
   * should not assume that the component has the focus until it receives
3388
   * a {@link java.awt.event.FocusEvent} with a value of
3389
   * {@link java.awt.event.FocusEvent#FOCUS_GAINED}.
3390
   *
3391
   * @return <code>false</code> if the focus change request will definitly
3392
   *     fail, <code>true</code> if it will likely succeed
3393
   *
3394
   * @see Component#requestFocusInWindow()
3395
   */
3396
  public boolean requestFocusInWindow()
3397
  {
3398
    if (isRequestFocusEnabled())
3399
      return super.requestFocusInWindow();
3400
    else
3401
      return false;
3402
  }
3403
 
3404
  /**
3405
   * This method is overridden to make it public so that it can be used
3406
   * by look and feel implementations.
3407
   *
3408
   * You should not use this method directly. Instead you are strongly
3409
   * encouraged to call {@link #requestFocus()} or
3410
   * {@link #requestFocusInWindow()} instead.
3411
   *
3412
   * @param temporary if the focus change is temporary
3413
   *
3414
   * @return <code>false</code> if the focus change request will definitly
3415
   *     fail, <code>true</code> if it will likely succeed
3416
   *
3417
   * @see Component#requestFocus(boolean)
3418
   *
3419
   * @since 1.4
3420
   */
3421
  protected boolean requestFocusInWindow(boolean temporary)
3422
  {
3423
    return super.requestFocusInWindow(temporary);
3424
  }
3425
 
3426
  /**
3427
   * Receives notification if this component is added to a parent component.
3428
   *
3429
   * Notification is sent to all registered AncestorListeners about the
3430
   * new parent.
3431
   *
3432
   * This method sets up ActionListeners for all registered KeyStrokes of
3433
   * this component in the chain of parent components.
3434
   *
3435
   * A PropertyChange event is fired to indicate that the ancestor property
3436
   * has changed.
3437
   *
3438
   * This method is used internally and should not be used in applications.
3439
   */
3440
  public void addNotify()
3441
  {
3442
    // Register the WHEN_IN_FOCUSED_WINDOW keyboard bindings
3443
    // Note that here we unregister all bindings associated with
3444
    // this component and then re-register them.  This may be more than
3445
    // necessary if the top-level ancestor hasn't changed.  Should
3446
    // maybe improve this.
3447
    KeyboardManager km = KeyboardManager.getManager();
3448
    km.clearBindingsForComp(this);
3449
    km.registerEntireMap((ComponentInputMap)
3450
                         this.getInputMap(WHEN_IN_FOCUSED_WINDOW));
3451
    super.addNotify();
3452
 
3453
    // Notify AncestorListeners.
3454
    fireAncestorEvent(this, AncestorEvent.ANCESTOR_ADDED);
3455
 
3456
    // fire property change event for 'ancestor'
3457
    firePropertyChange("ancestor", null, getParent());
3458
  }
3459
 
3460
  /**
3461
   * Receives notification that this component no longer has a parent.
3462
   *
3463
   * This method sends an AncestorEvent to all registered AncestorListeners,
3464
   * notifying them that the parent is gone.
3465
   *
3466
   * The keybord actions of this component are removed from the parent and
3467
   * its ancestors.
3468
   *
3469
   * A PropertyChangeEvent is fired to indicate that the 'ancestor' property
3470
   * has changed.
3471
   *
3472
   * This method is called before the component is actually removed from
3473
   * its parent, so the parent is still visible through
3474
   * {@link Component#getParent}.
3475
   */
3476
  public void removeNotify()
3477
  {
3478
    super.removeNotify();
3479
 
3480
    KeyboardManager.getManager().clearBindingsForComp(this);
3481
 
3482
    // Notify ancestor listeners.
3483
    fireAncestorEvent(this, AncestorEvent.ANCESTOR_REMOVED);
3484
 
3485
    // fire property change event for 'ancestor'
3486
    firePropertyChange("ancestor", getParent(), null);
3487
  }
3488
 
3489
  /**
3490
   * Returns <code>true</code> if the coordinates (x, y) lie within
3491
   * the bounds of this component and <code>false</code> otherwise.
3492
   * x and y are relative to the coordinate space of the component.
3493
   *
3494
   * @param x the X coordinate of the point to check
3495
   * @param y the Y coordinate of the point to check
3496
   *
3497
   * @return <code>true</code> if the specified point lies within the bounds
3498
   *     of this component, <code>false</code> otherwise
3499
   */
3500
  public boolean contains(int x, int y)
3501
  {
3502
    if (ui == null)
3503
      return super.contains(x, y);
3504
    else
3505
      return ui.contains(this, x, y);
3506
  }
3507
 
3508
  /**
3509
   * Disables this component.
3510
   *
3511
   * @deprecated replaced by {@link #setEnabled(boolean)}
3512
   */
3513
  public void disable()
3514
  {
3515
    super.disable();
3516
  }
3517
 
3518
  /**
3519
   * Enables this component.
3520
   *
3521
   * @deprecated replaced by {@link #setEnabled(boolean)}
3522
   */
3523
  public void enable()
3524
  {
3525
    super.enable();
3526
  }
3527
 
3528
  /**
3529
   * Returns the Graphics context for this component. This can be used
3530
   * to draw on a component.
3531
   *
3532
   * @return the Graphics context for this component
3533
   */
3534
  public Graphics getGraphics()
3535
  {
3536
    return super.getGraphics();
3537
  }
3538
 
3539
  /**
3540
   * Returns the X coordinate of the upper left corner of this component.
3541
   * Prefer this method over {@link #getBounds} or {@link #getLocation}
3542
   * because it does not cause any heap allocation.
3543
   *
3544
   * @return the X coordinate of the upper left corner of the component
3545
   */
3546
  public int getX()
3547
  {
3548
    return super.getX();
3549
  }
3550
 
3551
  /**
3552
   * Returns the Y coordinate of the upper left corner of this component.
3553
   * Prefer this method over {@link #getBounds} or {@link #getLocation}
3554
   * because it does not cause any heap allocation.
3555
   *
3556
   * @return the Y coordinate of the upper left corner of the component
3557
   */
3558
  public int getY()
3559
  {
3560
    return super.getY();
3561
  }
3562
 
3563
  /**
3564
   * Returns the height of this component. Prefer this method over
3565
   * {@link #getBounds} or {@link #getSize} because it does not cause
3566
   * any heap allocation.
3567
   *
3568
   * @return the height of the component
3569
   */
3570
  public int getHeight()
3571
  {
3572
    return super.getHeight();
3573
  }
3574
 
3575
  /**
3576
   * Returns the width of this component. Prefer this method over
3577
   * {@link #getBounds} or {@link #getSize} because it does not cause
3578
   * any heap allocation.
3579
   *
3580
   * @return the width of the component
3581
   */
3582
  public int getWidth()
3583
  {
3584
    return super.getWidth();
3585
  }
3586
 
3587
  /**
3588
   * Prints this component to the given Graphics context. A call to this
3589
   * method results in calls to the methods {@link #printComponent},
3590
   * {@link #printBorder} and {@link #printChildren} in this order.
3591
   *
3592
   * Double buffering is temporarily turned off so the painting goes directly
3593
   * to the supplied Graphics context.
3594
   *
3595
   * @param g the Graphics context to print onto
3596
   */
3597
  public void print(Graphics g)
3598
  {
3599
    boolean doubleBufferState = isDoubleBuffered();
3600
    setDoubleBuffered(false);
3601
    printComponent(g);
3602
    printBorder(g);
3603
    printChildren(g);
3604
    setDoubleBuffered(doubleBufferState);
3605
  }
3606
 
3607
  /**
3608
   * Prints this component to the given Graphics context. This invokes
3609
   * {@link #print}.
3610
   *
3611
   * @param g the Graphics context to print onto
3612
   */
3613
  public void printAll(Graphics g)
3614
  {
3615
    print(g);
3616
  }
3617
 
3618
  /**
3619
   * Prints this component to the specified Graphics context. The default
3620
   * behaviour is to invoke {@link #paintComponent}. Override this
3621
   * if you want special behaviour for printing.
3622
   *
3623
   * @param g the Graphics context to print onto
3624
   *
3625
   * @since 1.3
3626
   */
3627
  protected void printComponent(Graphics g)
3628
  {
3629
    paintComponent(g);
3630
  }
3631
 
3632
  /**
3633
   * Print this component's children to the specified Graphics context.
3634
   * The default behaviour is to invoke {@link #paintChildren}. Override this
3635
   * if you want special behaviour for printing.
3636
   *
3637
   * @param g the Graphics context to print onto
3638
   *
3639
   * @since 1.3
3640
   */
3641
  protected void printChildren(Graphics g)
3642
  {
3643
    paintChildren(g);
3644
  }
3645
 
3646
  /**
3647
   * Print this component's border to the specified Graphics context.
3648
   * The default behaviour is to invoke {@link #paintBorder}. Override this
3649
   * if you want special behaviour for printing.
3650
   *
3651
   * @param g the Graphics context to print onto
3652
   *
3653
   * @since 1.3
3654
   */
3655
  protected void printBorder(Graphics g)
3656
  {
3657
    paintBorder(g);
3658
  }
3659
 
3660
  /**
3661
   * Processes mouse motion event, like dragging and moving.
3662
   *
3663
   * @param ev the MouseEvent describing the mouse motion
3664
   */
3665
  protected void processMouseMotionEvent(MouseEvent ev)
3666
  {
3667
    super.processMouseMotionEvent(ev);
3668
  }
3669
 
3670
  /**
3671
   * Moves and resizes the component.
3672
   *
3673
   * @param x the new horizontal location
3674
   * @param y the new vertial location
3675
   * @param w the new width
3676
   * @param h the new height
3677
   */
3678
  public void reshape(int x, int y, int w, int h)
3679
  {
3680
    int oldX = getX();
3681
    int oldY = getY();
3682
    super.reshape(x, y, w, h);
3683
    // Notify AncestorListeners.
3684
    if (oldX != getX() || oldY != getY())
3685
      fireAncestorEvent(this, AncestorEvent.ANCESTOR_MOVED);
3686
  }
3687
 
3688
  /**
3689
   * Fires an AncestorEvent to this component's and all of its child
3690
   * component's AncestorListeners.
3691
   *
3692
   * @param ancestor the component that triggered the event
3693
   * @param id the kind of ancestor event that should be fired
3694
   */
3695
  void fireAncestorEvent(JComponent ancestor, int id)
3696
  {
3697
    // Fire event for registered ancestor listeners of this component.
3698
    AncestorListener[] listeners = getAncestorListeners();
3699
    if (listeners.length > 0)
3700
      {
3701
        AncestorEvent ev = new AncestorEvent(this, id,
3702
                                             ancestor, ancestor.getParent());
3703
        for (int i = 0; i < listeners.length; i++)
3704
          {
3705
            switch (id)
3706
              {
3707
              case AncestorEvent.ANCESTOR_MOVED:
3708
                listeners[i].ancestorMoved(ev);
3709
                break;
3710
              case AncestorEvent.ANCESTOR_ADDED:
3711
                listeners[i].ancestorAdded(ev);
3712
                break;
3713
              case AncestorEvent.ANCESTOR_REMOVED:
3714
                listeners[i].ancestorRemoved(ev);
3715
                break;
3716
              }
3717
          }
3718
      }
3719
    // Dispatch event to all children.
3720
    int numChildren = getComponentCount();
3721
    for (int i = 0; i < numChildren; i++)
3722
      {
3723
        Component child = getComponent(i);
3724
        if (! (child instanceof JComponent))
3725
          continue;
3726
        JComponent jc = (JComponent) child;
3727
        jc.fireAncestorEvent(ancestor, id);
3728
      }
3729
  }
3730
 
3731
  /**
3732
   * This is the method that gets called when the WHEN_IN_FOCUSED_WINDOW map
3733
   * is changed.
3734
   *
3735
   * @param changed the JComponent associated with the WHEN_IN_FOCUSED_WINDOW
3736
   *        map
3737
   */
3738
  void updateComponentInputMap(ComponentInputMap changed)
3739
  {
3740
    // Since you can change a component's input map via
3741
    // setInputMap, we have to check if <code>changed</code>
3742
    // is still in our WHEN_IN_FOCUSED_WINDOW map hierarchy
3743
    InputMap curr = getInputMap(WHEN_IN_FOCUSED_WINDOW);
3744
    while (curr != null && curr != changed)
3745
      curr = curr.getParent();
3746
 
3747
    // If curr is null then changed is not in the hierarchy
3748
    if (curr == null)
3749
      return;
3750
 
3751
    // Now we have to update the keyboard manager's hashtable
3752
    KeyboardManager km = KeyboardManager.getManager();
3753
 
3754
    // This is a poor strategy, should be improved.  We currently
3755
    // delete all the old bindings for the component and then register
3756
    // the current bindings.
3757
    km.clearBindingsForComp(changed.getComponent());
3758
    km.registerEntireMap((ComponentInputMap)
3759
                         getInputMap(WHEN_IN_FOCUSED_WINDOW));
3760
  }
3761
 
3762
  /**
3763
   * Helper method for
3764
   * {@link LookAndFeel#installProperty(JComponent, String, Object)}.
3765
   *
3766
   * @param propertyName the name of the property
3767
   * @param value the value of the property
3768
   *
3769
   * @throws IllegalArgumentException if the specified property cannot be set
3770
   *         by this method
3771
   * @throws ClassCastException if the property value does not match the
3772
   *         property type
3773
   * @throws NullPointerException if <code>c</code> or
3774
   *         <code>propertyValue</code> is <code>null</code>
3775
   */
3776
  void setUIProperty(String propertyName, Object value)
3777
  {
3778
    if (propertyName.equals("opaque"))
3779
      {
3780
        if (! clientOpaqueSet)
3781
          {
3782
            setOpaque(((Boolean) value).booleanValue());
3783
            clientOpaqueSet = false;
3784
          }
3785
      }
3786
    else if (propertyName.equals("autoscrolls"))
3787
      {
3788
        if (! clientAutoscrollsSet)
3789
          {
3790
            setAutoscrolls(((Boolean) value).booleanValue());
3791
            clientAutoscrollsSet = false;
3792
          }
3793
      }
3794
    else
3795
      {
3796
        throw new IllegalArgumentException
3797
            ("Unsupported property for LookAndFeel.installProperty(): "
3798
             + propertyName);
3799
      }
3800
  }
3801
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.