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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 772 jeremybenn
/* BasicButtonUI.java --
2
   Copyright (C) 2002, 2004, 2005  Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
 
39
package javax.swing.plaf.basic;
40
 
41
import java.awt.Dimension;
42
import java.awt.Font;
43
import java.awt.FontMetrics;
44
import java.awt.Graphics;
45
import java.awt.Insets;
46
import java.awt.Rectangle;
47
import java.beans.PropertyChangeEvent;
48
import java.beans.PropertyChangeListener;
49
 
50
import javax.swing.AbstractButton;
51
import javax.swing.ButtonModel;
52
import javax.swing.Icon;
53
import javax.swing.JButton;
54
import javax.swing.JComponent;
55
import javax.swing.LookAndFeel;
56
import javax.swing.SwingUtilities;
57
import javax.swing.UIManager;
58
import javax.swing.plaf.ButtonUI;
59
import javax.swing.plaf.ComponentUI;
60
import javax.swing.plaf.UIResource;
61
import javax.swing.text.View;
62
 
63
/**
64
 * A UI delegate for the {@link JButton} component.
65
 */
66
public class BasicButtonUI extends ButtonUI
67
{
68
  /**
69
   * Cached rectangle for layouting the label. Used in paint() and
70
   * BasicGraphicsUtils.getPreferredButtonSize().
71
   */
72
  static Rectangle viewR = new Rectangle();
73
 
74
  /**
75
   * Cached rectangle for layouting the label. Used in paint() and
76
   * BasicGraphicsUtils.getPreferredButtonSize().
77
   */
78
  static Rectangle iconR = new Rectangle();
79
 
80
  /**
81
   * Cached rectangle for layouting the label. Used in paint() and
82
   * BasicGraphicsUtils.getPreferredButtonSize().
83
   */
84
  static Rectangle textR = new Rectangle();
85
 
86
  /**
87
   * Cached Insets instance, used in paint().
88
   */
89
  static Insets cachedInsets;
90
 
91
  /**
92
   * The shared button UI.
93
   */
94
  private static BasicButtonUI sharedUI;
95
 
96
  /**
97
   * The shared BasicButtonListener.
98
   */
99
  private static BasicButtonListener sharedListener;
100
 
101
  /**
102
   * A constant used to pad out elements in the button's layout and
103
   * preferred size calculations.
104
   */
105
  protected int defaultTextIconGap = 4;
106
 
107
  /**
108
   * A constant added to the defaultTextIconGap to adjust the text
109
   * within this particular button.
110
   */
111
  protected int defaultTextShiftOffset;
112
 
113
  private int textShiftOffset;
114
 
115
  /**
116
   * Factory method to create an instance of BasicButtonUI for a given
117
   * {@link JComponent}, which should be an {@link AbstractButton}.
118
   *
119
   * @param c The component.
120
   *
121
   * @return A new UI capable of drawing the component
122
   */
123
  public static ComponentUI createUI(final JComponent c)
124
  {
125
    if (sharedUI == null)
126
      sharedUI = new BasicButtonUI();
127
    return sharedUI;
128
  }
129
 
130
  /**
131
   * Returns the default gap between the button's text and icon (in pixels).
132
   *
133
   * @param b  the button (ignored).
134
   *
135
   * @return The gap.
136
   */
137
  public int getDefaultTextIconGap(AbstractButton b)
138
  {
139
    return defaultTextIconGap;
140
  }
141
 
142
  /**
143
   * Sets the text shift offset to zero.
144
   *
145
   * @see #setTextShiftOffset()
146
   */
147
  protected void clearTextShiftOffset()
148
  {
149
    textShiftOffset = 0;
150
  }
151
 
152
  /**
153
   * Returns the text shift offset.
154
   *
155
   * @return The text shift offset.
156
   *
157
   * @see #clearTextShiftOffset()
158
   * @see #setTextShiftOffset()
159
   */
160
  protected int getTextShiftOffset()
161
  {
162
    return textShiftOffset;
163
  }
164
 
165
  /**
166
   * Sets the text shift offset to the value in {@link #defaultTextShiftOffset}.
167
   *
168
   * @see #clearTextShiftOffset()
169
   */
170
  protected void setTextShiftOffset()
171
  {
172
    textShiftOffset = defaultTextShiftOffset;
173
  }
174
 
175
  /**
176
   * Returns the prefix for the UI defaults property for this UI class.
177
   * This is 'Button' for this class.
178
   *
179
   * @return the prefix for the UI defaults property
180
   */
181
  protected String getPropertyPrefix()
182
  {
183
    return "Button.";
184
  }
185
 
186
  /**
187
   * Installs the default settings.
188
   *
189
   * @param b  the button (<code>null</code> not permitted).
190
   */
191
  protected void installDefaults(AbstractButton b)
192
  {
193
    String prefix = getPropertyPrefix();
194
    // Install colors and font.
195
    LookAndFeel.installColorsAndFont(b, prefix + "background",
196
                                     prefix + "foreground", prefix + "font");
197
    // Install border.
198
    LookAndFeel.installBorder(b, prefix + "border");
199
 
200
    // Install margin property.
201
    if (b.getMargin() == null || b.getMargin() instanceof UIResource)
202
      b.setMargin(UIManager.getInsets(prefix + "margin"));
203
 
204
    // Install rollover property.
205
    Object rollover = UIManager.get(prefix + "rollover");
206
    if (rollover != null)
207
      LookAndFeel.installProperty(b, "rolloverEnabled", rollover);
208
 
209
    // Fetch default textShiftOffset.
210
    defaultTextShiftOffset = UIManager.getInt(prefix + "textShiftOffset");
211
 
212
    // Make button opaque if needed.
213
    if (b.isContentAreaFilled())
214
      LookAndFeel.installProperty(b, "opaque", Boolean.TRUE);
215
    else
216
      LookAndFeel.installProperty(b, "opaque", Boolean.FALSE);
217
  }
218
 
219
  /**
220
   * Removes the defaults added by {@link #installDefaults(AbstractButton)}.
221
   *
222
   * @param b  the button (<code>null</code> not permitted).
223
   */
224
  protected void uninstallDefaults(AbstractButton b)
225
  {
226
    // The other properties aren't uninstallable.
227
    LookAndFeel.uninstallBorder(b);
228
  }
229
 
230
  /**
231
   * Creates and returns a new instance of {@link BasicButtonListener}.  This
232
   * method provides a hook to make it easy for subclasses to install a
233
   * different listener.
234
   *
235
   * @param b  the button.
236
   *
237
   * @return A new listener.
238
   */
239
  protected BasicButtonListener createButtonListener(AbstractButton b)
240
  {
241
    // Note: The RI always returns a new instance here. However,
242
    // the BasicButtonListener class is perfectly suitable to be shared
243
    // between multiple buttons, so we return a shared instance here
244
    // for efficiency.
245
    if (sharedListener == null)
246
      sharedListener = new BasicButtonListener(b);
247
    return sharedListener;
248
  }
249
 
250
  /**
251
   * Installs listeners for the button.
252
   *
253
   * @param b  the button (<code>null</code> not permitted).
254
   */
255
  protected void installListeners(AbstractButton b)
256
  {
257
    BasicButtonListener listener = createButtonListener(b);
258
    if (listener != null)
259
      {
260
        b.addChangeListener(listener);
261
        b.addPropertyChangeListener(listener);
262
        b.addFocusListener(listener);
263
        b.addMouseListener(listener);
264
        b.addMouseMotionListener(listener);
265
      }
266
    // Fire synthetic property change event to let the listener update
267
    // the TextLayout cache.
268
    listener.propertyChange(new PropertyChangeEvent(b, "font", null,
269
                                                    b.getFont()));
270
  }
271
 
272
  /**
273
   * Uninstalls listeners for the button.
274
   *
275
   * @param b  the button (<code>null</code> not permitted).
276
   */
277
  protected void uninstallListeners(AbstractButton b)
278
  {
279
    BasicButtonListener listener = getButtonListener(b);
280
    if (listener != null)
281
      {
282
        b.removeChangeListener(listener);
283
        b.removePropertyChangeListener(listener);
284
        b.removeFocusListener(listener);
285
        b.removeMouseListener(listener);
286
        b.removeMouseMotionListener(listener);
287
      }
288
  }
289
 
290
  protected void installKeyboardActions(AbstractButton b)
291
  {
292
    BasicButtonListener listener = getButtonListener(b);
293
    if (listener != null)
294
      listener.installKeyboardActions(b);
295
  }
296
 
297
  protected void uninstallKeyboardActions(AbstractButton b)
298
  {
299
    BasicButtonListener listener = getButtonListener(b);
300
    if (listener != null)
301
      listener.uninstallKeyboardActions(b);
302
  }
303
 
304
  /**
305
   * Install the BasicButtonUI as the UI for a particular component.
306
   * This means registering all the UI's listeners with the component,
307
   * and setting any properties of the button which are particular to
308
   * this look and feel.
309
   *
310
   * @param c The component to install the UI into
311
   */
312
  public void installUI(final JComponent c)
313
  {
314
    super.installUI(c);
315
    if (c instanceof AbstractButton)
316
      {
317
        AbstractButton b = (AbstractButton) c;
318
        installDefaults(b);
319
        // It is important to install the listeners before installing
320
        // the keyboard actions, because the keyboard actions
321
        // are actually installed on the listener instance.
322
        installListeners(b);
323
        installKeyboardActions(b);
324
        BasicHTML.updateRenderer(b, b.getText());
325
      }
326
  }
327
 
328
  /**
329
   * Uninstalls the UI from the component.
330
   *
331
   * @param c the component from which to uninstall the UI
332
   */
333
  public void uninstallUI(JComponent c)
334
  {
335
    if (c instanceof AbstractButton)
336
      {
337
        AbstractButton b = (AbstractButton) c;
338
        uninstallKeyboardActions(b);
339
        uninstallListeners(b);
340
        uninstallDefaults(b);
341
        BasicHTML.updateRenderer(b, "");
342
        b.putClientProperty(BasicGraphicsUtils.CACHED_TEXT_LAYOUT, null);
343
      }
344
  }
345
 
346
  /**
347
   * Calculates the minimum size for the specified component.
348
   *
349
   * @param c the component for which to compute the minimum size
350
   *
351
   * @return the minimum size for the specified component
352
   */
353
  public Dimension getMinimumSize(JComponent c)
354
  {
355
    Dimension size = getPreferredSize(c);
356
    // When the HTML view has a minimum width different from the preferred
357
    // width, then substract this here accordingly. The height is not
358
    // affected by that.
359
    View html = (View) c.getClientProperty(BasicHTML.propertyKey);
360
    if (html != null)
361
      {
362
        size.width -= html.getPreferredSpan(View.X_AXIS)
363
                      - html.getPreferredSpan(View.X_AXIS);
364
      }
365
    return size;
366
  }
367
 
368
  /**
369
   * Calculates the maximum size for the specified component.
370
   *
371
   * @param c the component for which to compute the maximum size
372
   *
373
   * @return the maximum size for the specified component
374
   */
375
  public Dimension getMaximumSize(JComponent c)
376
  {
377
    Dimension size = getPreferredSize(c);
378
    // When the HTML view has a maximum width different from the preferred
379
    // width, then add this here accordingly. The height is not
380
    // affected by that.
381
    View html = (View) c.getClientProperty(BasicHTML.propertyKey);
382
    if (html != null)
383
      {
384
        size.width += html.getMaximumSpan(View.X_AXIS)
385
                      - html.getPreferredSpan(View.X_AXIS);
386
      }
387
    return size;
388
  }
389
 
390
  /**
391
   * Calculate the preferred size of this component, by delegating to
392
   * {@link BasicGraphicsUtils#getPreferredButtonSize}.
393
   *
394
   * @param c The component to measure
395
   *
396
   * @return The preferred dimensions of the component
397
   */
398
  public Dimension getPreferredSize(JComponent c)
399
  {
400
    AbstractButton b = (AbstractButton) c;
401
    Dimension d = BasicGraphicsUtils.getPreferredButtonSize(b,
402
                                                           b.getIconTextGap());
403
    return d;
404
  }
405
 
406
  static Icon currentIcon(AbstractButton b)
407
  {
408
    Icon i = b.getIcon();
409
    ButtonModel model = b.getModel();
410
 
411
    if (model.isPressed() && b.getPressedIcon() != null && b.isEnabled())
412
      i = b.getPressedIcon();
413
 
414
    else if (model.isRollover())
415
      {
416
        if (b.isSelected() && b.getRolloverSelectedIcon() != null)
417
          i = b.getRolloverSelectedIcon();
418
        else if (b.getRolloverIcon() != null)
419
          i = b.getRolloverIcon();
420
      }
421
 
422
    else if (b.isSelected() && b.isEnabled())
423
      {
424
        if (b.isEnabled() && b.getSelectedIcon() != null)
425
          i = b.getSelectedIcon();
426
        else if (b.getDisabledSelectedIcon() != null)
427
          i = b.getDisabledSelectedIcon();
428
      }
429
 
430
    else if (! b.isEnabled() && b.getDisabledIcon() != null)
431
      i = b.getDisabledIcon();
432
 
433
    return i;
434
  }
435
 
436
  /**
437
   * Paint the component, which is an {@link AbstractButton}, according to
438
   * its current state.
439
   *
440
   * @param g The graphics context to paint with
441
   * @param c The component to paint the state of
442
   */
443
  public void paint(Graphics g, JComponent c)
444
  {
445
    AbstractButton b = (AbstractButton) c;
446
 
447
    Insets i = c.getInsets(cachedInsets);
448
    viewR.x = i.left;
449
    viewR.y = i.top;
450
    viewR.width = c.getWidth() - i.left - i.right;
451
    viewR.height = c.getHeight() - i.top - i.bottom;
452
    textR.x = 0;
453
    textR.y = 0;
454
    textR.width = 0;
455
    textR.height = 0;
456
    iconR.x = 0;
457
    iconR.y = 0;
458
    iconR.width = 0;
459
    iconR.height = 0;
460
 
461
    Font f = c.getFont();
462
    g.setFont(f);
463
    Icon icon = b.getIcon();
464
    String text = b.getText();
465
    text = SwingUtilities.layoutCompoundLabel(c, g.getFontMetrics(f),
466
                                              text, icon,
467
                                              b.getVerticalAlignment(),
468
                                              b.getHorizontalAlignment(),
469
                                              b.getVerticalTextPosition(),
470
                                              b.getHorizontalTextPosition(),
471
                                              viewR, iconR, textR,
472
                                              text == null ? 0
473
                                                         : b.getIconTextGap());
474
 
475
    ButtonModel model = b.getModel();
476
    if (model.isArmed() && model.isPressed())
477
      paintButtonPressed(g, b);
478
 
479
    if (icon != null)
480
      paintIcon(g, c, iconR);
481
    if (text != null)
482
      {
483
        View html = (View) b.getClientProperty(BasicHTML.propertyKey);
484
        if (html != null)
485
          html.paint(g, textR);
486
        else
487
          paintText(g, b, textR, text);
488
      }
489
    if (b.isFocusOwner() && b.isFocusPainted())
490
      paintFocus(g, b, viewR, textR, iconR);
491
  }
492
 
493
  /**
494
   * Paint any focus decoration this {@link JComponent} might have.  The
495
   * component, which in this case will be an {@link AbstractButton},
496
   * should only have focus decoration painted if it has the focus, and its
497
   * "focusPainted" property is <code>true</code>.
498
   *
499
   * @param g Graphics context to paint with
500
   * @param b Button to paint the focus of
501
   * @param vr Visible rectangle, the area in which to paint
502
   * @param tr Text rectangle, contained in visible rectangle
503
   * @param ir Icon rectangle, contained in visible rectangle
504
   *
505
   * @see AbstractButton#isFocusPainted()
506
   * @see JComponent#hasFocus()
507
   */
508
  protected void paintFocus(Graphics g, AbstractButton b, Rectangle vr,
509
                            Rectangle tr, Rectangle ir)
510
  {
511
    // In the BasicLookAndFeel no focus border is drawn. This can be
512
    // overridden in subclasses to implement such behaviour.
513
  }
514
 
515
  /**
516
   * Paint the icon for this component. Depending on the state of the
517
   * component and the availability of the button's various icon
518
   * properties, this might mean painting one of several different icons.
519
   *
520
   * @param g Graphics context to paint with
521
   * @param c Component to paint the icon of
522
   * @param iconRect Rectangle in which the icon should be painted
523
   */
524
  protected void paintIcon(Graphics g, JComponent c, Rectangle iconRect)
525
  {
526
    AbstractButton b = (AbstractButton) c;
527
    Icon i = currentIcon(b);
528
 
529
    if (i != null)
530
      {
531
        ButtonModel m = b.getModel();
532
        if (m.isPressed() && m.isArmed())
533
          {
534
            int offs = getTextShiftOffset();
535
            i.paintIcon(c, g, iconRect.x + offs, iconRect.y + offs);
536
          }
537
        else
538
          i.paintIcon(c, g, iconRect.x, iconRect.y);
539
      }
540
  }
541
 
542
  /**
543
   * Paints the background area of an {@link AbstractButton} in the pressed
544
   * state.  This means filling the supplied area with a darker than normal
545
   * background.
546
   *
547
   * @param g The graphics context to paint with
548
   * @param b The button to paint the state of
549
   */
550
  protected void paintButtonPressed(Graphics g, AbstractButton b)
551
  {
552
    if (b.isContentAreaFilled() && b.isOpaque())
553
      {
554
        Rectangle area = new Rectangle();
555
        SwingUtilities.calculateInnerArea(b, area);
556
        g.setColor(UIManager.getColor(getPropertyPrefix() + "shadow"));
557
        g.fillRect(area.x, area.y, area.width, area.height);
558
      }
559
  }
560
 
561
  /**
562
   * Paints the "text" property of an {@link AbstractButton}.
563
   *
564
   * @param g The graphics context to paint with
565
   * @param c The component to paint the state of
566
   * @param textRect The area in which to paint the text
567
   * @param text The text to paint
568
   */
569
  protected void paintText(Graphics g, JComponent c, Rectangle textRect,
570
                           String text)
571
  {
572
    AbstractButton b = (AbstractButton) c;
573
    Font f = b.getFont();
574
    g.setFont(f);
575
    FontMetrics fm = g.getFontMetrics(f);
576
 
577
    if (b.isEnabled())
578
      {
579
        g.setColor(b.getForeground());
580
        // FIXME: Underline mnemonic.
581
        BasicGraphicsUtils.drawString(b, g, text, -1, textRect.x,
582
                                      textRect.y + fm.getAscent());
583
      }
584
    else
585
      {
586
        String prefix = getPropertyPrefix();
587
        g.setColor(UIManager.getColor(prefix + "disabledText"));
588
        // FIXME: Underline mnemonic.
589
        BasicGraphicsUtils.drawString(b, g, text, -1, textRect.x,
590
                                      textRect.y + fm.getAscent());
591
      }
592
  }
593
 
594
  /**
595
   * Paints the "text" property of an {@link AbstractButton}.
596
   *
597
   * @param g The graphics context to paint with
598
   * @param b The button to paint the state of
599
   * @param textRect The area in which to paint the text
600
   * @param text The text to paint
601
   *
602
   * @since 1.4
603
   */
604
  protected void paintText(Graphics g, AbstractButton b, Rectangle textRect,
605
                           String text)
606
  {
607
    paintText(g, (JComponent) b, textRect, text);
608
  }
609
 
610
  /**
611
   * A helper method that finds the BasicButtonListener for the specified
612
   * button. This is there because this UI class is stateless and
613
   * shared for all buttons, and thus can't store the listener
614
   * as instance field. (We store our shared instance in sharedListener,
615
   * however, subclasses may override createButtonListener() and we would
616
   * be lost in this case).
617
   *
618
   * @param b the button
619
   *
620
   * @return the UI event listener
621
   */
622
  private BasicButtonListener getButtonListener(AbstractButton b)
623
  {
624
    // The listener gets installed as PropertyChangeListener,
625
    // so look for it in the list of property change listeners.
626
    PropertyChangeListener[] listeners = b.getPropertyChangeListeners();
627
    BasicButtonListener l = null;
628
    for (int i = 0; listeners != null && l == null && i < listeners.length;
629
           i++)
630
      {
631
        if (listeners[i] instanceof BasicButtonListener)
632
          l = (BasicButtonListener) listeners[i];
633
      }
634
    return l;
635
  }
636
}

powered by: WebSVN 2.1.0

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