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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libjava/] [classpath/] [java/] [awt/] [Container.java] - Blame information for rev 14

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 jlechner
/* Container.java -- parent container class in AWT
2
   Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005  Free Software Foundation
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 java.awt;
40
 
41
import java.awt.event.ComponentListener;
42
import java.awt.event.ContainerEvent;
43
import java.awt.event.ContainerListener;
44
import java.awt.event.KeyEvent;
45
import java.awt.event.MouseEvent;
46
import java.awt.peer.ComponentPeer;
47
import java.awt.peer.ContainerPeer;
48
import java.awt.peer.LightweightPeer;
49
import java.beans.PropertyChangeListener;
50
import java.beans.PropertyChangeSupport;
51
import java.io.IOException;
52
import java.io.ObjectInputStream;
53
import java.io.ObjectOutputStream;
54
import java.io.PrintStream;
55
import java.io.PrintWriter;
56
import java.io.Serializable;
57
import java.util.Collections;
58
import java.util.EventListener;
59
import java.util.HashSet;
60
import java.util.Iterator;
61
import java.util.Set;
62
 
63
import javax.accessibility.Accessible;
64
 
65
import gnu.java.awt.AWTUtilities;
66
 
67
/**
68
 * A generic window toolkit object that acts as a container for other objects.
69
 * Components are tracked in a list, and new elements are at the end of the
70
 * list or bottom of the stacking order.
71
 *
72
 * @author original author unknown
73
 * @author Eric Blake (ebb9@email.byu.edu)
74
 *
75
 * @since 1.0
76
 *
77
 * @status still missing 1.4 support
78
 */
79
public class Container extends Component
80
{
81
  /**
82
   * Compatible with JDK 1.0+.
83
   */
84
  private static final long serialVersionUID = 4613797578919906343L;
85
 
86
  /* Serialized fields from the serialization spec. */
87
  int ncomponents;
88
  Component[] component;
89
  LayoutManager layoutMgr;
90
 
91
  LightweightDispatcher dispatcher;
92
 
93
  Dimension maxSize;
94
 
95
  /**
96
   * @since 1.4
97
   */
98
  boolean focusCycleRoot;
99
 
100
  int containerSerializedDataVersion;
101
 
102
  /* Anything else is non-serializable, and should be declared "transient". */
103
  transient ContainerListener containerListener;
104
  transient PropertyChangeSupport changeSupport;
105
 
106
  /** The focus traversal policy that determines how focus is
107
      transferred between this Container and its children. */
108
  private FocusTraversalPolicy focusTraversalPolicy;
109
 
110
  /**
111
   * The focus traversal keys, if not inherited from the parent or default
112
   * keyboard manager. These sets will contain only AWTKeyStrokes that
113
   * represent press and release events to use as focus control.
114
   *
115
   * @see #getFocusTraversalKeys(int)
116
   * @see #setFocusTraversalKeys(int, Set)
117
   * @since 1.4
118
   */
119
  transient Set[] focusTraversalKeys;
120
 
121
  /**
122
   * Default constructor for subclasses.
123
   */
124
  public Container()
125
  {
126
    // Nothing to do here.
127
  }
128
 
129
  /**
130
   * Returns the number of components in this container.
131
   *
132
   * @return The number of components in this container.
133
   */
134
  public int getComponentCount()
135
  {
136
    return countComponents ();
137
  }
138
 
139
  /**
140
   * Returns the number of components in this container.
141
   *
142
   * @return The number of components in this container.
143
   *
144
   * @deprecated use {@link #getComponentCount()} instead
145
   */
146
  public int countComponents()
147
  {
148
    return ncomponents;
149
  }
150
 
151
  /**
152
   * Returns the component at the specified index.
153
   *
154
   * @param n The index of the component to retrieve.
155
   *
156
   * @return The requested component.
157
   *
158
   * @throws ArrayIndexOutOfBoundsException If the specified index is invalid
159
   */
160
  public Component getComponent(int n)
161
  {
162
    synchronized (getTreeLock ())
163
      {
164
        if (n < 0 || n >= ncomponents)
165
          throw new ArrayIndexOutOfBoundsException("no such component");
166
 
167
        return component[n];
168
      }
169
  }
170
 
171
  /**
172
   * Returns an array of the components in this container.
173
   *
174
   * @return The components in this container.
175
   */
176
  public Component[] getComponents()
177
  {
178
    synchronized (getTreeLock ())
179
      {
180
        Component[] result = new Component[ncomponents];
181
 
182
        if (ncomponents > 0)
183
          System.arraycopy(component, 0, result, 0, ncomponents);
184
 
185
        return result;
186
      }
187
  }
188
 
189
  /**
190
   * Swaps the components at position i and j, in the container.
191
   */
192
 
193
  protected void swapComponents (int i, int j)
194
  {
195
    synchronized (getTreeLock ())
196
      {
197
        if (i < 0
198
            || i >= component.length
199
            || j < 0
200
            || j >= component.length)
201
          throw new ArrayIndexOutOfBoundsException ();
202
        Component tmp = component[i];
203
        component[i] = component[j];
204
        component[j] = tmp;
205
      }
206
  }
207
 
208
  /**
209
   * Returns the insets for this container, which is the space used for
210
   * borders, the margin, etc.
211
   *
212
   * @return The insets for this container.
213
   */
214
  public Insets getInsets()
215
  {
216
    return insets ();
217
  }
218
 
219
  /**
220
   * Returns the insets for this container, which is the space used for
221
   * borders, the margin, etc.
222
   *
223
   * @return The insets for this container.
224
   * @deprecated use {@link #getInsets()} instead
225
   */
226
  public Insets insets()
227
  {
228
    if (peer == null)
229
      return new Insets (0, 0, 0, 0);
230
 
231
    return ((ContainerPeer) peer).getInsets ();
232
  }
233
 
234
  /**
235
   * Adds the specified component to this container at the end of the
236
   * component list.
237
   *
238
   * @param comp The component to add to the container.
239
   *
240
   * @return The same component that was added.
241
   */
242
  public Component add(Component comp)
243
  {
244
    addImpl(comp, null, -1);
245
    return comp;
246
  }
247
 
248
  /**
249
   * Adds the specified component to the container at the end of the
250
   * component list.  This method should not be used. Instead, use
251
   * <code>add(Component, Object)</code>.
252
   *
253
   * @param name The name of the component to be added.
254
   * @param comp The component to be added.
255
   *
256
   * @return The same component that was added.
257
   *
258
   * @see #add(Component,Object)
259
   */
260
  public Component add(String name, Component comp)
261
  {
262
    addImpl(comp, name, -1);
263
    return comp;
264
  }
265
 
266
  /**
267
   * Adds the specified component to this container at the specified index
268
   * in the component list.
269
   *
270
   * @param comp The component to be added.
271
   * @param index The index in the component list to insert this child
272
   * at, or -1 to add at the end of the list.
273
   *
274
   * @return The same component that was added.
275
   *
276
   * @throws ArrayIndexOutOfBoundsException If the specified index is invalid.
277
   */
278
  public Component add(Component comp, int index)
279
  {
280
    addImpl(comp, null, index);
281
    return comp;
282
  }
283
 
284
  /**
285
   * Adds the specified component to this container at the end of the
286
   * component list.  The layout manager will use the specified constraints
287
   * when laying out this component.
288
   *
289
   * @param comp The component to be added to this container.
290
   * @param constraints The layout constraints for this component.
291
   */
292
  public void add(Component comp, Object constraints)
293
  {
294
    addImpl(comp, constraints, -1);
295
  }
296
 
297
  /**
298
   * Adds the specified component to this container at the specified index
299
   * in the component list.  The layout manager will use the specified
300
   * constraints when layout out this component.
301
   *
302
   * @param comp The component to be added.
303
   * @param constraints The layout constraints for this component.
304
   * @param index The index in the component list to insert this child
305
   * at, or -1 to add at the end of the list.
306
   *
307
   * @throws ArrayIndexOutOfBoundsException If the specified index is invalid.
308
   */
309
  public void add(Component comp, Object constraints, int index)
310
  {
311
    addImpl(comp, constraints, index);
312
  }
313
 
314
  /**
315
   * This method is called by all the <code>add()</code> methods to perform
316
   * the actual adding of the component.  Subclasses who wish to perform
317
   * their own processing when a component is added should override this
318
   * method.  Any subclass doing this must call the superclass version of
319
   * this method in order to ensure proper functioning of the container.
320
   *
321
   * @param comp The component to be added.
322
   * @param constraints The layout constraints for this component, or
323
   * <code>null</code> if there are no constraints.
324
   * @param index The index in the component list to insert this child
325
   * at, or -1 to add at the end of the list.
326
   *
327
   * @throws ArrayIndexOutOfBoundsException If the specified index is invalid.
328
   */
329
  protected void addImpl(Component comp, Object constraints, int index)
330
  {
331
    synchronized (getTreeLock ())
332
      {
333
        if (index > ncomponents
334
            || (index < 0 && index != -1)
335
            || comp instanceof Window
336
            || (comp instanceof Container
337
                && ((Container) comp).isAncestorOf(this)))
338
          throw new IllegalArgumentException();
339
 
340
        // Reparent component, and make sure component is instantiated if
341
        // we are.
342
        if (comp.parent != null)
343
          comp.parent.remove(comp);
344
        comp.parent = this;
345
 
346
        if (peer != null)
347
          {
348
            // Notify the component that it has a new parent.
349
            comp.addNotify();
350
 
351
            if (comp.isLightweight ())
352
              {
353
                enableEvents (comp.eventMask);
354
                if (!isLightweight ())
355
                  enableEvents (AWTEvent.PAINT_EVENT_MASK);
356
              }
357
          }
358
 
359
        // Invalidate the layout of the added component and its ancestors.
360
        comp.invalidate();
361
 
362
        if (component == null)
363
          component = new Component[4]; // FIXME, better initial size?
364
 
365
        // This isn't the most efficient implementation.  We could do less
366
        // copying when growing the array.  It probably doesn't matter.
367
        if (ncomponents >= component.length)
368
          {
369
            int nl = component.length * 2;
370
            Component[] c = new Component[nl];
371
            System.arraycopy(component, 0, c, 0, ncomponents);
372
            component = c;
373
          }
374
 
375
        if (index == -1)
376
          component[ncomponents++] = comp;
377
        else
378
          {
379
            System.arraycopy(component, index, component, index + 1,
380
                             ncomponents - index);
381
            component[index] = comp;
382
            ++ncomponents;
383
          }
384
 
385
        // Notify the layout manager.
386
        if (layoutMgr != null)
387
          {
388
            if (layoutMgr instanceof LayoutManager2)
389
              {
390
                LayoutManager2 lm2 = (LayoutManager2) layoutMgr;
391
                lm2.addLayoutComponent(comp, constraints);
392
              }
393
            else if (constraints instanceof String)
394
              layoutMgr.addLayoutComponent((String) constraints, comp);
395
            else
396
              layoutMgr.addLayoutComponent(null, comp);
397
          }
398
 
399
        // We previously only sent an event when this container is showing.
400
        // Also, the event was posted to the event queue. A Mauve test shows
401
        // that this event is not delivered using the event queue and it is
402
        // also sent when the container is not showing. 
403
        ContainerEvent ce = new ContainerEvent(this,
404
                                               ContainerEvent.COMPONENT_ADDED,
405
                                               comp);
406
        ContainerListener[] listeners = getContainerListeners();
407
        for (int i = 0; i < listeners.length; i++)
408
          listeners[i].componentAdded(ce);
409
 
410
        // Repaint this container.
411
        repaint(comp.getX(), comp.getY(), comp.getWidth(),
412
                comp.getHeight());
413
      }
414
  }
415
 
416
  /**
417
   * Removes the component at the specified index from this container.
418
   *
419
   * @param index The index of the component to remove.
420
   */
421
  public void remove(int index)
422
  {
423
    synchronized (getTreeLock ())
424
      {
425
        Component r = component[index];
426
 
427
        ComponentListener[] list = r.getComponentListeners();
428
        for (int j = 0; j < list.length; j++)
429
              r.removeComponentListener(list[j]);
430
 
431
        if (r.isShowing())
432
          r.removeNotify();
433
 
434
        System.arraycopy(component, index + 1, component, index,
435
                         ncomponents - index - 1);
436
        component[--ncomponents] = null;
437
 
438
        invalidate();
439
 
440
        if (layoutMgr != null)
441
          layoutMgr.removeLayoutComponent(r);
442
 
443
        r.parent = null;
444
 
445
        if (isShowing ())
446
          {
447
            // Post event to notify of removing the component.
448
            ContainerEvent ce = new ContainerEvent(this,
449
                                                   ContainerEvent.COMPONENT_REMOVED,
450
                                                   r);
451
            getToolkit().getSystemEventQueue().postEvent(ce);
452
 
453
            // Repaint this container.
454
            repaint();
455
          }
456
      }
457
  }
458
 
459
  /**
460
   * Removes the specified component from this container.
461
   *
462
   * @param comp The component to remove from this container.
463
   */
464
  public void remove(Component comp)
465
  {
466
    synchronized (getTreeLock ())
467
      {
468
        for (int i = 0; i < ncomponents; ++i)
469
          {
470
            if (component[i] == comp)
471
              {
472
                remove(i);
473
                break;
474
              }
475
          }
476
      }
477
  }
478
 
479
  /**
480
   * Removes all components from this container.
481
   */
482
  public void removeAll()
483
  {
484
    synchronized (getTreeLock ())
485
      {
486
        while (ncomponents > 0)
487
          remove(0);
488
      }
489
  }
490
 
491
  /**
492
   * Returns the current layout manager for this container.
493
   *
494
   * @return The layout manager for this container.
495
   */
496
  public LayoutManager getLayout()
497
  {
498
    return layoutMgr;
499
  }
500
 
501
  /**
502
   * Sets the layout manager for this container to the specified layout
503
   * manager.
504
   *
505
   * @param mgr The new layout manager for this container.
506
   */
507
  public void setLayout(LayoutManager mgr)
508
  {
509
    layoutMgr = mgr;
510
    invalidate();
511
  }
512
 
513
  /**
514
   * Layout the components in this container.
515
   */
516
  public void doLayout()
517
  {
518
    layout ();
519
  }
520
 
521
  /**
522
   * Layout the components in this container.
523
   *
524
   * @deprecated use {@link #doLayout()} instead
525
   */
526
  public void layout()
527
  {
528
    if (layoutMgr != null)
529
      layoutMgr.layoutContainer (this);
530
  }
531
 
532
  /**
533
   * Invalidates this container to indicate that it (and all parent
534
   * containers) need to be laid out.
535
   */
536
  public void invalidate()
537
  {
538
    super.invalidate();
539
    if (layoutMgr != null && layoutMgr instanceof LayoutManager2)
540
      {
541
        LayoutManager2 lm2 = (LayoutManager2) layoutMgr;
542
        lm2.invalidateLayout(this);
543
      }
544
  }
545
 
546
  /**
547
   * Re-lays out the components in this container.
548
   */
549
  public void validate()
550
  {
551
    synchronized (getTreeLock ())
552
      {
553
        if (! isValid() && peer != null)
554
          {
555
            validateTree();
556
          }
557
      }
558
  }
559
 
560
  /**
561
   * Recursively invalidates the container tree.
562
   */
563
  void invalidateTree()
564
  {
565
    super.invalidate();  // Clean cached layout state.
566
    for (int i = 0; i < ncomponents; i++)
567
      {
568
        Component comp = component[i];
569
        comp.invalidate();
570
        if (comp instanceof Container)
571
          ((Container) comp).invalidateTree();
572
      }
573
 
574
    if (layoutMgr != null && layoutMgr instanceof LayoutManager2)
575
      {
576
        LayoutManager2 lm2 = (LayoutManager2) layoutMgr;
577
        lm2.invalidateLayout(this);
578
      }
579
  }
580
 
581
  /**
582
   * Recursively validates the container tree, recomputing any invalid
583
   * layouts.
584
   */
585
  protected void validateTree()
586
  {
587
    if (valid)
588
      return;
589
 
590
    ContainerPeer cPeer = null;
591
    if (peer != null && ! (peer instanceof LightweightPeer))
592
      {
593
        cPeer = (ContainerPeer) peer;
594
        cPeer.beginValidate();
595
      }
596
 
597
    for (int i = 0; i < ncomponents; ++i)
598
      {
599
        Component comp = component[i];
600
 
601
        if (comp.getPeer () == null)
602
          comp.addNotify();
603
      }
604
 
605
    doLayout ();
606
    for (int i = 0; i < ncomponents; ++i)
607
      {
608
        Component comp = component[i];
609
 
610
        if (! comp.isValid())
611
          {
612
            if (comp instanceof Container)
613
              {
614
                ((Container) comp).validateTree();
615
              }
616
            else
617
              {
618
                component[i].validate();
619
              }
620
          }
621
      }
622
 
623
    /* children will call invalidate() when they are layed out. It
624
       is therefore important that valid is not set to true
625
       until after the children have been layed out. */
626
    valid = true;
627
 
628
    if (cPeer != null)
629
      cPeer.endValidate();
630
  }
631
 
632
  public void setFont(Font f)
633
  {
634
    if( (f != null && (font == null || !font.equals(f)))
635
        || f == null)
636
      {
637
        super.setFont(f);
638
        // FIXME: Although it might make more sense to invalidate only
639
        // those children whose font == null, Sun invalidates all children.
640
        // So we'll do the same.
641
        invalidateTree();
642
      }
643
  }
644
 
645
  /**
646
   * Returns the preferred size of this container.
647
   *
648
   * @return The preferred size of this container.
649
   */
650
  public Dimension getPreferredSize()
651
  {
652
    return preferredSize ();
653
  }
654
 
655
  /**
656
   * Returns the preferred size of this container.
657
   *
658
   * @return The preferred size of this container.
659
   *
660
   * @deprecated use {@link #getPreferredSize()} instead
661
   */
662
  public Dimension preferredSize()
663
  {
664
    synchronized(treeLock)
665
      {
666
        if(valid && prefSize != null)
667
          return new Dimension(prefSize);
668
        LayoutManager layout = getLayout();
669
        if (layout != null)
670
          {
671
            Dimension layoutSize = layout.preferredLayoutSize(this);
672
            if(valid)
673
              prefSize = layoutSize;
674
            return new Dimension(layoutSize);
675
          }
676
        else
677
          return super.preferredSize ();
678
      }
679
  }
680
 
681
  /**
682
   * Returns the minimum size of this container.
683
   *
684
   * @return The minimum size of this container.
685
   */
686
  public Dimension getMinimumSize()
687
  {
688
    return minimumSize ();
689
  }
690
 
691
  /**
692
   * Returns the minimum size of this container.
693
   *
694
   * @return The minimum size of this container.
695
   *
696
   * @deprecated use {@link #getMinimumSize()} instead
697
   */
698
  public Dimension minimumSize()
699
  {
700
    if(valid && minSize != null)
701
      return new Dimension(minSize);
702
 
703
    LayoutManager layout = getLayout();
704
    if (layout != null)
705
      {
706
        minSize = layout.minimumLayoutSize (this);
707
        return minSize;
708
      }
709
    else
710
      return super.minimumSize ();
711
  }
712
 
713
  /**
714
   * Returns the maximum size of this container.
715
   *
716
   * @return The maximum size of this container.
717
   */
718
  public Dimension getMaximumSize()
719
  {
720
    if (valid && maxSize != null)
721
      return new Dimension(maxSize);
722
 
723
    LayoutManager layout = getLayout();
724
    if (layout != null && layout instanceof LayoutManager2)
725
      {
726
        LayoutManager2 lm2 = (LayoutManager2) layout;
727
        maxSize = lm2.maximumLayoutSize(this);
728
        return maxSize;
729
      }
730
    else
731
      return super.getMaximumSize();
732
  }
733
 
734
  /**
735
   * Returns the preferred alignment along the X axis.  This is a value
736
   * between 0 and 1 where 0 represents alignment flush left and
737
   * 1 means alignment flush right, and 0.5 means centered.
738
   *
739
   * @return The preferred alignment along the X axis.
740
   */
741
  public float getAlignmentX()
742
  {
743
    LayoutManager layout = getLayout();
744
    float alignmentX = 0.0F;
745
    if (layout != null && layout instanceof LayoutManager2)
746
      {
747
        LayoutManager2 lm2 = (LayoutManager2) layout;
748
        alignmentX = lm2.getLayoutAlignmentX(this);
749
      }
750
    else
751
      alignmentX = super.getAlignmentX();
752
    return alignmentX;
753
  }
754
 
755
  /**
756
   * Returns the preferred alignment along the Y axis.  This is a value
757
   * between 0 and 1 where 0 represents alignment flush top and
758
   * 1 means alignment flush bottom, and 0.5 means centered.
759
   *
760
   * @return The preferred alignment along the Y axis.
761
   */
762
  public float getAlignmentY()
763
  {
764
    LayoutManager layout = getLayout();
765
    float alignmentY = 0.0F;
766
    if (layout != null && layout instanceof LayoutManager2)
767
      {
768
        LayoutManager2 lm2 = (LayoutManager2) layout;
769
        alignmentY = lm2.getLayoutAlignmentY(this);
770
      }
771
    else
772
      alignmentY = super.getAlignmentY();
773
    return alignmentY;
774
  }
775
 
776
  /**
777
   * Paints this container.  The implementation of this method in this
778
   * class forwards to any lightweight components in this container.  If
779
   * this method is subclassed, this method should still be invoked as
780
   * a superclass method so that lightweight components are properly
781
   * drawn.
782
   *
783
   * @param g The graphics context for this paint job.
784
   */
785
  public void paint(Graphics g)
786
  {
787
    if (!isShowing())
788
      return;
789
 
790
    // Visit heavyweights as well, in case they were
791
    // erased when we cleared the background for this container.
792
    visitChildren(g, GfxPaintVisitor.INSTANCE, false);
793
  }
794
 
795
  /**
796
   * Updates this container.  The implementation of this method in this
797
   * class forwards to any lightweight components in this container.  If
798
   * this method is subclassed, this method should still be invoked as
799
   * a superclass method so that lightweight components are properly
800
   * drawn.
801
   *
802
   * @param g The graphics context for this update.
803
   *
804
   * @specnote The specification suggests that this method forwards the
805
   *           update() call to all its lightweight children. Tests show
806
   *           that this is not done either in the JDK. The exact behaviour
807
   *           seems to be that the background is cleared in heavyweight
808
   *           Containers, and all other containers
809
   *           directly call paint(), causing the (lightweight) children to
810
   *           be painted.
811
   */
812
  public void update(Graphics g)
813
  {
814
    // It seems that the JDK clears the background of containers like Panel
815
    // and Window (within this method) but not of 'plain' Containers or
816
    // JComponents. This could
817
    // lead to the assumption that it only clears heavyweight containers.
818
    // However that is not quite true. In a test with a custom Container
819
    // that overrides isLightweight() to return false, the background is
820
    // also not cleared. So we do a check on !(peer instanceof LightweightPeer)
821
    // instead.
822
    ComponentPeer p = peer;
823
    if (p != null && !(p instanceof LightweightPeer))
824
      g.clearRect(0, 0, getWidth(), getHeight());
825
 
826
    paint(g);
827
  }
828
 
829
  /**
830
   * Prints this container.  The implementation of this method in this
831
   * class forwards to any lightweight components in this container.  If
832
   * this method is subclassed, this method should still be invoked as
833
   * a superclass method so that lightweight components are properly
834
   * drawn.
835
   *
836
   * @param g The graphics context for this print job.
837
   */
838
  public void print(Graphics g)
839
  {
840
    super.print(g);
841
    visitChildren(g, GfxPrintVisitor.INSTANCE, true);
842
  }
843
 
844
  /**
845
   * Paints all of the components in this container.
846
   *
847
   * @param g The graphics context for this paint job.
848
   */
849
  public void paintComponents(Graphics g)
850
  {
851
    paint(g);
852
    visitChildren(g, GfxPaintAllVisitor.INSTANCE, true);
853
  }
854
 
855
  /**
856
   * Prints all of the components in this container.
857
   *
858
   * @param g The graphics context for this print job.
859
   */
860
  public void printComponents(Graphics g)
861
  {
862
    super.paint(g);
863
    visitChildren(g, GfxPrintAllVisitor.INSTANCE, true);
864
  }
865
 
866
  /**
867
   * Adds the specified container listener to this object's list of
868
   * container listeners.
869
   *
870
   * @param listener The listener to add.
871
   */
872
  public synchronized void addContainerListener(ContainerListener listener)
873
  {
874
    containerListener = AWTEventMulticaster.add(containerListener, listener);
875
  }
876
 
877
  /**
878
   * Removes the specified container listener from this object's list of
879
   * container listeners.
880
   *
881
   * @param listener The listener to remove.
882
   */
883
  public synchronized void removeContainerListener(ContainerListener listener)
884
  {
885
    containerListener = AWTEventMulticaster.remove(containerListener, listener);
886
  }
887
 
888
  /**
889
   * @since 1.4
890
   */
891
  public synchronized ContainerListener[] getContainerListeners()
892
  {
893
    return (ContainerListener[])
894
      AWTEventMulticaster.getListeners(containerListener,
895
                                       ContainerListener.class);
896
  }
897
 
898
  /**
899
   * Returns an array of all the objects currently registered as FooListeners
900
   * upon this Container. FooListeners are registered using the addFooListener
901
   * method.
902
   *
903
   * @exception ClassCastException If listenerType doesn't specify a class or
904
   * interface that implements @see java.util.EventListener.
905
   *
906
   * @since 1.3
907
   */
908
  public EventListener[] getListeners(Class listenerType)
909
  {
910
    if (listenerType == ContainerListener.class)
911
      return getContainerListeners();
912
    return super.getListeners(listenerType);
913
  }
914
 
915
  /**
916
   * Processes the specified event.  This method calls
917
   * <code>processContainerEvent()</code> if this method is a
918
   * <code>ContainerEvent</code>, otherwise it calls the superclass
919
   * method.
920
   *
921
   * @param e The event to be processed.
922
   */
923
  protected void processEvent(AWTEvent e)
924
  {
925
    if (e instanceof ContainerEvent)
926
      processContainerEvent((ContainerEvent) e);
927
    else
928
      super.processEvent(e);
929
  }
930
 
931
  /**
932
   * Called when a container event occurs if container events are enabled.
933
   * This method calls any registered listeners.
934
   *
935
   * @param e The event that occurred.
936
   */
937
  protected void processContainerEvent(ContainerEvent e)
938
  {
939
    if (containerListener == null)
940
      return;
941
    switch (e.id)
942
      {
943
      case ContainerEvent.COMPONENT_ADDED:
944
        containerListener.componentAdded(e);
945
        break;
946
 
947
      case ContainerEvent.COMPONENT_REMOVED:
948
        containerListener.componentRemoved(e);
949
        break;
950
      }
951
  }
952
 
953
  /**
954
   * AWT 1.0 event processor.
955
   *
956
   * @param e The event that occurred.
957
   *
958
   * @deprecated use {@link #dispatchEvent(AWTEvent)} instead
959
   */
960
  public void deliverEvent(Event e)
961
  {
962
    if (!handleEvent (e))
963
      {
964
        synchronized (getTreeLock ())
965
          {
966
            Component parent = getParent ();
967
 
968
            if (parent != null)
969
              parent.deliverEvent (e);
970
          }
971
      }
972
  }
973
 
974
  /**
975
   * Returns the component located at the specified point.  This is done
976
   * by checking whether or not a child component claims to contain this
977
   * point.  The first child component that does is returned.  If no
978
   * child component claims the point, the container itself is returned,
979
   * unless the point does not exist within this container, in which
980
   * case <code>null</code> is returned.
981
   *
982
   * @param x The X coordinate of the point.
983
   * @param y The Y coordinate of the point.
984
   *
985
   * @return The component containing the specified point, or
986
   * <code>null</code> if there is no such point.
987
   */
988
  public Component getComponentAt(int x, int y)
989
  {
990
    return locate (x, y);
991
  }
992
 
993
  /**
994
   * Returns the component located at the specified point.  This is done
995
   * by checking whether or not a child component claims to contain this
996
   * point.  The first child component that does is returned.  If no
997
   * child component claims the point, the container itself is returned,
998
   * unless the point does not exist within this container, in which
999
   * case <code>null</code> is returned.
1000
   *
1001
   * @param x The x position of the point to return the component at.
1002
   * @param y The y position of the point to return the component at.
1003
   *
1004
   * @return The component containing the specified point, or <code>null</code>
1005
   * if there is no such point.
1006
   *
1007
   * @deprecated use {@link #getComponentAt(int, int)} instead
1008
   */
1009
  public Component locate(int x, int y)
1010
  {
1011
    synchronized (getTreeLock ())
1012
      {
1013
        if (!contains (x, y))
1014
          return null;
1015
        for (int i = 0; i < ncomponents; ++i)
1016
          {
1017
            // Ignore invisible children...
1018
            if (!component[i].isVisible ())
1019
              continue;
1020
 
1021
            int x2 = x - component[i].x;
1022
            int y2 = y - component[i].y;
1023
            if (component[i].contains (x2, y2))
1024
              return component[i];
1025
          }
1026
        return this;
1027
      }
1028
  }
1029
 
1030
  /**
1031
   * Returns the component located at the specified point.  This is done
1032
   * by checking whether or not a child component claims to contain this
1033
   * point.  The first child component that does is returned.  If no
1034
   * child component claims the point, the container itself is returned,
1035
   * unless the point does not exist within this container, in which
1036
   * case <code>null</code> is returned.
1037
   *
1038
   * @param p The point to return the component at.
1039
   * @return The component containing the specified point, or <code>null</code>
1040
   * if there is no such point.
1041
   */
1042
  public Component getComponentAt(Point p)
1043
  {
1044
    return getComponentAt (p.x, p.y);
1045
  }
1046
 
1047
  public Component findComponentAt(int x, int y)
1048
  {
1049
    synchronized (getTreeLock ())
1050
      {
1051
        if (! contains(x, y))
1052
          return null;
1053
 
1054
        for (int i = 0; i < ncomponents; ++i)
1055
          {
1056
            // Ignore invisible children...
1057
            if (!component[i].isVisible())
1058
              continue;
1059
 
1060
            int x2 = x - component[i].x;
1061
            int y2 = y - component[i].y;
1062
            // We don't do the contains() check right away because
1063
            // findComponentAt would redundantly do it first thing.
1064
            if (component[i] instanceof Container)
1065
              {
1066
                Container k = (Container) component[i];
1067
                Component r = k.findComponentAt(x2, y2);
1068
                if (r != null)
1069
                  return r;
1070
              }
1071
            else if (component[i].contains(x2, y2))
1072
              return component[i];
1073
          }
1074
 
1075
        return this;
1076
      }
1077
  }
1078
 
1079
  /**
1080
   * Finds the visible child component that contains the specified position.
1081
   * The top-most child is returned in the case where there is overlap.
1082
   * If the top-most child is transparent and has no MouseListeners attached,
1083
   * we discard it and return the next top-most component containing the
1084
   * specified position.
1085
   * @param x the x coordinate
1086
   * @param y the y coordinate
1087
   * @return null if the <code>this</code> does not contain the position,
1088
   * otherwise the top-most component (out of this container itself and
1089
   * its descendants) meeting the criteria above.
1090
   */
1091
  Component findComponentForMouseEventAt(int x, int y)
1092
  {
1093
    synchronized (getTreeLock())
1094
      {
1095
        if (!contains(x, y))
1096
          return null;
1097
 
1098
        for (int i = 0; i < ncomponents; ++i)
1099
          {
1100
            // Ignore invisible children...
1101
            if (!component[i].isVisible())
1102
              continue;
1103
 
1104
            int x2 = x - component[i].x;
1105
            int y2 = y - component[i].y;
1106
            // We don't do the contains() check right away because
1107
            // findComponentAt would redundantly do it first thing.
1108
            if (component[i] instanceof Container)
1109
              {
1110
                Container k = (Container) component[i];
1111
                Component r = k.findComponentForMouseEventAt(x2, y2);
1112
                if (r != null)
1113
                  return r;
1114
              }
1115
            else if (component[i].contains(x2, y2))
1116
              return component[i];
1117
          }
1118
 
1119
        //don't return transparent components with no MouseListeners
1120
        if (this.getMouseListeners().length == 0)
1121
          return null;
1122
        return this;
1123
      }
1124
  }
1125
 
1126
  public Component findComponentAt(Point p)
1127
  {
1128
    return findComponentAt(p.x, p.y);
1129
  }
1130
 
1131
  /**
1132
   * Called when this container is added to another container to inform it
1133
   * to create its peer.  Peers for any child components will also be
1134
   * created.
1135
   */
1136
  public void addNotify()
1137
  {
1138
    super.addNotify();
1139
    addNotifyContainerChildren();
1140
  }
1141
 
1142
  /**
1143
   * Called when this container is removed from its parent container to
1144
   * inform it to destroy its peer.  This causes the peers of all child
1145
   * component to be destroyed as well.
1146
   */
1147
  public void removeNotify()
1148
  {
1149
    synchronized (getTreeLock ())
1150
      {
1151
        for (int i = 0; i < ncomponents; ++i)
1152
          component[i].removeNotify();
1153
        super.removeNotify();
1154
      }
1155
  }
1156
 
1157
  /**
1158
   * Tests whether or not the specified component is contained within
1159
   * this components subtree.
1160
   *
1161
   * @param comp The component to test.
1162
   *
1163
   * @return <code>true</code> if this container is an ancestor of the
1164
   * specified component, <code>false</code> otherwise.
1165
   */
1166
  public boolean isAncestorOf(Component comp)
1167
  {
1168
    synchronized (getTreeLock ())
1169
      {
1170
        while (true)
1171
          {
1172
            if (comp == null)
1173
              return false;
1174
            if (comp == this)
1175
              return true;
1176
            comp = comp.getParent();
1177
          }
1178
      }
1179
  }
1180
 
1181
  /**
1182
   * Returns a string representing the state of this container for
1183
   * debugging purposes.
1184
   *
1185
   * @return A string representing the state of this container.
1186
   */
1187
  protected String paramString()
1188
  {
1189
    if (layoutMgr == null)
1190
      return super.paramString();
1191
 
1192
    StringBuffer sb = new StringBuffer();
1193
    sb.append(super.paramString());
1194
    sb.append(",layout=");
1195
    sb.append(layoutMgr.getClass().getName());
1196
    return sb.toString();
1197
  }
1198
 
1199
  /**
1200
   * Writes a listing of this container to the specified stream starting
1201
   * at the specified indentation point.
1202
   *
1203
   * @param out The <code>PrintStream</code> to write to.
1204
   * @param indent The indentation point.
1205
   */
1206
  public void list(PrintStream out, int indent)
1207
  {
1208
    synchronized (getTreeLock ())
1209
      {
1210
        super.list(out, indent);
1211
        for (int i = 0; i < ncomponents; ++i)
1212
          component[i].list(out, indent + 2);
1213
      }
1214
  }
1215
 
1216
  /**
1217
   * Writes a listing of this container to the specified stream starting
1218
   * at the specified indentation point.
1219
   *
1220
   * @param out The <code>PrintWriter</code> to write to.
1221
   * @param indent The indentation point.
1222
   */
1223
  public void list(PrintWriter out, int indent)
1224
  {
1225
    synchronized (getTreeLock ())
1226
      {
1227
        super.list(out, indent);
1228
        for (int i = 0; i < ncomponents; ++i)
1229
          component[i].list(out, indent + 2);
1230
      }
1231
  }
1232
 
1233
  /**
1234
   * Sets the focus traversal keys for a given traversal operation for this
1235
   * Container.
1236
   *
1237
   * @exception IllegalArgumentException If id is not one of
1238
   * KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
1239
   * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
1240
   * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS,
1241
   * or KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS,
1242
   * or if keystrokes contains null, or if any Object in keystrokes is not an
1243
   * AWTKeyStroke, or if any keystroke represents a KEY_TYPED event, or if any
1244
   * keystroke already maps to another focus traversal operation for this
1245
   * Container.
1246
   *
1247
   * @since 1.4
1248
   */
1249
  public void setFocusTraversalKeys(int id, Set keystrokes)
1250
  {
1251
    if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
1252
        id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
1253
        id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS &&
1254
        id != KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS)
1255
      throw new IllegalArgumentException ();
1256
 
1257
    if (keystrokes == null)
1258
      {
1259
        Container parent = getParent ();
1260
 
1261
        while (parent != null)
1262
          {
1263
            if (parent.areFocusTraversalKeysSet (id))
1264
              {
1265
                keystrokes = parent.getFocusTraversalKeys (id);
1266
                break;
1267
              }
1268
            parent = parent.getParent ();
1269
          }
1270
 
1271
        if (keystrokes == null)
1272
          keystrokes = KeyboardFocusManager.getCurrentKeyboardFocusManager ().
1273
            getDefaultFocusTraversalKeys (id);
1274
      }
1275
 
1276
    Set sa;
1277
    Set sb;
1278
    Set sc;
1279
    String name;
1280
    switch (id)
1281
      {
1282
      case KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS:
1283
        sa = getFocusTraversalKeys
1284
          (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
1285
        sb = getFocusTraversalKeys
1286
          (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
1287
        sc = getFocusTraversalKeys
1288
          (KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS);
1289
        name = "forwardFocusTraversalKeys";
1290
        break;
1291
      case KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS:
1292
        sa = getFocusTraversalKeys
1293
          (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
1294
        sb = getFocusTraversalKeys
1295
          (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
1296
        sc = getFocusTraversalKeys
1297
          (KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS);
1298
        name = "backwardFocusTraversalKeys";
1299
        break;
1300
      case KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS:
1301
        sa = getFocusTraversalKeys
1302
          (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
1303
        sb = getFocusTraversalKeys
1304
          (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
1305
        sc = getFocusTraversalKeys
1306
          (KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS);
1307
        name = "upCycleFocusTraversalKeys";
1308
        break;
1309
      case KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS:
1310
        sa = getFocusTraversalKeys
1311
          (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
1312
        sb = getFocusTraversalKeys
1313
          (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
1314
        sc = getFocusTraversalKeys
1315
          (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
1316
        name = "downCycleFocusTraversalKeys";
1317
        break;
1318
      default:
1319
        throw new IllegalArgumentException ();
1320
      }
1321
 
1322
    int i = keystrokes.size ();
1323
    Iterator iter = keystrokes.iterator ();
1324
 
1325
    while (--i >= 0)
1326
      {
1327
        Object o = iter.next ();
1328
        if (!(o instanceof AWTKeyStroke)
1329
            || sa.contains (o) || sb.contains (o) || sc.contains (o)
1330
            || ((AWTKeyStroke) o).keyCode == KeyEvent.VK_UNDEFINED)
1331
          throw new IllegalArgumentException ();
1332
      }
1333
 
1334
    if (focusTraversalKeys == null)
1335
      focusTraversalKeys = new Set[4];
1336
 
1337
    keystrokes = Collections.unmodifiableSet (new HashSet (keystrokes));
1338
    firePropertyChange (name, focusTraversalKeys[id], keystrokes);
1339
 
1340
    focusTraversalKeys[id] = keystrokes;
1341
  }
1342
 
1343
  /**
1344
   * Returns the Set of focus traversal keys for a given traversal operation for
1345
   * this Container.
1346
   *
1347
   * @exception IllegalArgumentException If id is not one of
1348
   * KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
1349
   * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
1350
   * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS,
1351
   * or KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS.
1352
   *
1353
   * @since 1.4
1354
   */
1355
  public Set getFocusTraversalKeys (int id)
1356
  {
1357
    if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
1358
        id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
1359
        id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS &&
1360
        id != KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS)
1361
      throw new IllegalArgumentException ();
1362
 
1363
    Set s = null;
1364
 
1365
    if (focusTraversalKeys != null)
1366
      s = focusTraversalKeys[id];
1367
 
1368
    if (s == null && parent != null)
1369
      s = parent.getFocusTraversalKeys (id);
1370
 
1371
    return s == null ? (KeyboardFocusManager.getCurrentKeyboardFocusManager()
1372
                        .getDefaultFocusTraversalKeys(id)) : s;
1373
  }
1374
 
1375
  /**
1376
   * Returns whether the Set of focus traversal keys for the given focus
1377
   * traversal operation has been explicitly defined for this Container.
1378
   * If this method returns false, this Container is inheriting the Set from
1379
   * an ancestor, or from the current KeyboardFocusManager.
1380
   *
1381
   * @exception IllegalArgumentException If id is not one of
1382
   * KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
1383
   * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
1384
   * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS,
1385
   * or KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS.
1386
   *
1387
   * @since 1.4
1388
   */
1389
  public boolean areFocusTraversalKeysSet (int id)
1390
  {
1391
    if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
1392
        id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
1393
        id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS &&
1394
        id != KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS)
1395
      throw new IllegalArgumentException ();
1396
 
1397
    return focusTraversalKeys != null && focusTraversalKeys[id] != null;
1398
  }
1399
 
1400
  /**
1401
   * Check whether the given Container is the focus cycle root of this
1402
   * Container's focus traversal cycle.  If this Container is a focus
1403
   * cycle root itself, then it will be in two different focus cycles
1404
   * -- it's own, and that of its ancestor focus cycle root's.  In
1405
   * that case, if <code>c</code> is either of those containers, this
1406
   * method will return true.
1407
   *
1408
   * @param c the candidate Container
1409
   *
1410
   * @return true if c is the focus cycle root of the focus traversal
1411
   * cycle to which this Container belongs, false otherwise
1412
   *
1413
   * @since 1.4
1414
   */
1415
  public boolean isFocusCycleRoot (Container c)
1416
  {
1417
    if (this == c
1418
        && isFocusCycleRoot ())
1419
      return true;
1420
 
1421
    Container ancestor = getFocusCycleRootAncestor ();
1422
 
1423
    if (c == ancestor)
1424
      return true;
1425
 
1426
    return false;
1427
  }
1428
 
1429
  /**
1430
   * If this Container is a focus cycle root, set the focus traversal
1431
   * policy that determines the focus traversal order for its
1432
   * children.  If non-null, this policy will be inherited by all
1433
   * inferior focus cycle roots.  If <code>policy</code> is null, this
1434
   * Container will inherit its policy from the closest ancestor focus
1435
   * cycle root that's had its policy set.
1436
   *
1437
   * @param policy the new focus traversal policy for this Container or null
1438
   *
1439
   * @since 1.4
1440
   */
1441
  public void setFocusTraversalPolicy (FocusTraversalPolicy policy)
1442
  {
1443
    focusTraversalPolicy = policy;
1444
  }
1445
 
1446
  /**
1447
   * Return the focus traversal policy that determines the focus
1448
   * traversal order for this Container's children.  This method
1449
   * returns null if this Container is not a focus cycle root.  If the
1450
   * focus traversal policy has not been set explicitly, then this
1451
   * method will return an ancestor focus cycle root's policy instead.
1452
   *
1453
   * @return this Container's focus traversal policy or null
1454
   *
1455
   * @since 1.4
1456
   */
1457
  public FocusTraversalPolicy getFocusTraversalPolicy ()
1458
  {
1459
    if (!isFocusCycleRoot ())
1460
      return null;
1461
 
1462
    if (focusTraversalPolicy == null)
1463
      {
1464
        Container ancestor = getFocusCycleRootAncestor ();
1465
 
1466
        if (ancestor != this)
1467
          return ancestor.getFocusTraversalPolicy ();
1468
        else
1469
          {
1470
            KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
1471
 
1472
            return manager.getDefaultFocusTraversalPolicy ();
1473
          }
1474
      }
1475
    else
1476
      return focusTraversalPolicy;
1477
  }
1478
 
1479
  /**
1480
   * Check whether this Container's focus traversal policy has been
1481
   * explicitly set.  If it has not, then this Container will inherit
1482
   * its focus traversal policy from one of its ancestor focus cycle
1483
   * roots.
1484
   *
1485
   * @return true if focus traversal policy is set, false otherwise
1486
  */
1487
  public boolean isFocusTraversalPolicySet ()
1488
  {
1489
    return focusTraversalPolicy == null;
1490
  }
1491
 
1492
  /**
1493
   * Set whether or not this Container is the root of a focus
1494
   * traversal cycle.  This Container's focus traversal policy
1495
   * determines the order of focus traversal.  Some policies prevent
1496
   * the focus from being transferred between two traversal cycles
1497
   * until an up or down traversal operation is performed.  In that
1498
   * case, normal traversal (not up or down) is limited to this
1499
   * Container and all of this Container's descendents that are not
1500
   * descendents of inferior focus cycle roots.  In the default case
1501
   * however, ContainerOrderFocusTraversalPolicy is in effect, and it
1502
   * supports implicit down-cycle traversal operations.
1503
   *
1504
   * @param focusCycleRoot true if this is a focus cycle root, false otherwise
1505
   *
1506
   * @since 1.4
1507
   */
1508
  public void setFocusCycleRoot (boolean focusCycleRoot)
1509
  {
1510
    this.focusCycleRoot = focusCycleRoot;
1511
  }
1512
 
1513
  /**
1514
   * Check whether this Container is a focus cycle root.
1515
   *
1516
   * @return true if this is a focus cycle root, false otherwise
1517
   *
1518
   * @since 1.4
1519
   */
1520
  public boolean isFocusCycleRoot ()
1521
  {
1522
    return focusCycleRoot;
1523
  }
1524
 
1525
  /**
1526
   * Transfer focus down one focus traversal cycle.  If this Container
1527
   * is a focus cycle root, then its default component becomes the
1528
   * focus owner, and this Container becomes the current focus cycle
1529
   * root.  No traversal will occur if this Container is not a focus
1530
   * cycle root.
1531
   *
1532
   * @since 1.4
1533
   */
1534
  public void transferFocusDownCycle ()
1535
  {
1536
    KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
1537
 
1538
    manager.downFocusCycle (this);
1539
  }
1540
 
1541
  /**
1542
   * Sets the ComponentOrientation property of this container and all components
1543
   * contained within it.
1544
   *
1545
   * @exception NullPointerException If orientation is null
1546
   *
1547
   * @since 1.4
1548
   */
1549
  public void applyComponentOrientation (ComponentOrientation orientation)
1550
  {
1551
    if (orientation == null)
1552
      throw new NullPointerException ();
1553
  }
1554
 
1555
  public void addPropertyChangeListener (PropertyChangeListener listener)
1556
  {
1557
    if (listener == null)
1558
      return;
1559
 
1560
    if (changeSupport == null)
1561
      changeSupport = new PropertyChangeSupport (this);
1562
 
1563
    changeSupport.addPropertyChangeListener (listener);
1564
  }
1565
 
1566
  public void addPropertyChangeListener (String name,
1567
                                         PropertyChangeListener listener)
1568
  {
1569
    if (listener == null)
1570
      return;
1571
 
1572
    if (changeSupport == null)
1573
      changeSupport = new PropertyChangeSupport (this);
1574
 
1575
    changeSupport.addPropertyChangeListener (name, listener);
1576
  }
1577
 
1578
  // Hidden helper methods.
1579
 
1580
  /**
1581
   * Perform a graphics operation on the children of this container.
1582
   * For each applicable child, the visitChild() method will be called
1583
   * to perform the graphics operation.
1584
   *
1585
   * @param gfx The graphics object that will be used to derive new
1586
   * graphics objects for the children.
1587
   *
1588
   * @param visitor Object encapsulating the graphics operation that
1589
   * should be performed.
1590
   *
1591
   * @param lightweightOnly If true, only lightweight components will
1592
   * be visited.
1593
   */
1594
  private void visitChildren(Graphics gfx, GfxVisitor visitor,
1595
                             boolean lightweightOnly)
1596
  {
1597
    synchronized (getTreeLock ())
1598
      {
1599
        for (int i = ncomponents - 1; i >= 0; --i)
1600
          {
1601
            Component comp = component[i];
1602
            boolean applicable = comp.isVisible()
1603
              && (comp.isLightweight() || !lightweightOnly);
1604
 
1605
            if (applicable)
1606
              visitChild(gfx, visitor, comp);
1607
          }
1608
      }
1609
  }
1610
 
1611
  /**
1612
   * Perform a graphics operation on a child. A translated and clipped
1613
   * graphics object will be created, and the visit() method of the
1614
   * visitor will be called to perform the operation.
1615
   *
1616
   * @param gfx The graphics object that will be used to derive new
1617
   * graphics objects for the child.
1618
   *
1619
   * @param visitor Object encapsulating the graphics operation that
1620
   * should be performed.
1621
   *
1622
   * @param comp The child component that should be visited.
1623
   */
1624
  private void visitChild(Graphics gfx, GfxVisitor visitor,
1625
                          Component comp)
1626
  {
1627
    Rectangle bounds = comp.getBounds();
1628
    Rectangle oldClip = gfx.getClipBounds();
1629
    if (oldClip == null)
1630
      oldClip = bounds;
1631
 
1632
    Rectangle clip = oldClip.intersection(bounds);
1633
 
1634
    if (clip.isEmpty()) return;
1635
 
1636
    boolean clipped = false;
1637
    boolean translated = false;
1638
    try
1639
      {
1640
        gfx.setClip(clip.x, clip.y, clip.width, clip.height);
1641
        clipped = true;
1642
        gfx.translate(bounds.x, bounds.y);
1643
        translated = true;
1644
        visitor.visit(comp, gfx);
1645
      }
1646
    finally
1647
      {
1648
        if (translated)
1649
          gfx.translate (-bounds.x, -bounds.y);
1650
        if (clipped)
1651
          gfx.setClip (oldClip.x, oldClip.y, oldClip.width, oldClip.height);
1652
      }
1653
  }
1654
 
1655
  void dispatchEventImpl(AWTEvent e)
1656
  {
1657
    // Give lightweight dispatcher a chance to handle it.
1658
    if (dispatcher != null && dispatcher.handleEvent (e))
1659
      return;
1660
 
1661
    if ((e.id <= ContainerEvent.CONTAINER_LAST
1662
             && e.id >= ContainerEvent.CONTAINER_FIRST)
1663
        && (containerListener != null
1664
            || (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0))
1665
      processEvent(e);
1666
    else
1667
      super.dispatchEventImpl(e);
1668
  }
1669
 
1670
  /**
1671
   * Tests if this container has an interest in the given event id.
1672
   *
1673
   * @param eventId The event id to check.
1674
   *
1675
   * @return <code>true</code> if a listener for the event id exists or
1676
   *         if the eventMask is set for the event id.
1677
   *
1678
   * @see java.awt.Component#eventTypeEnabled(int)
1679
   */
1680
  boolean eventTypeEnabled(int eventId)
1681
  {
1682
    if(eventId <= ContainerEvent.CONTAINER_LAST
1683
       && eventId >= ContainerEvent.CONTAINER_FIRST)
1684
      return containerListener != null
1685
        || (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0;
1686
      else
1687
        return super.eventTypeEnabled(eventId);
1688
  }
1689
 
1690
  // This is used to implement Component.transferFocus.
1691
  Component findNextFocusComponent(Component child)
1692
  {
1693
    synchronized (getTreeLock ())
1694
      {
1695
        int start, end;
1696
        if (child != null)
1697
          {
1698
            for (start = 0; start < ncomponents; ++start)
1699
              {
1700
                if (component[start] == child)
1701
                  break;
1702
              }
1703
            end = start;
1704
            // This special case lets us be sure to terminate.
1705
            if (end == 0)
1706
              end = ncomponents;
1707
            ++start;
1708
          }
1709
        else
1710
          {
1711
            start = 0;
1712
            end = ncomponents;
1713
          }
1714
 
1715
        for (int j = start; j != end; ++j)
1716
          {
1717
            if (j >= ncomponents)
1718
              {
1719
                // The JCL says that we should wrap here.  However, that
1720
                // seems wrong.  To me it seems that focus order should be
1721
                // global within in given window.  So instead if we reach
1722
                // the end we try to look in our parent, if we have one.
1723
                if (parent != null)
1724
                  return parent.findNextFocusComponent(this);
1725
                j -= ncomponents;
1726
              }
1727
            if (component[j] instanceof Container)
1728
              {
1729
                Component c = component[j];
1730
                c = c.findNextFocusComponent(null);
1731
                if (c != null)
1732
                  return c;
1733
              }
1734
            else if (component[j].isFocusTraversable())
1735
              return component[j];
1736
          }
1737
 
1738
        return null;
1739
      }
1740
  }
1741
 
1742
  private void addNotifyContainerChildren()
1743
  {
1744
    synchronized (getTreeLock ())
1745
      {
1746
        for (int i = ncomponents;  --i >= 0; )
1747
          {
1748
            component[i].addNotify();
1749
            if (component[i].isLightweight ())
1750
              {
1751
 
1752
                // If we're not lightweight, and we just got a lightweight
1753
                // child, we need a lightweight dispatcher to feed it events.
1754
                if (!this.isLightweight() && dispatcher == null)
1755
                  dispatcher = new LightweightDispatcher (this);
1756
 
1757
                if (dispatcher != null)
1758
                  dispatcher.enableEvents(component[i].eventMask);
1759
 
1760
                enableEvents(component[i].eventMask);
1761
                if (peer != null && !isLightweight ())
1762
                  enableEvents (AWTEvent.PAINT_EVENT_MASK);
1763
              }
1764
          }
1765
      }
1766
  }
1767
 
1768
  /**
1769
   * Deserialize this Container:
1770
   * <ol>
1771
   * <li>Read from the stream the default serializable fields.</li>
1772
   * <li>Read a list of serializable ContainerListeners as optional
1773
   * data.  If the list is null, no listeners will be registered.</li>
1774
   * <li>Read this Container's FocusTraversalPolicy as optional data.
1775
   * If this is null, then this Container will use a
1776
   * DefaultFocusTraversalPolicy.</li>
1777
   * </ol>
1778
   *
1779
   * @param s the stream to read from
1780
   * @throws ClassNotFoundException if deserialization fails
1781
   * @throws IOException if the stream fails
1782
   */
1783
  private void readObject (ObjectInputStream s)
1784
    throws ClassNotFoundException, IOException
1785
  {
1786
    s.defaultReadObject ();
1787
    String key = (String) s.readObject ();
1788
    while (key != null)
1789
      {
1790
        Object object = s.readObject ();
1791
        if ("containerL".equals (key))
1792
          addContainerListener((ContainerListener) object);
1793
        // FIXME: under what key is the focus traversal policy stored?
1794
        else if ("focusTraversalPolicy".equals (key))
1795
          setFocusTraversalPolicy ((FocusTraversalPolicy) object);
1796
 
1797
        key = (String) s.readObject();
1798
      }
1799
  }
1800
 
1801
  /**
1802
   * Serialize this Container:
1803
   * <ol>
1804
   * <li>Write to the stream the default serializable fields.</li>
1805
   * <li>Write the list of serializable ContainerListeners as optional
1806
   * data.</li>
1807
   * <li>Write this Container's FocusTraversalPolicy as optional data.</li>
1808
   * </ol>
1809
   *
1810
   * @param s the stream to write to
1811
   * @throws IOException if the stream fails
1812
   */
1813
  private void writeObject (ObjectOutputStream s) throws IOException
1814
  {
1815
    s.defaultWriteObject ();
1816
    AWTEventMulticaster.save (s, "containerL", containerListener);
1817
    if (focusTraversalPolicy instanceof Serializable)
1818
      s.writeObject (focusTraversalPolicy);
1819
    else
1820
      s.writeObject (null);
1821
  }
1822
 
1823
  // Nested classes.
1824
 
1825
  /* The following classes are used in concert with the
1826
     visitChildren() method to implement all the graphics operations
1827
     that requires traversal of the containment hierarchy. */
1828
 
1829
  abstract static class GfxVisitor
1830
  {
1831
    public abstract void visit(Component c, Graphics gfx);
1832
  }
1833
 
1834
  static class GfxPaintVisitor extends GfxVisitor
1835
  {
1836
    public static final GfxVisitor INSTANCE = new GfxPaintVisitor();
1837
 
1838
    public void visit(Component c, Graphics gfx)
1839
    {
1840
      c.paint(gfx);
1841
    }
1842
  }
1843
 
1844
  static class GfxPrintVisitor extends GfxVisitor
1845
  {
1846
    public static final GfxVisitor INSTANCE = new GfxPrintVisitor();
1847
 
1848
    public void visit(Component c, Graphics gfx)
1849
    {
1850
      c.print(gfx);
1851
    }
1852
  }
1853
 
1854
  static class GfxPaintAllVisitor extends GfxVisitor
1855
  {
1856
    public static final GfxVisitor INSTANCE = new GfxPaintAllVisitor();
1857
 
1858
    public void visit(Component c, Graphics gfx)
1859
    {
1860
      c.paintAll(gfx);
1861
    }
1862
  }
1863
 
1864
  static class GfxPrintAllVisitor extends GfxVisitor
1865
  {
1866
    public static final GfxVisitor INSTANCE = new GfxPrintAllVisitor();
1867
 
1868
    public void visit(Component c, Graphics gfx)
1869
    {
1870
      c.printAll(gfx);
1871
    }
1872
  }
1873
 
1874
  /**
1875
   * This class provides accessibility support for subclasses of container.
1876
   *
1877
   * @author Eric Blake (ebb9@email.byu.edu)
1878
   *
1879
   * @since 1.3
1880
   */
1881
  protected class AccessibleAWTContainer extends AccessibleAWTComponent
1882
  {
1883
    /**
1884
     * Compatible with JDK 1.4+.
1885
     */
1886
    private static final long serialVersionUID = 5081320404842566097L;
1887
 
1888
    /**
1889
     * The handler to fire PropertyChange when children are added or removed.
1890
     *
1891
     * @serial the handler for property changes
1892
     */
1893
    protected ContainerListener accessibleContainerHandler
1894
      = new AccessibleContainerHandler();
1895
 
1896
    /**
1897
     * The default constructor.
1898
     */
1899
    protected AccessibleAWTContainer()
1900
    {
1901
      Container.this.addContainerListener(accessibleContainerHandler);
1902
    }
1903
 
1904
    /**
1905
     * Return the number of accessible children of the containing accessible
1906
     * object (at most the total number of its children).
1907
     *
1908
     * @return the number of accessible children
1909
     */
1910
    public int getAccessibleChildrenCount()
1911
    {
1912
      synchronized (getTreeLock ())
1913
        {
1914
          int count = 0;
1915
          int i = component == null ? 0 : component.length;
1916
          while (--i >= 0)
1917
            if (component[i] instanceof Accessible)
1918
              count++;
1919
          return count;
1920
        }
1921
    }
1922
 
1923
    /**
1924
     * Return the nth accessible child of the containing accessible object.
1925
     *
1926
     * @param i the child to grab, zero-based
1927
     * @return the accessible child, or null
1928
     */
1929
    public Accessible getAccessibleChild(int i)
1930
    {
1931
      synchronized (getTreeLock ())
1932
        {
1933
          if (component == null)
1934
            return null;
1935
          int index = -1;
1936
          while (i >= 0 && ++index < component.length)
1937
            if (component[index] instanceof Accessible)
1938
              i--;
1939
          if (i < 0)
1940
            return (Accessible) component[index];
1941
          return null;
1942
        }
1943
    }
1944
 
1945
    /**
1946
     * Return the accessible child located at point (in the parent's
1947
     * coordinates), if one exists.
1948
     *
1949
     * @param p the point to look at
1950
     *
1951
     * @return an accessible object at that point, or null
1952
     *
1953
     * @throws NullPointerException if p is null
1954
     */
1955
    public Accessible getAccessibleAt(Point p)
1956
    {
1957
      Component c = getComponentAt(p.x, p.y);
1958
      return c != Container.this && c instanceof Accessible ? (Accessible) c
1959
        : null;
1960
    }
1961
 
1962
    /**
1963
     * This class fires a <code>PropertyChange</code> listener, if registered,
1964
     * when children are added or removed from the enclosing accessible object.
1965
     *
1966
     * @author Eric Blake (ebb9@email.byu.edu)
1967
     *
1968
     * @since 1.3
1969
     */
1970
    protected class AccessibleContainerHandler implements ContainerListener
1971
    {
1972
      /**
1973
       * Default constructor.
1974
       */
1975
      protected AccessibleContainerHandler()
1976
      {
1977
        // Nothing to do here.
1978
      }
1979
 
1980
      /**
1981
       * Fired when a component is added; forwards to the PropertyChange
1982
       * listener.
1983
       *
1984
       * @param e the container event for adding
1985
       */
1986
      public void componentAdded(ContainerEvent e)
1987
      {
1988
        AccessibleAWTContainer.this.firePropertyChange
1989
          (ACCESSIBLE_CHILD_PROPERTY, null, e.getChild());
1990
      }
1991
 
1992
      /**
1993
       * Fired when a component is removed; forwards to the PropertyChange
1994
       * listener.
1995
       *
1996
       * @param e the container event for removing
1997
       */
1998
      public void componentRemoved(ContainerEvent e)
1999
      {
2000
        AccessibleAWTContainer.this.firePropertyChange
2001
          (ACCESSIBLE_CHILD_PROPERTY, e.getChild(), null);
2002
      }
2003
    } // class AccessibleContainerHandler
2004
  } // class AccessibleAWTContainer
2005
} // class Container
2006
 
2007
/**
2008
 * There is a helper class implied from stack traces called
2009
 * LightweightDispatcher, but since it is not part of the public API,
2010
 * rather than mimic it exactly we write something which does "roughly
2011
 * the same thing".
2012
 */
2013
class LightweightDispatcher implements Serializable
2014
{
2015
  private static final long serialVersionUID = 5184291520170872969L;
2016
  private Container nativeContainer;
2017
  private Cursor nativeCursor;
2018
  private long eventMask;
2019
 
2020
  private transient Component pressedComponent;
2021
  private transient Component lastComponentEntered;
2022
  private transient int pressCount;
2023
 
2024
  LightweightDispatcher(Container c)
2025
  {
2026
    nativeContainer = c;
2027
  }
2028
 
2029
  void enableEvents(long l)
2030
  {
2031
    eventMask |= l;
2032
  }
2033
 
2034
  /**
2035
   * Returns the deepest visible descendent of parent that contains the
2036
   * specified location and that is not transparent and MouseListener-less.
2037
   * @param parent the root component to begin the search
2038
   * @param x the x coordinate
2039
   * @param y the y coordinate
2040
   * @return null if <code>parent</code> doesn't contain the location,
2041
   * parent if parent is not a container or has no child that contains the
2042
   * location, otherwise the appropriate component from the conditions
2043
   * above.
2044
   */
2045
  Component getDeepestComponentForMouseEventAt(Component parent, int x, int y)
2046
  {
2047
    if (parent == null || (! parent.contains(x, y)))
2048
      return null;
2049
 
2050
    if (! (parent instanceof Container))
2051
      return parent;
2052
 
2053
    Container c = (Container) parent;
2054
    return c.findComponentForMouseEventAt(x, y);
2055
  }
2056
 
2057
  Component acquireComponentForMouseEvent(MouseEvent me)
2058
  {
2059
    int x = me.getX ();
2060
    int y = me.getY ();
2061
 
2062
    Component mouseEventTarget = null;
2063
    // Find the candidate which should receive this event.
2064
    Component parent = nativeContainer;
2065
    Component candidate = null;
2066
    Point p = me.getPoint();
2067
    while (candidate == null && parent != null)
2068
      {
2069
        candidate = getDeepestComponentForMouseEventAt(parent, p.x, p.y);
2070
        if (candidate == null || (candidate.eventMask & me.getID()) == 0)
2071
          {
2072
            candidate = null;
2073
            p = AWTUtilities.convertPoint(parent, p.x, p.y, parent.parent);
2074
            parent = parent.parent;
2075
          }
2076
      }
2077
 
2078
    // If the only candidate we found was the native container itself,
2079
    // don't dispatch any event at all.  We only care about the lightweight
2080
    // children here.
2081
    if (candidate == nativeContainer)
2082
      candidate = null;
2083
 
2084
    // If our candidate is new, inform the old target we're leaving.
2085
    if (lastComponentEntered != null
2086
        && lastComponentEntered.isShowing()
2087
        && lastComponentEntered != candidate)
2088
      {
2089
        // Old candidate could have been removed from 
2090
        // the nativeContainer so we check first.
2091
        if (AWTUtilities.isDescendingFrom(lastComponentEntered,
2092
                                          nativeContainer))
2093
          {
2094
            Point tp = AWTUtilities.convertPoint(nativeContainer,
2095
                                                 x, y, lastComponentEntered);
2096
            MouseEvent exited = new MouseEvent (lastComponentEntered,
2097
                                                MouseEvent.MOUSE_EXITED,
2098
                                                me.getWhen (),
2099
                                                me.getModifiersEx (),
2100
                                                tp.x, tp.y,
2101
                                                me.getClickCount (),
2102
                                                me.isPopupTrigger (),
2103
                                                me.getButton ());
2104
            lastComponentEntered.dispatchEvent (exited);
2105
          }
2106
        lastComponentEntered = null;
2107
      }
2108
 
2109
    // If we have a candidate, maybe enter it.
2110
    if (candidate != null)
2111
      {
2112
        mouseEventTarget = candidate;
2113
        if (candidate.isLightweight()
2114
            && candidate.isShowing()
2115
            && candidate != nativeContainer
2116
            && candidate != lastComponentEntered)
2117
          {
2118
            lastComponentEntered = mouseEventTarget;
2119
            Point cp = AWTUtilities.convertPoint(nativeContainer,
2120
                                                 x, y, lastComponentEntered);
2121
            MouseEvent entered = new MouseEvent (lastComponentEntered,
2122
                                                 MouseEvent.MOUSE_ENTERED,
2123
                                                 me.getWhen (),
2124
                                                 me.getModifiersEx (),
2125
                                                 cp.x, cp.y,
2126
                                                 me.getClickCount (),
2127
                                                 me.isPopupTrigger (),
2128
                                                 me.getButton ());
2129
            lastComponentEntered.dispatchEvent (entered);
2130
          }
2131
      }
2132
 
2133
    // Check which buttons where pressed except the last button that
2134
    // changed state.
2135
    int modifiers = me.getModifiersEx() & (MouseEvent.BUTTON1_DOWN_MASK
2136
                                           | MouseEvent.BUTTON2_DOWN_MASK
2137
                                           | MouseEvent.BUTTON3_DOWN_MASK);
2138
    switch(me.getButton())
2139
      {
2140
      case MouseEvent.BUTTON1:
2141
        modifiers &= ~MouseEvent.BUTTON1_DOWN_MASK;
2142
        break;
2143
      case MouseEvent.BUTTON2:
2144
        modifiers &= ~MouseEvent.BUTTON2_DOWN_MASK;
2145
        break;
2146
      case MouseEvent.BUTTON3:
2147
        modifiers &= ~MouseEvent.BUTTON3_DOWN_MASK;
2148
        break;
2149
      }
2150
 
2151
    if (me.getID() == MouseEvent.MOUSE_PRESSED && modifiers > 0
2152
        || me.getID() == MouseEvent.MOUSE_DRAGGED)
2153
      {
2154
        // If any of the following events occur while a button is held down,
2155
        // they should be dispatched to the same component to which the
2156
        // original MOUSE_PRESSED event was dispatched:
2157
        //   - MOUSE_PRESSED: another button pressed while the first is held
2158
        //     down
2159
        //   - MOUSE_DRAGGED
2160
        if (AWTUtilities.isDescendingFrom(pressedComponent, nativeContainer))
2161
          mouseEventTarget = pressedComponent;
2162
      }
2163
    else if (me.getID() == MouseEvent.MOUSE_CLICKED)
2164
      {
2165
        // Don't dispatch CLICKED events whose target is not the same as the
2166
        // target for the original PRESSED event.
2167
        if (candidate != pressedComponent)
2168
          {
2169
            mouseEventTarget = null;
2170
            pressCount = 0;
2171
          }
2172
        else if (pressCount == 0)
2173
          pressedComponent = null;
2174
      }
2175
    return mouseEventTarget;
2176
  }
2177
 
2178
  boolean handleEvent(AWTEvent e)
2179
  {
2180
    if (e instanceof MouseEvent)
2181
      {
2182
        MouseEvent me = (MouseEvent) e;
2183
 
2184
        // Make the LightWeightDispatcher reentrant. This is necessary when
2185
        // a lightweight component does its own modal event queue.
2186
        Component mouseEventTarget = acquireComponentForMouseEvent(me);
2187
 
2188
        // Avoid dispatching ENTERED and EXITED events twice.
2189
        if (mouseEventTarget != null
2190
            && mouseEventTarget.isShowing()
2191
            && e.getID() != MouseEvent.MOUSE_ENTERED
2192
            && e.getID() != MouseEvent.MOUSE_EXITED)
2193
          {
2194
            switch (e.getID())
2195
              {
2196
              case MouseEvent.MOUSE_PRESSED:
2197
                if (pressCount++ == 0)
2198
                  pressedComponent = mouseEventTarget;
2199
                break;
2200
              case MouseEvent.MOUSE_RELEASED:
2201
                // Clear our memory of the original PRESSED event, only if
2202
                // we're not expecting a CLICKED event after this. If
2203
                // there is a CLICKED event after this, it will do clean up.
2204
                if (--pressCount == 0
2205
                    && mouseEventTarget != pressedComponent)
2206
                  {
2207
                    pressedComponent = null;
2208
                    pressCount = 0;
2209
                  }
2210
                break;
2211
              }
2212
 
2213
            MouseEvent newEvt =
2214
              AWTUtilities.convertMouseEvent(nativeContainer, me,
2215
                                             mouseEventTarget);
2216
            mouseEventTarget.dispatchEvent(newEvt);
2217
 
2218
            if (newEvt.isConsumed())
2219
              e.consume();
2220
          }
2221
      }
2222
 
2223
    return e.isConsumed();
2224
  }
2225
}

powered by: WebSVN 2.1.0

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