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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libjava/] [classpath/] [javax/] [swing/] [AbstractButton.java] - Blame information for rev 14

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 jlechner
/* AbstractButton.java -- Provides basic button functionality.
2
   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
package javax.swing;
39
 
40
import java.awt.Graphics;
41
import java.awt.Image;
42
import java.awt.Insets;
43
import java.awt.ItemSelectable;
44
import java.awt.Point;
45
import java.awt.Rectangle;
46
import java.awt.event.ActionEvent;
47
import java.awt.event.ActionListener;
48
import java.awt.event.ItemEvent;
49
import java.awt.event.ItemListener;
50
import java.awt.image.ImageObserver;
51
import java.beans.PropertyChangeEvent;
52
import java.beans.PropertyChangeListener;
53
import java.io.Serializable;
54
 
55
import javax.accessibility.AccessibleAction;
56
import javax.accessibility.AccessibleIcon;
57
import javax.accessibility.AccessibleRelationSet;
58
import javax.accessibility.AccessibleStateSet;
59
import javax.accessibility.AccessibleText;
60
import javax.accessibility.AccessibleValue;
61
import javax.swing.event.ChangeEvent;
62
import javax.swing.event.ChangeListener;
63
import javax.swing.plaf.ButtonUI;
64
import javax.swing.text.AttributeSet;
65
 
66
 
67
/**
68
 * Provides an abstract implementation of common button behaviour,
69
 * data model and look & feel.
70
 *
71
 * <p>This class is supposed to serve as a base class for
72
 * several kinds of buttons with similar but non-identical semantics:
73
 * toggle buttons (radio buttons and checkboxes), simple push buttons,
74
 * menu items, etc.</p>
75
 *
76
 * <p>Buttons have many properties, some of which are stored in this class
77
 * while others are delegated to the button's model. The following properties
78
 * are available:</p>
79
 *
80
 * <table>
81
 * <tr><th>Property               </th><th>Stored in</th><th>Bound?</th></tr>
82
 *
83
 * <tr><td>action                 </td><td>button</td> <td>no</td></tr>
84
 * <tr><td>actionCommand          </td><td>model</td>  <td>no</td></tr>
85
 * <tr><td>borderPainted          </td><td>button</td> <td>yes</td></tr>
86
 * <tr><td>contentAreaFilled      </td><td>button</td> <td>yes</td></tr>
87
 * <tr><td>disabledIcon           </td><td>button</td> <td>yes</td></tr>
88
 * <tr><td>disabledSelectedIcon   </td><td>button</td> <td>yes</td></tr>
89
 * <tr><td>displayedMnemonicIndex </td><td>button</td> <td>no</td></tr>
90
 * <tr><td>enabled                </td><td>model</td>  <td>no</td></tr>
91
 * <tr><td>focusPainted           </td><td>button</td> <td>yes</td></tr>
92
 * <tr><td>horizontalAlignment    </td><td>button</td> <td>yes</td></tr>
93
 * <tr><td>horizontalTextPosition </td><td>button</td> <td>yes</td></tr>
94
 * <tr><td>icon                   </td><td>button</td> <td>yes</td></tr>
95
 * <tr><td>iconTextGap            </td><td>button</td> <td>no</td></tr>
96
 * <tr><td>label (same as text)   </td><td>model</td>  <td>yes</td></tr>
97
 * <tr><td>margin                 </td><td>button</td> <td>yes</td></tr>
98
 * <tr><td>multiClickThreshold    </td><td>button</td> <td>no</td></tr>
99
 * <tr><td>pressedIcon            </td><td>button</td> <td>yes</td></tr>
100
 * <tr><td>rolloverEnabled        </td><td>button</td> <td>yes</td></tr>
101
 * <tr><td>rolloverIcon           </td><td>button</td> <td>yes</td></tr>
102
 * <tr><td>rolloverSelectedIcon   </td><td>button</td> <td>yes</td></tr>
103
 * <tr><td>selected               </td><td>model</td>  <td>no</td></tr>
104
 * <tr><td>selectedIcon           </td><td>button</td> <td>yes</td></tr>
105
 * <tr><td>selectedObjects        </td><td>button</td> <td>no</td></tr>
106
 * <tr><td>text                   </td><td>model</td>  <td>yes</td></tr>
107
 * <tr><td>UI                     </td><td>button</td> <td>yes</td></tr>
108
 * <tr><td>verticalAlignment      </td><td>button</td> <td>yes</td></tr>
109
 * <tr><td>verticalTextPosition   </td><td>button</td> <td>yes</td></tr>
110
 *
111
 * </table>
112
 *
113
 * <p>The various behavioral aspects of these properties follows:</p>
114
 *
115
 * <ul>
116
 *
117
 * <li>When non-bound properties stored in the button change, the button
118
 * fires ChangeEvents to its ChangeListeners.</li>
119
 *
120
 * <li>When bound properties stored in the button change, the button fires
121
 * PropertyChangeEvents to its PropertyChangeListeners</li>
122
 *
123
 * <li>If any of the model's properties change, it fires a ChangeEvent to
124
 * its ChangeListeners, which include the button.</li>
125
 *
126
 * <li>If the button receives a ChangeEvent from its model, it will
127
 * propagate the ChangeEvent to its ChangeListeners, with the ChangeEvent's
128
 * "source" property set to refer to the button, rather than the model. The
129
 * the button will request a repaint, to paint its updated state.</li>
130
 *
131
 * <li>If the model's "selected" property changes, the model will fire an
132
 * ItemEvent to its ItemListeners, which include the button, in addition to
133
 * the ChangeEvent which models the property change. The button propagates
134
 * ItemEvents directly to its ItemListeners.</li>
135
 *
136
 * <li>If the model's armed and pressed properties are simultaneously
137
 * <code>true</code>, the model will fire an ActionEvent to its
138
 * ActionListeners, which include the button. The button will propagate
139
 * this ActionEvent to its ActionListeners, with the ActionEvent's "source"
140
 * property set to refer to the button, rather than the model.</li>
141
 *
142
 * </ul>
143
 *
144
 * @author Ronald Veldema (rveldema@cs.vu.nl)
145
 * @author Graydon Hoare (graydon@redhat.com)
146
 */
147
 
148
public abstract class AbstractButton extends JComponent
149
  implements ItemSelectable, SwingConstants
150
{
151
  private static final long serialVersionUID = -937921345538462020L;
152
 
153
  /**
154
   * An extension of ChangeListener to be serializable.
155
   */
156
  protected class ButtonChangeListener
157
    implements ChangeListener, Serializable
158
  {
159
    private static final long serialVersionUID = 1471056094226600578L;
160
 
161
    /**
162
     * Notified when the target of the listener changes its state.
163
     *
164
     * @param ev the ChangeEvent describing the change
165
     */
166
    public void stateChanged(ChangeEvent ev)
167
    {
168
      AbstractButton.this.fireStateChanged();
169
      repaint();
170
    }
171
  }
172
 
173
  /** The icon displayed by default. */
174
  Icon default_icon;
175
 
176
  /** The icon displayed when the button is pressed. */
177
  Icon pressed_icon;
178
 
179
  /** The icon displayed when the button is disabled. */
180
  Icon disabeldIcon;
181
 
182
  /** The icon displayed when the button is selected. */
183
  Icon selectedIcon;
184
 
185
  /** The icon displayed when the button is selected but disabled. */
186
  Icon disabledSelectedIcon;
187
 
188
  /** The icon displayed when the button is rolled over. */
189
  Icon rolloverIcon;
190
 
191
  /** The icon displayed when the button is selected and rolled over. */
192
  Icon rolloverSelectedIcon;
193
 
194
  /** The icon currently displayed. */
195
  Icon current_icon;
196
 
197
  /** The text displayed in the button. */
198
  String text;
199
 
200
  /**
201
   * The gap between icon and text, if both icon and text are
202
   * non-<code>null</code>.
203
   */
204
  int iconTextGap;
205
 
206
  /** The vertical alignment of the button's text and icon. */
207
  int verticalAlignment;
208
 
209
  /** The horizontal alignment of the button's text and icon. */
210
  int horizontalAlignment;
211
 
212
  /** The horizontal position of the button's text relative to its icon. */
213
  int horizontalTextPosition;
214
 
215
  /** The vertical position of the button's text relative to its icon. */
216
  int verticalTextPosition;
217
 
218
  /** Whether or not the button paints its border. */
219
  boolean borderPainted;
220
 
221
  /** Whether or not the button paints its focus state. */
222
  boolean focusPainted;
223
 
224
  /** Whether or not the button fills its content area. */
225
  boolean contentAreaFilled;
226
 
227
  /** Whether rollover is enabled. */
228
  boolean rollOverEnabled;
229
 
230
  /** The action taken when the button is clicked. */
231
  Action action;
232
 
233
  /** The button's current state. */
234
  protected ButtonModel model;
235
 
236
  /** The margin between the button's border and its label. */
237
  Insets margin;
238
 
239
  /**
240
   * A hint to the look and feel class, suggesting which character in the
241
   * button's label should be underlined when drawing the label.
242
   */
243
  int mnemonicIndex;
244
 
245
  /** Listener the button uses to receive ActionEvents from its model.  */
246
  protected ActionListener actionListener;
247
 
248
  /** Listener the button uses to receive ItemEvents from its model.  */
249
  protected ItemListener itemListener;
250
 
251
  /** Listener the button uses to receive ChangeEvents from its model.  */
252
  protected ChangeListener changeListener;
253
 
254
  /**
255
   * The time in miliseconds in which clicks get coalesced into a single
256
   * <code>ActionEvent</code>.
257
   */
258
  long multiClickThreshhold;
259
 
260
  /**
261
   * Listener the button uses to receive PropertyChangeEvents from its
262
   * Action.
263
   */
264
  PropertyChangeListener actionPropertyChangeListener;
265
 
266
  /** ChangeEvent that is fired to button's ChangeEventListeners  */
267
  protected ChangeEvent changeEvent = new ChangeEvent(this);
268
 
269
  /**
270
   * Fired in a PropertyChangeEvent when the "borderPainted" property changes.
271
   */
272
  public static final String BORDER_PAINTED_CHANGED_PROPERTY = "borderPainted";
273
 
274
  /**
275
   * Fired in a PropertyChangeEvent when the "contentAreaFilled" property
276
   * changes.
277
   */
278
  public static final String CONTENT_AREA_FILLED_CHANGED_PROPERTY =
279
    "contentAreaFilled";
280
 
281
  /**
282
   * Fired in a PropertyChangeEvent when the "disabledIcon" property changes.
283
   */
284
  public static final String DISABLED_ICON_CHANGED_PROPERTY = "disabledIcon";
285
 
286
  /**
287
   * Fired in a PropertyChangeEvent when the "disabledSelectedIcon" property
288
   * changes.
289
   */
290
  public static final String DISABLED_SELECTED_ICON_CHANGED_PROPERTY =
291
    "disabledSelectedIcon";
292
 
293
  /**
294
   * Fired in a PropertyChangeEvent when the "focusPainted" property changes.
295
   */
296
  public static final String FOCUS_PAINTED_CHANGED_PROPERTY = "focusPainted";
297
 
298
  /**
299
   * Fired in a PropertyChangeEvent when the "horizontalAlignment" property
300
   * changes.
301
   */
302
  public static final String HORIZONTAL_ALIGNMENT_CHANGED_PROPERTY =
303
    "horizontalAlignment";
304
 
305
  /**
306
   * Fired in a PropertyChangeEvent when the "horizontalTextPosition" property
307
   * changes.
308
   */
309
  public static final String HORIZONTAL_TEXT_POSITION_CHANGED_PROPERTY =
310
    "horizontalTextPosition";
311
 
312
  /**
313
   * Fired in a PropertyChangeEvent when the "icon" property changes. */
314
  public static final String ICON_CHANGED_PROPERTY = "icon";
315
 
316
  /** Fired in a PropertyChangeEvent when the "margin" property changes. */
317
  public static final String MARGIN_CHANGED_PROPERTY = "margin";
318
 
319
  /** Fired in a PropertyChangeEvent when the "mnemonic" property changes. */
320
  public static final String MNEMONIC_CHANGED_PROPERTY = "mnemonic";
321
 
322
  /** Fired in a PropertyChangeEvent when the "model" property changes. */
323
  public static final String MODEL_CHANGED_PROPERTY = "model";
324
 
325
  /** Fired in a PropertyChangeEvent when the "pressedIcon" property changes. */
326
  public static final String PRESSED_ICON_CHANGED_PROPERTY = "pressedIcon";
327
 
328
  /**
329
   * Fired in a PropertyChangeEvent when the "rolloverEnabled" property
330
   * changes.
331
   */
332
  public static final String ROLLOVER_ENABLED_CHANGED_PROPERTY =
333
    "rolloverEnabled";
334
 
335
  /**
336
   * Fired in a PropertyChangeEvent when the "rolloverIcon" property changes.
337
   */
338
  public static final String ROLLOVER_ICON_CHANGED_PROPERTY = "rolloverIcon";
339
 
340
  /**
341
   * Fired in a PropertyChangeEvent when the "rolloverSelectedIcon" property
342
   * changes.
343
   */
344
  public static final String ROLLOVER_SELECTED_ICON_CHANGED_PROPERTY =
345
    "rolloverSelectedIcon";
346
 
347
  /**
348
   * Fired in a PropertyChangeEvent when the "selectedIcon" property changes.
349
   */
350
  public static final String SELECTED_ICON_CHANGED_PROPERTY = "selectedIcon";
351
 
352
  /** Fired in a PropertyChangeEvent when the "text" property changes. */
353
  public static final String TEXT_CHANGED_PROPERTY = "text";
354
 
355
  /**
356
   * Fired in a PropertyChangeEvent when the "verticalAlignment" property
357
   * changes.
358
   */
359
  public static final String VERTICAL_ALIGNMENT_CHANGED_PROPERTY =
360
    "verticalAlignment";
361
 
362
  /**
363
   * Fired in a PropertyChangeEvent when the "verticalTextPosition" property
364
   * changes.
365
   */
366
  public static final String VERTICAL_TEXT_POSITION_CHANGED_PROPERTY =
367
    "verticalTextPosition";
368
 
369
  /**
370
   * A Java Accessibility extension of the AbstractButton.
371
   */
372
  protected abstract class AccessibleAbstractButton
373
    extends AccessibleJComponent implements AccessibleAction, AccessibleValue,
374
                                            AccessibleText
375
  {
376
    private static final long serialVersionUID = -5673062525319836790L;
377
 
378
    protected AccessibleAbstractButton()
379
    {
380
      // Nothing to do here yet.
381
    }
382
 
383
    public AccessibleStateSet getAccessibleStateSet()
384
    {
385
      return null; // TODO
386
    }
387
 
388
    public String getAccessibleName()
389
    {
390
      return null; // TODO
391
    }
392
 
393
    public AccessibleIcon[] getAccessibleIcon()
394
    {
395
      return null; // TODO
396
    }
397
 
398
    public AccessibleRelationSet getAccessibleRelationSet()
399
    {
400
      return null; // TODO
401
    }
402
 
403
    public AccessibleAction getAccessibleAction()
404
    {
405
      return null; // TODO
406
    }
407
 
408
    public AccessibleValue getAccessibleValue()
409
    {
410
      return null; // TODO
411
    }
412
 
413
    public int getAccessibleActionCount()
414
    {
415
      return 0; // TODO
416
    }
417
 
418
    public String getAccessibleActionDescription(int value0)
419
    {
420
      return null; // TODO
421
    }
422
 
423
    public boolean doAccessibleAction(int value0)
424
    {
425
      return false; // TODO
426
    }
427
 
428
    public Number getCurrentAccessibleValue()
429
    {
430
      return null; // TODO
431
    }
432
 
433
    public boolean setCurrentAccessibleValue(Number value0)
434
    {
435
      return false; // TODO
436
    }
437
 
438
    public Number getMinimumAccessibleValue()
439
    {
440
      return null; // TODO
441
    }
442
 
443
    public Number getMaximumAccessibleValue()
444
    {
445
      return null; // TODO
446
    }
447
 
448
    public AccessibleText getAccessibleText()
449
    {
450
      return null; // TODO
451
    }
452
 
453
    public int getIndexAtPoint(Point value0)
454
    {
455
      return 0; // TODO
456
    }
457
 
458
    public Rectangle getCharacterBounds(int value0)
459
    {
460
      return null; // TODO
461
    }
462
 
463
    public int getCharCount()
464
    {
465
      return 0; // TODO
466
    }
467
 
468
    public int getCaretPosition()
469
    {
470
      return 0; // TODO
471
    }
472
 
473
    public String getAtIndex(int value0, int value1)
474
    {
475
      return null; // TODO
476
    }
477
 
478
    public String getAfterIndex(int value0, int value1)
479
    {
480
      return null; // TODO
481
    }
482
 
483
    public String getBeforeIndex(int value0, int value1)
484
    {
485
      return null; // TODO
486
    }
487
 
488
    public AttributeSet getCharacterAttribute(int value0)
489
    {
490
      return null; // TODO
491
    }
492
 
493
    public int getSelectionStart()
494
    {
495
      return 0; // TODO
496
    }
497
 
498
    public int getSelectionEnd()
499
    {
500
      return 0; // TODO
501
    }
502
 
503
    public String getSelectedText()
504
    {
505
      return null; // TODO
506
    }
507
 
508
    private Rectangle getTextRectangle()
509
    {
510
      return null; // TODO
511
    }
512
  }
513
 
514
  /**
515
   * Creates a new AbstractButton object. Subclasses should call the following
516
   * sequence in their constructor in order to initialize the button correctly:
517
   * <pre>
518
   * super();
519
   * init(text, icon);
520
   * </pre>
521
   *
522
   * The {@link #init(String, Icon)} method is not called automatically by this
523
   * constructor.
524
   *
525
   * @see #init(String, Icon)
526
   */
527
  public AbstractButton()
528
  {
529
    actionListener = createActionListener();
530
    changeListener = createChangeListener();
531
    itemListener = createItemListener();
532
 
533
    horizontalAlignment = CENTER;
534
    horizontalTextPosition = TRAILING;
535
    verticalAlignment = CENTER;
536
    verticalTextPosition = CENTER;
537
    borderPainted = true;
538
    contentAreaFilled = true;
539
    focusPainted = true;
540
    setFocusable(true);
541
    setAlignmentX(CENTER_ALIGNMENT);
542
    setAlignmentY(CENTER_ALIGNMENT);
543
    setDisplayedMnemonicIndex(-1);
544
    setOpaque(true);
545
    text = "";
546
    updateUI();
547
  }
548
 
549
  /**
550
   * Get the model the button is currently using.
551
   *
552
   * @return The current model
553
   */
554
  public ButtonModel getModel()
555
  {
556
      return model;
557
  }
558
 
559
  /**
560
   * Set the model the button is currently using. This un-registers all
561
   * listeners associated with the current model, and re-registers them
562
   * with the new model.
563
   *
564
   * @param newModel The new model
565
   */
566
  public void setModel(ButtonModel newModel)
567
  {
568
    if (newModel == model)
569
      return;
570
 
571
    if (model != null)
572
      {
573
        model.removeActionListener(actionListener);
574
        model.removeChangeListener(changeListener);
575
        model.removeItemListener(itemListener);
576
      }
577
    ButtonModel old = model;
578
    model = newModel;
579
    if (model != null)
580
      {
581
        model.addActionListener(actionListener);
582
        model.addChangeListener(changeListener);
583
        model.addItemListener(itemListener);
584
      }
585
    firePropertyChange(MODEL_CHANGED_PROPERTY, old, model);
586
    revalidate();
587
    repaint();
588
  }
589
 
590
 protected void init(String text, Icon icon)
591
 {
592
    // If text is null, we fall back to the empty
593
    // string (which is set using AbstractButton's
594
    // constructor).
595
    // This way the behavior of the JDK is matched.
596
    if(text != null)
597
        this.text = text;
598
 
599
    if (icon != null)
600
      default_icon = icon;
601
 }
602
 
603
  /**
604
   * <p>Returns the action command string for this button's model.</p>
605
   *
606
   * <p>If the action command was set to <code>null</code>, the button's
607
   * text (label) is returned instead.</p>
608
   *
609
   * @return The current action command string from the button's model
610
   */
611
  public String getActionCommand()
612
  {
613
    String ac = model.getActionCommand();
614
    if (ac != null)
615
      return ac;
616
    else
617
      return text;
618
  }
619
 
620
  /**
621
   * Sets the action command string for this button's model.
622
   *
623
   * @param actionCommand The new action command string to set in the button's
624
   * model.
625
   */
626
  public void setActionCommand(String actionCommand)
627
  {
628
    if (model != null)
629
      model.setActionCommand(actionCommand);
630
  }
631
 
632
  /**
633
   * Adds an ActionListener to the button's listener list. When the
634
   * button's model is clicked it fires an ActionEvent, and these
635
   * listeners will be called.
636
   *
637
   * @param l The new listener to add
638
   */
639
  public void addActionListener(ActionListener l)
640
  {
641
    listenerList.add(ActionListener.class, l);
642
  }
643
 
644
  /**
645
   * Removes an ActionListener from the button's listener list.
646
   *
647
   * @param l The listener to remove
648
   */
649
  public void removeActionListener(ActionListener l)
650
  {
651
    listenerList.remove(ActionListener.class, l);
652
  }
653
 
654
  /**
655
   * Returns all added <code>ActionListener</code> objects.
656
   *
657
   * @return an array of listeners
658
   *
659
   * @since 1.4
660
   */
661
  public ActionListener[] getActionListeners()
662
  {
663
    return (ActionListener[]) listenerList.getListeners(ActionListener.class);
664
  }
665
 
666
  /**
667
   * Adds an ItemListener to the button's listener list. When the button's
668
   * model changes state (between any of ARMED, ENABLED, PRESSED, ROLLOVER
669
   * or SELECTED) it fires an ItemEvent, and these listeners will be
670
   * called.
671
   *
672
   * @param l The new listener to add
673
   */
674
  public void addItemListener(ItemListener l)
675
  {
676
    listenerList.add(ItemListener.class, l);
677
  }
678
 
679
  /**
680
   * Removes an ItemListener from the button's listener list.
681
   *
682
   * @param l The listener to remove
683
   */
684
  public void removeItemListener(ItemListener l)
685
  {
686
    listenerList.remove(ItemListener.class, l);
687
  }
688
 
689
  /**
690
   * Returns all added <code>ItemListener</code> objects.
691
   *
692
   * @return an array of listeners
693
   *
694
   * @since 1.4
695
   */
696
  public ItemListener[] getItemListeners()
697
  {
698
    return (ItemListener[]) listenerList.getListeners(ItemListener.class);
699
  }
700
 
701
  /**
702
   * Adds a ChangeListener to the button's listener list. When the button's
703
   * model changes any of its (non-bound) properties, these listeners will be
704
   * called.
705
   *
706
   * @param l The new listener to add
707
   */
708
  public void addChangeListener(ChangeListener l)
709
  {
710
    listenerList.add(ChangeListener.class, l);
711
  }
712
 
713
  /**
714
   * Removes a ChangeListener from the button's listener list.
715
   *
716
   * @param l The listener to remove
717
   */
718
  public void removeChangeListener(ChangeListener l)
719
  {
720
    listenerList.remove(ChangeListener.class, l);
721
  }
722
 
723
  /**
724
   * Returns all added <code>ChangeListener</code> objects.
725
   *
726
   * @return an array of listeners
727
   *
728
   * @since 1.4
729
   */
730
  public ChangeListener[] getChangeListeners()
731
  {
732
    return (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
733
  }
734
 
735
  /**
736
   * Calls {@link ItemListener#itemStateChanged} on each ItemListener in
737
   * the button's listener list.
738
   *
739
   * @param e The event signifying that the button's model changed state
740
   */
741
  protected void fireItemStateChanged(ItemEvent e)
742
  {
743
    e.setSource(this);
744
    ItemListener[] listeners = getItemListeners();
745
 
746
    for (int i = 0; i < listeners.length; i++)
747
      listeners[i].itemStateChanged(e);
748
  }
749
 
750
  /**
751
   * Calls {@link ActionListener#actionPerformed} on each {@link
752
   * ActionListener} in the button's listener list.
753
   *
754
   * @param e The event signifying that the button's model was clicked
755
   */
756
  protected void fireActionPerformed(ActionEvent e)
757
  {
758
        // Dispatch a copy of the given ActionEvent in order to
759
        // set the source and action command correctly.
760
    ActionEvent ae = new ActionEvent(
761
        this,
762
        e.getID(),
763
        getActionCommand(),
764
        e.getWhen(),
765
        e.getModifiers());
766
 
767
    ActionListener[] listeners = getActionListeners();
768
 
769
    for (int i = 0; i < listeners.length; i++)
770
      listeners[i].actionPerformed(ae);
771
  }
772
 
773
  /**
774
   * Calls {@link ChangeListener#stateChanged} on each {@link ChangeListener}
775
   * in the button's listener list.
776
   */
777
  protected void fireStateChanged()
778
  {
779
    ChangeListener[] listeners = getChangeListeners();
780
 
781
    for (int i = 0; i < listeners.length; i++)
782
      listeners[i].stateChanged(changeEvent);
783
  }
784
 
785
  /**
786
   * Get the current keyboard mnemonic value. This value corresponds to a
787
   * single key code (one of the {@link java.awt.event.KeyEvent} VK_*
788
   * codes) and is used to activate the button when pressed in conjunction
789
   * with the "mouseless modifier" of the button's look and feel class, and
790
   * when focus is in one of the button's ancestors.
791
   *
792
   * @return The button's current keyboard mnemonic
793
   */
794
  public int getMnemonic()
795
  {
796
    ButtonModel mod = getModel();
797
    if (mod != null)
798
      return mod.getMnemonic();
799
    return -1;
800
  }
801
 
802
  /**
803
   * Set the current keyboard mnemonic value. This value corresponds to a
804
   * single key code (one of the {@link java.awt.event.KeyEvent} VK_*
805
   * codes) and is used to activate the button when pressed in conjunction
806
   * with the "mouseless modifier" of the button's look and feel class, and
807
   * when focus is in one of the button's ancestors.
808
   *
809
   * @param mne A new mnemonic to use for the button
810
   */
811
  public void setMnemonic(char mne)
812
  {
813
    setMnemonic((int) mne);
814
  }
815
 
816
  /**
817
   * Set the current keyboard mnemonic value. This value corresponds to a
818
   * single key code (one of the {@link java.awt.event.KeyEvent} VK_*
819
   * codes) and is used to activate the button when pressed in conjunction
820
   * with the "mouseless modifier" of the button's look and feel class, and
821
   * when focus is in one of the button's ancestors.
822
   *
823
   * @param mne A new mnemonic to use for the button
824
   */
825
  public void setMnemonic(int mne)
826
  {
827
    ButtonModel mod = getModel();
828
    int old = -1;
829
    if (mod != null)
830
      old = mod.getMnemonic();
831
 
832
    if (old != mne)
833
      {
834
        if (mod != null)
835
          mod.setMnemonic(mne);
836
 
837
        if (text != null && !text.equals(""))
838
          {
839
            // Since lower case char = upper case char for
840
            // mnemonic, we will convert both text and mnemonic
841
            // to upper case before checking if mnemonic character occurs
842
            // in the menu item text.
843
            int upperCaseMne = Character.toUpperCase((char) mne);
844
            String upperCaseText = text.toUpperCase();
845
            setDisplayedMnemonicIndex(upperCaseText.indexOf(upperCaseMne));
846
          }
847
 
848
        firePropertyChange(MNEMONIC_CHANGED_PROPERTY, old, mne);
849
        revalidate();
850
        repaint();
851
      }
852
  }
853
 
854
  /**
855
   * Sets the button's mnemonic index. The mnemonic index is a hint to the
856
   * look and feel class, suggesting which character in the button's label
857
   * should be underlined when drawing the label. If the mnemonic index is
858
   * -1, no mnemonic will be displayed.
859
   *
860
   * If no mnemonic index is set, the button will choose a mnemonic index
861
   * by default, which will be the first occurrence of the mnemonic
862
   * character in the button's text.
863
   *
864
   * @param index An offset into the "text" property of the button
865
   * @throws IllegalArgumentException If <code>index</code> is not within the
866
   * range of legal offsets for the "text" property of the button.
867
   * @since 1.4
868
   */
869
 
870
  public void setDisplayedMnemonicIndex(int index)
871
  {
872
    if (index < -1 || (text != null && index >= text.length()))
873
      throw new IllegalArgumentException();
874
 
875
    mnemonicIndex = index;
876
  }
877
 
878
  /**
879
   * Get the button's mnemonic index, which is an offset into the button's
880
   * "text" property.  The character specified by this offset should be
881
   * underlined when the look and feel class draws this button.
882
   *
883
   * @return An index into the button's "text" property
884
   */
885
  public int getDisplayedMnemonicIndex()
886
  {
887
    return mnemonicIndex;
888
  }
889
 
890
 
891
  /**
892
   * Set the "rolloverEnabled" property. When rollover is enabled, and the
893
   * look and feel supports it, the button will change its icon to
894
   * rolloverIcon, when the mouse passes over it.
895
   *
896
   * @param r Whether or not to enable rollover icon changes
897
   */
898
  public void setRolloverEnabled(boolean r)
899
  {
900
    if (rollOverEnabled != r)
901
      {
902
        rollOverEnabled = r;
903
        firePropertyChange(ROLLOVER_ENABLED_CHANGED_PROPERTY, !r, r);
904
        revalidate();
905
        repaint();
906
      }
907
  }
908
 
909
  /**
910
   * Returns whether or not rollover icon changes are enabled on the
911
   * button.
912
   *
913
   * @return The state of the "rolloverEnabled" property
914
   */
915
  public boolean isRolloverEnabled()
916
  {
917
    return rollOverEnabled;
918
  }
919
 
920
  /**
921
   * Set the value of the button's "selected" property. Selection is only
922
   * meaningful for toggle-type buttons (check boxes, radio buttons).
923
   *
924
   * @param s New value for the property
925
   */
926
  public void setSelected(boolean s)
927
  {
928
    ButtonModel mod = getModel();
929
    if (mod != null)
930
      mod.setSelected(s);
931
  }
932
 
933
  /**
934
   * Get the value of the button's "selected" property. Selection is only
935
   * meaningful for toggle-type buttons (check boxes, radio buttons).
936
   *
937
   * @return The value of the property
938
   */
939
  public boolean isSelected()
940
  {
941
    ButtonModel mod = getModel();
942
    if (mod != null)
943
      return mod.isSelected();
944
    return false;
945
  }
946
 
947
  /**
948
   * Enables or disables the button. A button will neither be selectable
949
   * nor preform any actions unless it is enabled.
950
   *
951
   * @param b Whether or not to enable the button
952
   */
953
  public void setEnabled(boolean b)
954
  {
955
    // Do nothing if state does not change.
956
    if (b == isEnabled())
957
      return;
958
    super.setEnabled(b);
959
    setFocusable(b);
960
    ButtonModel mod = getModel();
961
    if (mod != null)
962
      mod.setEnabled(b);
963
  }
964
 
965
  /**
966
   * Set the horizontal alignment of the button's text and icon. The
967
   * alignment is a numeric constant from {@link SwingConstants}. It must
968
   * be one of: <code>RIGHT</code>, <code>LEFT</code>, <code>CENTER</code>,
969
   * <code>LEADING</code> or <code>TRAILING</code>.  The default is
970
   * <code>RIGHT</code>.
971
   *
972
   * @return The current horizontal alignment
973
   */
974
  public int getHorizontalAlignment()
975
  {
976
    return horizontalAlignment;
977
  }
978
 
979
  /**
980
   * Set the horizontal alignment of the button's text and icon. The
981
   * alignment is a numeric constant from {@link SwingConstants}. It must
982
   * be one of: <code>RIGHT</code>, <code>LEFT</code>, <code>CENTER</code>,
983
   * <code>LEADING</code> or <code>TRAILING</code>.  The default is
984
   * <code>RIGHT</code>.
985
   *
986
   * @param a The new horizontal alignment
987
   * @throws IllegalArgumentException If alignment is not one of the legal
988
   * constants.
989
   */
990
  public void setHorizontalAlignment(int a)
991
  {
992
    if (horizontalAlignment == a)
993
      return;
994
 
995
    int old = horizontalAlignment;
996
    horizontalAlignment = a;
997
    firePropertyChange(HORIZONTAL_ALIGNMENT_CHANGED_PROPERTY, old, a);
998
    revalidate();
999
    repaint();
1000
  }
1001
 
1002
  /**
1003
   * Get the horizontal position of the button's text relative to its
1004
   * icon. The position is a numeric constant from {@link
1005
   * SwingConstants}. It must be one of: <code>RIGHT</code>,
1006
   * <code>LEFT</code>, <code>CENTER</code>, <code>LEADING</code> or
1007
   * <code>TRAILING</code>.  The default is <code>TRAILING</code>.
1008
   *
1009
   * @return The current horizontal text position
1010
   */
1011
  public int getHorizontalTextPosition()
1012
  {
1013
    return horizontalTextPosition;
1014
  }
1015
 
1016
  /**
1017
   * Set the horizontal position of the button's text relative to its
1018
   * icon. The position is a numeric constant from {@link
1019
   * SwingConstants}. It must be one of: <code>RIGHT</code>,
1020
   * <code>LEFT</code>, <code>CENTER</code>, <code>LEADING</code> or
1021
   * <code>TRAILING</code>. The default is <code>TRAILING</code>.
1022
   *
1023
   * @param t The new horizontal text position
1024
   * @throws IllegalArgumentException If position is not one of the legal
1025
   * constants.
1026
   */
1027
  public void setHorizontalTextPosition(int t)
1028
  {
1029
    if (horizontalTextPosition == t)
1030
      return;
1031
 
1032
    int old = horizontalTextPosition;
1033
    horizontalTextPosition = t;
1034
    firePropertyChange(HORIZONTAL_TEXT_POSITION_CHANGED_PROPERTY, old, t);
1035
    revalidate();
1036
    repaint();
1037
  }
1038
 
1039
  /**
1040
   * Get the vertical alignment of the button's text and icon. The
1041
   * alignment is a numeric constant from {@link SwingConstants}. It must
1042
   * be one of: <code>CENTER</code>, <code>TOP</code>, or
1043
   * <code>BOTTOM</code>. The default is <code>CENTER</code>.
1044
   *
1045
   * @return The current vertical alignment
1046
   */
1047
  public int getVerticalAlignment()
1048
  {
1049
    return verticalAlignment;
1050
  }
1051
 
1052
  /**
1053
   * Set the vertical alignment of the button's text and icon. The
1054
   * alignment is a numeric constant from {@link SwingConstants}. It must
1055
   * be one of: <code>CENTER</code>, <code>TOP</code>, or
1056
   * <code>BOTTOM</code>. The default is <code>CENTER</code>.
1057
   *
1058
   * @param a The new vertical alignment
1059
   * @throws IllegalArgumentException If alignment is not one of the legal
1060
   * constants.
1061
   */
1062
  public void setVerticalAlignment(int a)
1063
  {
1064
    if (verticalAlignment == a)
1065
      return;
1066
 
1067
    int old = verticalAlignment;
1068
    verticalAlignment = a;
1069
    firePropertyChange(VERTICAL_ALIGNMENT_CHANGED_PROPERTY, old, a);
1070
    revalidate();
1071
    repaint();
1072
  }
1073
 
1074
  /**
1075
   * Get the vertical position of the button's text relative to its
1076
   * icon. The alignment is a numeric constant from {@link
1077
   * SwingConstants}. It must be one of: <code>CENTER</code>,
1078
   * <code>TOP</code>, or <code>BOTTOM</code>. The default is
1079
   * <code>CENTER</code>.
1080
   *
1081
   * @return The current vertical position
1082
   */
1083
  public int getVerticalTextPosition()
1084
  {
1085
    return verticalTextPosition;
1086
  }
1087
 
1088
  /**
1089
   * Set the vertical position of the button's text relative to its
1090
   * icon. The alignment is a numeric constant from {@link
1091
   * SwingConstants}. It must be one of: <code>CENTER</code>,
1092
   * <code>TOP</code>, or <code>BOTTOM</code>. The default is
1093
   * <code>CENTER</code>.
1094
   *
1095
   * @param t The new vertical position
1096
   * @throws IllegalArgumentException If position is not one of the legal
1097
   * constants.
1098
   */
1099
  public void setVerticalTextPosition(int t)
1100
  {
1101
    if (verticalTextPosition == t)
1102
      return;
1103
 
1104
    int old = verticalTextPosition;
1105
    verticalTextPosition = t;
1106
    firePropertyChange(VERTICAL_TEXT_POSITION_CHANGED_PROPERTY, old, t);
1107
    revalidate();
1108
    repaint();
1109
  }
1110
 
1111
  /**
1112
   * Set the value of the "borderPainted" property. If set to
1113
   * <code>false</code>, the button's look and feel class should not paint
1114
   * a border for the button. The default is <code>true</code>.
1115
   *
1116
   * @return The current value of the property.
1117
   */
1118
  public boolean isBorderPainted()
1119
  {
1120
    return borderPainted;
1121
  }
1122
 
1123
  /**
1124
   * Set the value of the "borderPainted" property. If set to
1125
   * <code>false</code>, the button's look and feel class should not paint
1126
   * a border for the button. The default is <code>true</code>.
1127
   *
1128
   * @param b The new value of the property.
1129
   */
1130
  public void setBorderPainted(boolean b)
1131
  {
1132
    if (borderPainted == b)
1133
      return;
1134
 
1135
    boolean old = borderPainted;
1136
    borderPainted = b;
1137
    firePropertyChange(BORDER_PAINTED_CHANGED_PROPERTY, old, b);
1138
    revalidate();
1139
    repaint();
1140
  }
1141
 
1142
  /**
1143
   * Get the value of the "action" property.
1144
   *
1145
   * @return The current value of the "action" property
1146
   */
1147
  public Action getAction()
1148
  {
1149
    return action;
1150
  }
1151
 
1152
  /**
1153
   * <p>Set the button's "action" property, subscribing the new action to the
1154
   * button, as an ActionListener, if it is not already subscribed. The old
1155
   * Action, if it exists, is unsubscribed, and the button is unsubscribed
1156
   * from the old Action if it was previously subscribed as a
1157
   * PropertyChangeListener.</p>
1158
   *
1159
   * <p>This method also configures several of the button's properties from
1160
   * the Action, by calling {@link #configurePropertiesFromAction}, and
1161
   * subscribes the button to the Action as a PropertyChangeListener.
1162
   * Subsequent changes to the Action will thus reconfigure the button
1163
   * automatically.</p>
1164
   *
1165
   * @param a The new value of the "action" property
1166
   */
1167
  public void setAction(Action a)
1168
  {
1169
    if (action != null)
1170
      {
1171
        action.removePropertyChangeListener(actionPropertyChangeListener);
1172
        removeActionListener(action);
1173
        if (actionPropertyChangeListener != null)
1174
          {
1175
            action.removePropertyChangeListener(actionPropertyChangeListener);
1176
            actionPropertyChangeListener = null;
1177
          }
1178
      }
1179
 
1180
    Action old = action;
1181
    action = a;
1182
    configurePropertiesFromAction(action);
1183
    if (action != null)
1184
      {
1185
        actionPropertyChangeListener = createActionPropertyChangeListener(a);
1186
        action.addPropertyChangeListener(actionPropertyChangeListener);
1187
        addActionListener(action);
1188
      }
1189
  }
1190
 
1191
  /**
1192
   * Return the button's default "icon" property.
1193
   *
1194
   * @return The current default icon
1195
   */
1196
  public Icon getIcon()
1197
  {
1198
    return default_icon;
1199
  }
1200
 
1201
  /**
1202
   * Set the button's default "icon" property. This icon is used as a basis
1203
   * for the pressed and disabled icons, if none are explicitly set.
1204
   *
1205
   * @param i The new default icon
1206
   */
1207
  public void setIcon(Icon i)
1208
  {
1209
    if (default_icon == i)
1210
      return;
1211
 
1212
    Icon old = default_icon;
1213
    default_icon = i;
1214
    firePropertyChange(ICON_CHANGED_PROPERTY, old, i);
1215
    revalidate();
1216
    repaint();
1217
  }
1218
 
1219
  /**
1220
   * Return the button's "text" property. This property is synonymous with
1221
   * the "label" property.
1222
   *
1223
   * @return The current "text" property
1224
   */
1225
  public String getText()
1226
  {
1227
    return text;
1228
  }
1229
 
1230
  /**
1231
   * Set the button's "label" property. This property is synonymous with the
1232
   * "text" property.
1233
   *
1234
   * @param label The new "label" property
1235
   *
1236
   * @deprecated use <code>setText(text)</code>
1237
   */
1238
  public void setLabel(String label)
1239
  {
1240
    setText(label);
1241
  }
1242
 
1243
  /**
1244
   * Return the button's "label" property. This property is synonymous with
1245
   * the "text" property.
1246
   *
1247
   * @return The current "label" property
1248
   *
1249
   * @deprecated use <code>getText()</code>
1250
   */
1251
  public String getLabel()
1252
  {
1253
    return getText();
1254
  }
1255
 
1256
  /**
1257
   * Set the button's "text" property. This property is synonymous with the
1258
   * "label" property.
1259
   *
1260
   * @param t The new "text" property
1261
   */
1262
  public void setText(String t)
1263
  {
1264
    if (text == t)
1265
      return;
1266
 
1267
    String old = text;
1268
    text = t;
1269
    firePropertyChange(TEXT_CHANGED_PROPERTY, old, t);
1270
    revalidate();
1271
    repaint();
1272
  }
1273
 
1274
  /**
1275
   * Set the value of the {@link #iconTextGap} property.
1276
   *
1277
   * @param i The new value of the property
1278
   */
1279
  public void setIconTextGap(int i)
1280
  {
1281
    if (iconTextGap == i)
1282
      return;
1283
 
1284
    int old = iconTextGap;
1285
    iconTextGap = i;
1286
    fireStateChanged();
1287
    revalidate();
1288
    repaint();
1289
  }
1290
 
1291
  /**
1292
   * Get the value of the {@link #iconTextGap} property.
1293
   *
1294
   * @return The current value of the property
1295
   */
1296
  public int getIconTextGap()
1297
  {
1298
    return iconTextGap;
1299
  }
1300
 
1301
  /**
1302
   * Return the button's "margin" property, which is an {@link Insets} object
1303
   * describing the distance between the button's border and its text and
1304
   * icon.
1305
   *
1306
   * @return The current "margin" property
1307
   */
1308
  public Insets getMargin()
1309
  {
1310
    return margin;
1311
  }
1312
 
1313
  /**
1314
   * Set the button's "margin" property, which is an {@link Insets} object
1315
   * describing the distance between the button's border and its text and
1316
   * icon.
1317
   *
1318
   * @param m The new "margin" property
1319
   */
1320
  public void setMargin(Insets m)
1321
  {
1322
    if (margin == m)
1323
      return;
1324
 
1325
    Insets old = margin;
1326
    margin = m;
1327
    firePropertyChange(MARGIN_CHANGED_PROPERTY, old, m);
1328
    revalidate();
1329
    repaint();
1330
  }
1331
 
1332
  /**
1333
   * Return the button's "pressedIcon" property. The look and feel class
1334
   * should paint this icon when the "pressed" property of the button's
1335
   * {@link ButtonModel} is <code>true</code>. This property may be
1336
   * <code>null</code>, in which case the default icon is used.
1337
   *
1338
   * @return The current "pressedIcon" property
1339
   */
1340
  public Icon getPressedIcon()
1341
  {
1342
    return pressed_icon;
1343
  }
1344
 
1345
  /**
1346
   * Set the button's "pressedIcon" property. The look and feel class
1347
   * should paint this icon when the "pressed" property of the button's
1348
   * {@link ButtonModel} is <code>true</code>. This property may be
1349
   * <code>null</code>, in which case the default icon is used.
1350
   *
1351
   * @param pressedIcon The new "pressedIcon" property
1352
   */
1353
  public void setPressedIcon(Icon pressedIcon)
1354
  {
1355
    if (pressed_icon == pressedIcon)
1356
      return;
1357
 
1358
    Icon old = pressed_icon;
1359
    pressed_icon = pressedIcon;
1360
    firePropertyChange(PRESSED_ICON_CHANGED_PROPERTY, old, pressed_icon);
1361
    revalidate();
1362
    repaint();
1363
  }
1364
 
1365
  /**
1366
   * Return the button's "disabledIcon" property. The look and feel class
1367
   * should paint this icon when the "enabled" property of the button's
1368
   * {@link ButtonModel} is <code>false</code>. This property may be
1369
   * <code>null</code>, in which case an icon is constructed, based on the
1370
   * default icon.
1371
   *
1372
   * @return The current "disabledIcon" property
1373
   */
1374
  public Icon getDisabledIcon()
1375
  {
1376
    if (disabeldIcon == null && default_icon instanceof ImageIcon)
1377
      {
1378
        Image iconImage = ((ImageIcon) default_icon).getImage();
1379
        Image grayImage = GrayFilter.createDisabledImage(iconImage);
1380
        disabeldIcon = new ImageIcon(grayImage);
1381
      }
1382
 
1383
    return disabeldIcon;
1384
  }
1385
 
1386
  /**
1387
   * Set the button's "disabledIcon" property. The look and feel class should
1388
   * paint this icon when the "enabled" property of the button's {@link
1389
   * ButtonModel} is <code>false</code>. This property may be
1390
   * <code>null</code>, in which case an icon is constructed, based on the
1391
   * default icon.
1392
   *
1393
   * @param d The new "disabledIcon" property
1394
   */
1395
  public void setDisabledIcon(Icon d)
1396
  {
1397
    disabeldIcon = d;
1398
    revalidate();
1399
    repaint();
1400
  }
1401
 
1402
  /**
1403
   * Return the button's "paintFocus" property. This property controls
1404
   * whether or not the look and feel class will paint a special indicator
1405
   * of focus state for the button. If it is false, the button still paints
1406
   * when focused, but no special decoration is painted to indicate the
1407
   * presence of focus.
1408
   *
1409
   * @return The current "paintFocus" property
1410
   */
1411
  public boolean isFocusPainted()
1412
  {
1413
    return focusPainted;
1414
  }
1415
 
1416
  /**
1417
   * Set the button's "paintFocus" property. This property controls whether
1418
   * or not the look and feel class will paint a special indicator of focus
1419
   * state for the button. If it is false, the button still paints when
1420
   * focused, but no special decoration is painted to indicate the presence
1421
   * of focus.
1422
   *
1423
   * @param p The new "paintFocus" property
1424
   */
1425
  public void setFocusPainted(boolean p)
1426
  {
1427
    if (focusPainted == p)
1428
      return;
1429
 
1430
    boolean old = focusPainted;
1431
    focusPainted = p;
1432
    firePropertyChange(FOCUS_PAINTED_CHANGED_PROPERTY, old, p);
1433
    revalidate();
1434
    repaint();
1435
  }
1436
 
1437
  /**
1438
   * Verifies that a particular key is one of the valid constants used for
1439
   * describing horizontal alignment and positioning. The valid constants
1440
   * are the following members of {@link SwingConstants}:
1441
   * <code>RIGHT</code>, <code>LEFT</code>, <code>CENTER</code>,
1442
   * <code>LEADING</code> or <code>TRAILING</code>.
1443
   *
1444
   * @param key The key to check
1445
   * @param exception A message to include in an IllegalArgumentException
1446
   *
1447
   * @return the value of key
1448
   *
1449
   * @throws IllegalArgumentException If key is not one of the valid constants
1450
   *
1451
   * @see #setHorizontalTextPosition(int)
1452
   * @see #setHorizontalAlignment(int)
1453
   */
1454
  protected  int checkHorizontalKey(int key, String exception)
1455
  {
1456
    switch (key)
1457
      {
1458
      case SwingConstants.RIGHT:
1459
      case SwingConstants.LEFT:
1460
      case SwingConstants.CENTER:
1461
      case SwingConstants.LEADING:
1462
      case SwingConstants.TRAILING:
1463
        break;
1464
      default:
1465
        throw new IllegalArgumentException(exception);
1466
      }
1467
    return key;
1468
  }
1469
 
1470
  /**
1471
   * Verifies that a particular key is one of the valid constants used for
1472
   * describing vertical alignment and positioning. The valid constants are
1473
   * the following members of {@link SwingConstants}: <code>TOP</code>,
1474
   * <code>BOTTOM</code> or <code>CENTER</code>.
1475
   *
1476
   * @param key The key to check
1477
   * @param exception A message to include in an IllegalArgumentException
1478
   *
1479
   * @return the value of key
1480
   *
1481
   * @throws IllegalArgumentException If key is not one of the valid constants
1482
   *
1483
   * @see #setVerticalTextPosition(int)
1484
   * @see #setVerticalAlignment(int)
1485
   */
1486
  protected  int checkVerticalKey(int key, String exception)
1487
  {
1488
    switch (key)
1489
      {
1490
      case SwingConstants.TOP:
1491
      case SwingConstants.BOTTOM:
1492
      case SwingConstants.CENTER:
1493
        break;
1494
      default:
1495
        throw new IllegalArgumentException(exception);
1496
      }
1497
    return key;
1498
  }
1499
 
1500
  /**
1501
   * Configure various properties of the button by reading properties
1502
   * of an {@link Action}. The mapping of properties is as follows:
1503
   *
1504
   * <table>
1505
   *
1506
   * <tr><th>Action keyed property</th> <th>AbstractButton property</th></tr>
1507
   *
1508
   * <tr><td>NAME                 </td> <td>text                   </td></tr>
1509
   * <tr><td>SMALL_ICON           </td> <td>icon                   </td></tr>
1510
   * <tr><td>SHORT_DESCRIPTION    </td> <td>toolTipText            </td></tr>
1511
   * <tr><td>MNEMONIC_KEY         </td> <td>mnemonic               </td></tr>
1512
   * <tr><td>ACTION_COMMAND_KEY   </td> <td>actionCommand          </td></tr>
1513
   *
1514
   * </table>
1515
   *
1516
   * <p>In addition, this method always sets the button's "enabled" property to
1517
   * the value of the Action's "enabled" property.</p>
1518
   *
1519
   * <p>If the provided Action is <code>null</code>, the text, icon, and
1520
   * toolTipText properties of the button are set to <code>null</code>, and
1521
   * the "enabled" property is set to <code>true</code>; the mnemonic and
1522
   * actionCommand properties are unchanged.</p>
1523
   *
1524
   * @param a An Action to configure the button from
1525
   */
1526
  protected void configurePropertiesFromAction(Action a)
1527
  {
1528
    if (a == null)
1529
      {
1530
        setText(null);
1531
        setIcon(null);
1532
        setEnabled(true);
1533
        setToolTipText(null);
1534
      }
1535
    else
1536
      {
1537
        setText((String) (a.getValue(Action.NAME)));
1538
        setIcon((Icon) (a.getValue(Action.SMALL_ICON)));
1539
        setEnabled(a.isEnabled());
1540
        setToolTipText((String) (a.getValue(Action.SHORT_DESCRIPTION)));
1541
        if (a.getValue(Action.MNEMONIC_KEY) != null)
1542
          setMnemonic(((Integer) (a.getValue(Action.MNEMONIC_KEY))).intValue());
1543
        String actionCommand = (String) (a.getValue(Action.ACTION_COMMAND_KEY));
1544
 
1545
        // Set actionCommand to button's text by default if it is not specified
1546
        if (actionCommand != null)
1547
          setActionCommand((String) (a.getValue(Action.ACTION_COMMAND_KEY)));
1548
        else
1549
          setActionCommand(getText());
1550
      }
1551
  }
1552
 
1553
  /**
1554
   * <p>A factory method which should return an {@link ActionListener} that
1555
   * propagates events from the button's {@link ButtonModel} to any of the
1556
   * button's ActionListeners. By default, this is an inner class which
1557
   * calls {@link AbstractButton#fireActionPerformed} with a modified copy
1558
   * of the incoming model {@link ActionEvent}.</p>
1559
   *
1560
   * <p>The button calls this method during construction, stores the
1561
   * resulting ActionListener in its <code>actionListener</code> member
1562
   * field, and subscribes it to the button's model. If the button's model
1563
   * is changed, this listener is unsubscribed from the old model and
1564
   * subscribed to the new one.</p>
1565
   *
1566
   * @return A new ActionListener
1567
   */
1568
  protected  ActionListener createActionListener()
1569
  {
1570
    return new ActionListener()
1571
      {
1572
        public void actionPerformed(ActionEvent e)
1573
        {
1574
          AbstractButton.this.fireActionPerformed(e);
1575
        }
1576
      };
1577
  }
1578
 
1579
  /**
1580
   * <p>A factory method which should return a {@link PropertyChangeListener}
1581
   * that accepts changes to the specified {@link Action} and reconfigure
1582
   * the {@link AbstractButton}, by default using the {@link
1583
   * #configurePropertiesFromAction} method.</p>
1584
   *
1585
   * <p>The button calls this method whenever a new Action is assigned to
1586
   * the button's "action" property, via {@link #setAction}, and stores the
1587
   * resulting PropertyChangeListener in its
1588
   * <code>actionPropertyChangeListener</code> member field. The button
1589
   * then subscribes the listener to the button's new action. If the
1590
   * button's action is changed subsequently, the listener is unsubscribed
1591
   * from the old action and subscribed to the new one.</p>
1592
   *
1593
   * @param a The Action which will be listened to, and which should be
1594
   * the same as the source of any PropertyChangeEvents received by the
1595
   * new listener returned from this method.
1596
   *
1597
   * @return A new PropertyChangeListener
1598
   */
1599
  protected  PropertyChangeListener createActionPropertyChangeListener(Action a)
1600
  {
1601
    return new PropertyChangeListener()
1602
      {
1603
        public void propertyChange(PropertyChangeEvent e)
1604
        {
1605
          Action act = (Action) (e.getSource());
1606
          if (e.getPropertyName().equals("enabled"))
1607
            setEnabled(act.isEnabled());
1608
          else if (e.getPropertyName().equals(Action.NAME))
1609
            setText((String) (act.getValue(Action.NAME)));
1610
          else if (e.getPropertyName().equals(Action.SMALL_ICON))
1611
            setIcon((Icon) (act.getValue(Action.SMALL_ICON)));
1612
          else if (e.getPropertyName().equals(Action.SHORT_DESCRIPTION))
1613
            setToolTipText((String) (act.getValue(Action.SHORT_DESCRIPTION)));
1614
          else if (e.getPropertyName().equals(Action.MNEMONIC_KEY))
1615
            if (act.getValue(Action.MNEMONIC_KEY) != null)
1616
              setMnemonic(((Integer) (act.getValue(Action.MNEMONIC_KEY)))
1617
                          .intValue());
1618
          else if (e.getPropertyName().equals(Action.ACTION_COMMAND_KEY))
1619
            setActionCommand((String) (act.getValue(Action.ACTION_COMMAND_KEY)));
1620
        }
1621
      };
1622
  }
1623
 
1624
  /**
1625
   * <p>Factory method which creates a {@link ChangeListener}, used to
1626
   * subscribe to ChangeEvents from the button's model. Subclasses of
1627
   * AbstractButton may wish to override the listener used to subscribe to
1628
   * such ChangeEvents. By default, the listener just propagates the
1629
   * {@link ChangeEvent} to the button's ChangeListeners, via the {@link
1630
   * AbstractButton#fireStateChanged} method.</p>
1631
   *
1632
   * <p>The button calls this method during construction, stores the
1633
   * resulting ChangeListener in its <code>changeListener</code> member
1634
   * field, and subscribes it to the button's model. If the button's model
1635
   * is changed, this listener is unsubscribed from the old model and
1636
   * subscribed to the new one.</p>
1637
   *
1638
   * @return The new ChangeListener
1639
   */
1640
  protected ChangeListener createChangeListener()
1641
  {
1642
    return new ButtonChangeListener();
1643
  }
1644
 
1645
  /**
1646
   * <p>Factory method which creates a {@link ItemListener}, used to
1647
   * subscribe to ItemEvents from the button's model. Subclasses of
1648
   * AbstractButton may wish to override the listener used to subscribe to
1649
   * such ItemEvents. By default, the listener just propagates the
1650
   * {@link ItemEvent} to the button's ItemListeners, via the {@link
1651
   * AbstractButton#fireItemStateChanged} method.</p>
1652
   *
1653
   * <p>The button calls this method during construction, stores the
1654
   * resulting ItemListener in its <code>changeListener</code> member
1655
   * field, and subscribes it to the button's model. If the button's model
1656
   * is changed, this listener is unsubscribed from the old model and
1657
   * subscribed to the new one.</p>
1658
   *
1659
   * <p>Note that ItemEvents are only generated from the button's model
1660
   * when the model's <em>selected</em> property changes. If you want to
1661
   * subscribe to other properties of the model, you must subscribe to
1662
   * ChangeEvents.
1663
   *
1664
   * @return The new ItemListener
1665
   */
1666
  protected  ItemListener createItemListener()
1667
  {
1668
    return new ItemListener()
1669
      {
1670
        public void itemStateChanged(ItemEvent e)
1671
        {
1672
          AbstractButton.this.fireItemStateChanged(e);
1673
        }
1674
      };
1675
  }
1676
 
1677
  /**
1678
   * Programmatically perform a "click" on the button: arming, pressing,
1679
   * waiting, un-pressing, and disarming the model.
1680
   */
1681
  public void doClick()
1682
  {
1683
    doClick(100);
1684
  }
1685
 
1686
  /**
1687
   * Programmatically perform a "click" on the button: arming, pressing,
1688
   * waiting, un-pressing, and disarming the model.
1689
   *
1690
   * @param pressTime The number of milliseconds to wait in the pressed state
1691
   */
1692
  public void doClick(int pressTime)
1693
  {
1694
    ButtonModel mod = getModel();
1695
    if (mod != null)
1696
      {
1697
        mod.setArmed(true);
1698
        mod.setPressed(true);
1699
        try
1700
          {
1701
            java.lang.Thread.sleep(pressTime);
1702
          }
1703
        catch (java.lang.InterruptedException e)
1704
          {
1705
            // probably harmless
1706
          }
1707
        mod.setPressed(false);
1708
        mod.setArmed(false);
1709
      }
1710
  }
1711
 
1712
  /**
1713
   * Return the button's disabled selected icon. The look and feel class
1714
   * should paint this icon when the "enabled" property of the button's model
1715
   * is <code>false</code> and its "selected" property is
1716
   * <code>true</code>. This icon can be <code>null</code>, in which case
1717
   * it is synthesized from the button's selected icon.
1718
   *
1719
   * @return The current disabled selected icon
1720
   */
1721
  public Icon getDisabledSelectedIcon()
1722
  {
1723
    return disabledSelectedIcon;
1724
  }
1725
 
1726
  /**
1727
   * Set the button's disabled selected icon. The look and feel class
1728
   * should paint this icon when the "enabled" property of the button's model
1729
   * is <code>false</code> and its "selected" property is
1730
   * <code>true</code>. This icon can be <code>null</code>, in which case
1731
   * it is synthesized from the button's selected icon.
1732
   *
1733
   * @param icon The new disabled selected icon
1734
   */
1735
  public void setDisabledSelectedIcon(Icon icon)
1736
  {
1737
    if (disabledSelectedIcon == icon)
1738
      return;
1739
 
1740
    Icon old = disabledSelectedIcon;
1741
    disabledSelectedIcon = icon;
1742
    firePropertyChange(DISABLED_SELECTED_ICON_CHANGED_PROPERTY, old, icon);
1743
    revalidate();
1744
    repaint();
1745
  }
1746
 
1747
  /**
1748
   * Return the button's rollover icon. The look and feel class should
1749
   * paint this icon when the "rolloverEnabled" property of the button is
1750
   * <code>true</code> and the mouse rolls over the button.
1751
   *
1752
   * @return The current rollover icon
1753
   */
1754
  public Icon getRolloverIcon()
1755
  {
1756
    return rolloverIcon;
1757
  }
1758
 
1759
  /**
1760
   * Set the button's rollover icon. The look and feel class should
1761
   * paint this icon when the "rolloverEnabled" property of the button is
1762
   * <code>true</code> and the mouse rolls over the button.
1763
   *
1764
   * @param r The new rollover icon
1765
   */
1766
  public void setRolloverIcon(Icon r)
1767
  {
1768
    if (rolloverIcon == r)
1769
      return;
1770
 
1771
    Icon old = rolloverIcon;
1772
    rolloverIcon = r;
1773
    firePropertyChange(ROLLOVER_ICON_CHANGED_PROPERTY, old, rolloverIcon);
1774
    revalidate();
1775
    repaint();
1776
  }
1777
 
1778
  /**
1779
   * Return the button's rollover selected icon. The look and feel class
1780
   * should paint this icon when the "rolloverEnabled" property of the button
1781
   * is <code>true</code>, the "selected" property of the button's model is
1782
   * <code>true</code>, and the mouse rolls over the button.
1783
   *
1784
   * @return The current rollover selected icon
1785
   */
1786
  public Icon getRolloverSelectedIcon()
1787
  {
1788
    return rolloverSelectedIcon;
1789
  }
1790
 
1791
  /**
1792
   * Set the button's rollover selected icon. The look and feel class
1793
   * should paint this icon when the "rolloverEnabled" property of the button
1794
   * is <code>true</code>, the "selected" property of the button's model is
1795
   * <code>true</code>, and the mouse rolls over the button.
1796
   *
1797
   * @param r The new rollover selected icon
1798
   */
1799
  public void setRolloverSelectedIcon(Icon r)
1800
  {
1801
    if (rolloverSelectedIcon == r)
1802
      return;
1803
 
1804
    Icon old = rolloverSelectedIcon;
1805
    rolloverSelectedIcon = r;
1806
    firePropertyChange(ROLLOVER_SELECTED_ICON_CHANGED_PROPERTY, old, r);
1807
    revalidate();
1808
    repaint();
1809
  }
1810
 
1811
  /**
1812
   * Return the button's selected icon. The look and feel class should
1813
   * paint this icon when the "selected" property of the button's model is
1814
   * <code>true</code>, and either the "rolloverEnabled" property of the
1815
   * button is <code>false</code> or the mouse is not currently rolled
1816
   * over the button.
1817
   *
1818
   * @return The current selected icon
1819
   */
1820
  public Icon getSelectedIcon()
1821
  {
1822
    return selectedIcon;
1823
  }
1824
 
1825
  /**
1826
   * Set the button's selected icon. The look and feel class should
1827
   * paint this icon when the "selected" property of the button's model is
1828
   * <code>true</code>, and either the "rolloverEnabled" property of the
1829
   * button is <code>false</code> or the mouse is not currently rolled
1830
   * over the button.
1831
   *
1832
   * @param s The new selected icon
1833
   */
1834
  public void setSelectedIcon(Icon s)
1835
  {
1836
    if (selectedIcon == s)
1837
      return;
1838
 
1839
    Icon old = selectedIcon;
1840
    selectedIcon = s;
1841
    firePropertyChange(SELECTED_ICON_CHANGED_PROPERTY, old, s);
1842
    revalidate();
1843
    repaint();
1844
  }
1845
 
1846
  /**
1847
   * Returns an single-element array containing the "text" property of the
1848
   * button if the "selected" property of the button's model is
1849
   * <code>true</code>, otherwise returns <code>null</code>.
1850
   *
1851
   * @return The button's "selected object" array
1852
   */
1853
  public Object[] getSelectedObjects()
1854
  {
1855
    if (isSelected())
1856
      {
1857
        Object[] objs = new Object[1];
1858
        objs[0] = getText();
1859
        return objs;
1860
      }
1861
    else
1862
      {
1863
        return null;
1864
      }
1865
  }
1866
 
1867
  /**
1868
   * Called when image data becomes available for one of the button's icons.
1869
   *
1870
   * @param img The image being updated
1871
   * @param infoflags One of the constant codes in {@link ImageObserver} used
1872
   *     to describe updated portions of an image.
1873
   * @param x X coordinate of the region being updated
1874
   * @param y Y coordinate of the region being updated
1875
   * @param w Width of the region beign updated
1876
   * @param h Height of the region being updated
1877
   *
1878
   * @return <code>true</code> if img is equal to the button's current icon,
1879
   *     otherwise <code>false</code>
1880
   */
1881
  public boolean imageUpdate(Image img, int infoflags, int x, int y, int w,
1882
                             int h)
1883
  {
1884
    return current_icon == img;
1885
  }
1886
 
1887
  /**
1888
   * Returns the value of the button's "contentAreaFilled" property. This
1889
   * property indicates whether the area surrounding the text and icon of
1890
   * the button should be filled by the look and feel class.  If this
1891
   * property is <code>false</code>, the look and feel class should leave
1892
   * the content area transparent.
1893
   *
1894
   * @return The current value of the "contentAreaFilled" property
1895
   */
1896
  public boolean isContentAreaFilled()
1897
  {
1898
    return contentAreaFilled;
1899
  }
1900
 
1901
  /**
1902
   * Sets the value of the button's "contentAreaFilled" property. This
1903
   * property indicates whether the area surrounding the text and icon of
1904
   * the button should be filled by the look and feel class.  If this
1905
   * property is <code>false</code>, the look and feel class should leave
1906
   * the content area transparent.
1907
   *
1908
   * @param b The new value of the "contentAreaFilled" property
1909
   */
1910
  public void setContentAreaFilled(boolean b)
1911
  {
1912
    if (contentAreaFilled == b)
1913
      return;
1914
 
1915
    boolean old = contentAreaFilled;
1916
    contentAreaFilled = b;
1917
    firePropertyChange(CONTENT_AREA_FILLED_CHANGED_PROPERTY, old, b);
1918
    // The JDK sets the opaque property to the value of the contentAreaFilled
1919
    // property, so should we do.
1920
    setOpaque(b);
1921
   }
1922
 
1923
  /**
1924
   * Paints the button's border, if the button's "borderPainted" property is
1925
   * <code>true</code>, by out calling to the button's look and feel class.
1926
   *
1927
   * @param g The graphics context used to paint the border
1928
   */
1929
  protected void paintBorder(Graphics g)
1930
  {
1931
    if (isBorderPainted())
1932
      super.paintBorder(g);
1933
  }
1934
 
1935
  /**
1936
   * Returns a string, used only for debugging, which identifies or somehow
1937
   * represents this button. The exact value is implementation-defined.
1938
   *
1939
   * @return A string representation of the button
1940
   */
1941
  protected String paramString()
1942
  {
1943
    StringBuffer sb = new StringBuffer();
1944
    sb.append(super.paramString());
1945
    sb.append(",defaultIcon=");
1946
    if (getIcon() != null)
1947
      sb.append(getIcon());
1948
    sb.append(",disabledIcon=");
1949
    if (getDisabledIcon() != null)
1950
      sb.append(getDisabledIcon());
1951
    sb.append(",disabledSelectedIcon=");
1952
    if (getDisabledSelectedIcon() != null)
1953
      sb.append(getDisabledSelectedIcon());
1954
    sb.append(",margin=");
1955
    if (getMargin() != null)
1956
      sb.append(getMargin());
1957
    sb.append(",paintBorder=").append(isBorderPainted());
1958
    sb.append(",paintFocus=").append(isFocusPainted());
1959
    sb.append(",pressedIcon=");
1960
    if (getPressedIcon() != null)
1961
      sb.append(getPressedIcon());
1962
    sb.append(",rolloverEnabled=").append(isRolloverEnabled());
1963
    sb.append(",rolloverIcon=");
1964
    if (getRolloverIcon() != null)
1965
      sb.append(getRolloverIcon());
1966
    sb.append(",rolloverSelected=");
1967
    if (getRolloverSelectedIcon() != null)
1968
      sb.append(getRolloverSelectedIcon());
1969
    sb.append(",selectedIcon=");
1970
    if (getSelectedIcon() != null)
1971
      sb.append(getSelectedIcon());
1972
    sb.append(",text=");
1973
    if (getText() != null)
1974
      sb.append(getText());
1975
    return sb.toString();
1976
  }
1977
 
1978
  /**
1979
   * Set the "UI" property of the button, which is a look and feel class
1980
   * responsible for handling the button's input events and painting it.
1981
   *
1982
   * @param ui The new "UI" property
1983
   */
1984
  public void setUI(ButtonUI ui)
1985
  {
1986
    super.setUI(ui);
1987
  }
1988
 
1989
  /**
1990
   * Set the "UI" property of the button, which is a look and feel class
1991
   * responsible for handling the button's input events and painting it.
1992
   *
1993
   * @return The current "UI" property
1994
   */
1995
  public ButtonUI getUI()
1996
  {
1997
    return (ButtonUI) ui;
1998
  }
1999
 
2000
  /**
2001
   * Set the "UI" property to a class constructed, via the {@link
2002
   * UIManager}, from the current look and feel. This should be overridden
2003
   * for each subclass of AbstractButton, to retrieve a suitable {@link
2004
   * ButtonUI} look and feel class.
2005
   */
2006
  public void updateUI()
2007
  {
2008
    // TODO: What to do here?
2009
  }
2010
 
2011
  /**
2012
   * Returns the current time in milliseconds in which clicks gets coalesced
2013
   * into a single <code>ActionEvent</code>.
2014
   *
2015
   * @return the time in milliseconds
2016
   *
2017
   * @since 1.4
2018
   */
2019
  public long getMultiClickThreshhold()
2020
  {
2021
    return multiClickThreshhold;
2022
  }
2023
 
2024
  /**
2025
   * Sets the time in milliseconds in which clicks gets coalesced into a single
2026
   * <code>ActionEvent</code>.
2027
   *
2028
   * @param threshhold the time in milliseconds
2029
   *
2030
   * @since 1.4
2031
   */
2032
  public void setMultiClickThreshhold(long threshhold)
2033
  {
2034
    if (threshhold < 0)
2035
      throw new IllegalArgumentException();
2036
 
2037
    multiClickThreshhold = threshhold;
2038
  }
2039
}

powered by: WebSVN 2.1.0

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