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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 772 jeremybenn
/* BasicOptionPaneUI.java --
2
   Copyright (C) 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.BorderLayout;
42
import java.awt.Color;
43
import java.awt.Component;
44
import java.awt.Container;
45
import java.awt.Dimension;
46
import java.awt.Font;
47
import java.awt.Graphics;
48
import java.awt.GridBagConstraints;
49
import java.awt.GridBagLayout;
50
import java.awt.Insets;
51
import java.awt.LayoutManager;
52
import java.awt.Polygon;
53
import java.awt.Window;
54
import java.awt.event.ActionEvent;
55
import java.awt.event.ActionListener;
56
import java.beans.PropertyChangeEvent;
57
import java.beans.PropertyChangeListener;
58
import java.beans.PropertyVetoException;
59
 
60
import javax.swing.AbstractAction;
61
import javax.swing.Action;
62
import javax.swing.ActionMap;
63
import javax.swing.BorderFactory;
64
import javax.swing.Box;
65
import javax.swing.BoxLayout;
66
import javax.swing.Icon;
67
import javax.swing.InputMap;
68
import javax.swing.JButton;
69
import javax.swing.JComboBox;
70
import javax.swing.JComponent;
71
import javax.swing.JDialog;
72
import javax.swing.JInternalFrame;
73
import javax.swing.JLabel;
74
import javax.swing.JList;
75
import javax.swing.JOptionPane;
76
import javax.swing.JPanel;
77
import javax.swing.JTextField;
78
import javax.swing.LookAndFeel;
79
import javax.swing.SwingUtilities;
80
import javax.swing.UIManager;
81
import javax.swing.border.Border;
82
import javax.swing.plaf.ActionMapUIResource;
83
import javax.swing.plaf.ComponentUI;
84
import javax.swing.plaf.OptionPaneUI;
85
 
86
/**
87
 * This class is the UI delegate for JOptionPane in the Basic Look and Feel.
88
 */
89
public class BasicOptionPaneUI extends OptionPaneUI
90
{
91
  /**
92
   * Implements the "close" keyboard action.
93
   */
94
  static class OptionPaneCloseAction
95
    extends AbstractAction
96
  {
97
 
98
    public void actionPerformed(ActionEvent event)
99
    {
100
      JOptionPane op = (JOptionPane) event.getSource();
101
      op.setValue(new Integer(JOptionPane.CLOSED_OPTION));
102
    }
103
 
104
  }
105
 
106
  /**
107
   * This is a helper class that listens to the buttons located at the bottom
108
   * of the JOptionPane.
109
   *
110
   * @specnote Apparently this class was intended to be protected,
111
   *           but was made public by a compiler bug and is now
112
   *           public for compatibility.
113
   */
114
  public class ButtonActionListener implements ActionListener
115
  {
116
    /** The index of the option this button represents. */
117
    protected int buttonIndex;
118
 
119
    /**
120
     * Creates a new ButtonActionListener object with the given buttonIndex.
121
     *
122
     * @param buttonIndex The index of the option this button represents.
123
     */
124
    public ButtonActionListener(int buttonIndex)
125
    {
126
      this.buttonIndex = buttonIndex;
127
    }
128
 
129
    /**
130
     * This method is called when one of the option buttons are pressed.
131
     *
132
     * @param e The ActionEvent.
133
     */
134
    public void actionPerformed(ActionEvent e)
135
    {
136
      Object value = new Integer(JOptionPane.CLOSED_OPTION);
137
      Object[] options = optionPane.getOptions();
138
      if (options != null)
139
        value = new Integer(buttonIndex);
140
      else
141
        {
142
          String text = ((JButton) e.getSource()).getText();
143
          if (text.equals(OK_STRING))
144
            value = new Integer(JOptionPane.OK_OPTION);
145
          if (text.equals(CANCEL_STRING))
146
            value = new Integer(JOptionPane.CANCEL_OPTION);
147
          if (text.equals(YES_STRING))
148
            value = new Integer(JOptionPane.YES_OPTION);
149
          if (text.equals(NO_STRING))
150
            value = new Integer(JOptionPane.NO_OPTION);
151
        }
152
      optionPane.setValue(value);
153
      resetInputValue();
154
 
155
      Window owner = SwingUtilities.windowForComponent(optionPane);
156
 
157
      if (owner instanceof JDialog)
158
        ((JDialog) owner).dispose();
159
 
160
      //else we probably have some kind of internal frame.
161
      JInternalFrame inf = (JInternalFrame) SwingUtilities.getAncestorOfClass(
162
          JInternalFrame.class, optionPane);
163
      if (inf != null)
164
        {
165
          try
166
            {
167
              inf.setClosed(true);
168
            }
169
          catch (PropertyVetoException pve)
170
            {
171
              // We do nothing if attempt has been vetoed.
172
            }
173
        }
174
    }
175
  }
176
 
177
  /**
178
   * This helper layout manager is responsible for the layout of the button
179
   * area. The button area is the panel that holds the buttons which
180
   * represent the options.
181
   *
182
   * @specnote Apparently this class was intended to be protected,
183
   *           but was made public by a compiler bug and is now
184
   *           public for compatibility.
185
   */
186
  public static class ButtonAreaLayout implements LayoutManager
187
  {
188
    /** Whether this layout will center the buttons. */
189
    protected boolean centersChildren = true;
190
 
191
    /** The space between the buttons. */
192
    protected int padding;
193
 
194
    /** Whether the buttons will share the same widths. */
195
    protected boolean syncAllWidths;
196
 
197
    /** The width of the widest button. */
198
    private transient int widthOfWidestButton;
199
 
200
    /** The height of the tallest button. */
201
    private transient int tallestButton;
202
 
203
    /**
204
     * Creates a new ButtonAreaLayout object with the given sync widths
205
     * property and padding.
206
     *
207
     * @param syncAllWidths Whether the buttons will share the same widths.
208
     * @param padding The padding between the buttons.
209
     */
210
    public ButtonAreaLayout(boolean syncAllWidths, int padding)
211
    {
212
      this.syncAllWidths = syncAllWidths;
213
      this.padding = padding;
214
    }
215
 
216
    /**
217
     * This method is called when a component is added to the container.
218
     *
219
     * @param string The constraints string.
220
     * @param comp The component added.
221
     */
222
    public void addLayoutComponent(String string, Component comp)
223
    {
224
      // Do nothing.
225
    }
226
 
227
    /**
228
     * This method returns whether the children will be centered.
229
     *
230
     * @return Whether the children will be centered.
231
     */
232
    public boolean getCentersChildren()
233
    {
234
      return centersChildren;
235
    }
236
 
237
    /**
238
     * This method returns the amount of space between components.
239
     *
240
     * @return The amount of space between components.
241
     */
242
    public int getPadding()
243
    {
244
      return padding;
245
    }
246
 
247
    /**
248
     * This method returns whether all components will share widths (set to
249
     * largest width).
250
     *
251
     * @return Whether all components will share widths.
252
     */
253
    public boolean getSyncAllWidths()
254
    {
255
      return syncAllWidths;
256
    }
257
 
258
    /**
259
     * This method lays out the given container.
260
     *
261
     * @param container The container to lay out.
262
     */
263
    public void layoutContainer(Container container)
264
    {
265
      Component[] buttonList = container.getComponents();
266
      int x = container.getInsets().left;
267
      if (getCentersChildren())
268
        x += (int) ((double) (container.getSize().width) / 2
269
        - (double) (buttonRowLength(container)) / 2);
270
      for (int i = 0; i < buttonList.length; i++)
271
        {
272
          Dimension dims = buttonList[i].getPreferredSize();
273
          if (syncAllWidths)
274
            {
275
              buttonList[i].setBounds(x, 0, widthOfWidestButton, dims.height);
276
              x += widthOfWidestButton + getPadding();
277
            }
278
          else
279
            {
280
              buttonList[i].setBounds(x, 0, dims.width, dims.height);
281
              x += dims.width + getPadding();
282
            }
283
        }
284
    }
285
 
286
    /**
287
     * This method returns the width of the given container taking into
288
     * consideration the padding and syncAllWidths.
289
     *
290
     * @param c The container to calculate width for.
291
     *
292
     * @return The width of the given container.
293
     */
294
    private int buttonRowLength(Container c)
295
    {
296
      Component[] buttonList = c.getComponents();
297
 
298
      int buttonLength = 0;
299
      int widest = 0;
300
      int tallest = 0;
301
 
302
      for (int i = 0; i < buttonList.length; i++)
303
        {
304
          Dimension dims = buttonList[i].getPreferredSize();
305
          buttonLength += dims.width + getPadding();
306
          widest = Math.max(widest, dims.width);
307
          tallest = Math.max(tallest, dims.height);
308
        }
309
 
310
      widthOfWidestButton = widest;
311
      tallestButton = tallest;
312
 
313
      int width;
314
      if (getSyncAllWidths())
315
        width = widest * buttonList.length
316
                + getPadding() * (buttonList.length - 1);
317
      else
318
        width = buttonLength;
319
 
320
      Insets insets = c.getInsets();
321
      width += insets.left + insets.right;
322
 
323
      return width;
324
    }
325
 
326
    /**
327
     * This method returns the minimum layout size for the given container.
328
     *
329
     * @param c The container to measure.
330
     *
331
     * @return The minimum layout size.
332
     */
333
    public Dimension minimumLayoutSize(Container c)
334
    {
335
      return preferredLayoutSize(c);
336
    }
337
 
338
    /**
339
     * This method returns the preferred size of the given container.
340
     *
341
     * @param c The container to measure.
342
     *
343
     * @return The preferred size.
344
     */
345
    public Dimension preferredLayoutSize(Container c)
346
    {
347
      int w = buttonRowLength(c);
348
 
349
      return new Dimension(w, tallestButton);
350
    }
351
 
352
    /**
353
     * This method removes the given component from the layout manager's
354
     * knowledge.
355
     *
356
     * @param c The component to remove.
357
     */
358
    public void removeLayoutComponent(Component c)
359
    {
360
      // Do nothing.
361
    }
362
 
363
    /**
364
     * This method sets whether the children will be centered.
365
     *
366
     * @param newValue Whether the children will be centered.
367
     */
368
    public void setCentersChildren(boolean newValue)
369
    {
370
      centersChildren = newValue;
371
    }
372
 
373
    /**
374
     * This method sets the amount of space between each component.
375
     *
376
     * @param newPadding The padding between components.
377
     */
378
    public void setPadding(int newPadding)
379
    {
380
      padding = newPadding;
381
    }
382
 
383
    /**
384
     * This method sets whether the widths will be synced.
385
     *
386
     * @param newValue Whether the widths will be synced.
387
     */
388
    public void setSyncAllWidths(boolean newValue)
389
    {
390
      syncAllWidths = newValue;
391
    }
392
  }
393
 
394
  /**
395
   * This helper class handles property change events from the JOptionPane.
396
   *
397
   * @specnote Apparently this class was intended to be protected,
398
   *           but was made public by a compiler bug and is now
399
   *           public for compatibility.
400
   */
401
  public class PropertyChangeHandler implements PropertyChangeListener
402
  {
403
    /**
404
     * This method is called when one of the properties of the JOptionPane
405
     * changes.
406
     *
407
     * @param e The PropertyChangeEvent.
408
     */
409
    public void propertyChange(PropertyChangeEvent e)
410
    {
411
      String property = e.getPropertyName();
412
      if (property.equals(JOptionPane.ICON_PROPERTY)
413
          || property.equals(JOptionPane.INITIAL_SELECTION_VALUE_PROPERTY)
414
          || property.equals(JOptionPane.INITIAL_VALUE_PROPERTY)
415
          || property.equals(JOptionPane.MESSAGE_PROPERTY)
416
          || property.equals(JOptionPane.MESSAGE_TYPE_PROPERTY)
417
          || property.equals(JOptionPane.OPTION_TYPE_PROPERTY)
418
          || property.equals(JOptionPane.OPTIONS_PROPERTY)
419
          || property.equals(JOptionPane.WANTS_INPUT_PROPERTY))
420
        {
421
          uninstallComponents();
422
          installComponents();
423
          optionPane.validate();
424
        }
425
    }
426
  }
427
 
428
  /**
429
   * The minimum width for JOptionPanes.
430
   */
431
  public static final int MinimumWidth = 262;
432
 
433
  /**
434
   * The minimum height for JOptionPanes.
435
   */
436
  public static final int MinimumHeight = 90;
437
 
438
  /** Whether the JOptionPane contains custom components. */
439
  protected boolean hasCustomComponents;
440
 
441
  // The initialFocusComponent seems to always be set to a button (even if
442
  // I try to set initialSelectionValue). This is different from what the
443
  // javadocs state (which should switch this reference to the input component
444
  // if one is present since that is what's going to get focus).
445
 
446
  /**
447
   * The button that will receive focus based on initialValue when no input
448
   * component is present. If an input component is present, then the input
449
   * component will receive focus instead.
450
   */
451
  protected Component initialFocusComponent;
452
 
453
  /** The component that receives input when the JOptionPane needs it. */
454
  protected JComponent inputComponent;
455
 
456
  /** The minimum dimensions of the JOptionPane. */
457
  protected Dimension minimumSize;
458
 
459
  /** The propertyChangeListener for the JOptionPane. */
460
  protected PropertyChangeListener propertyChangeListener;
461
 
462
  /** The JOptionPane this UI delegate is used for. */
463
  protected JOptionPane optionPane;
464
 
465
  /** The size of the icons. */
466
  private static final int ICON_SIZE = 36;
467
 
468
  /** The string used to describe OK buttons. */
469
  private static final String OK_STRING = "OK";
470
 
471
  /** The string used to describe Yes buttons. */
472
  private static final String YES_STRING = "Yes";
473
 
474
  /** The string used to describe No buttons. */
475
  private static final String NO_STRING = "No";
476
 
477
  /** The string used to describe Cancel buttons. */
478
  private static final String CANCEL_STRING = "Cancel";
479
 
480
  /** The container for the message area.
481
   * This is package-private to avoid an accessor method. */
482
  transient Container messageAreaContainer;
483
 
484
  /** The container for the buttons.
485
   * This is package-private to avoid an accessor method.  */
486
  transient Container buttonContainer;
487
 
488
  /**
489
   * A helper class that implements Icon. This is used temporarily until
490
   * ImageIcons are fixed.
491
   */
492
  private static class MessageIcon implements Icon
493
  {
494
    /**
495
     * This method returns the width of the icon.
496
     *
497
     * @return The width of the icon.
498
     */
499
    public int getIconWidth()
500
    {
501
      return ICON_SIZE;
502
    }
503
 
504
    /**
505
     * This method returns the height of the icon.
506
     *
507
     * @return The height of the icon.
508
     */
509
    public int getIconHeight()
510
    {
511
      return ICON_SIZE;
512
    }
513
 
514
    /**
515
     * This method paints the icon as a part of the given component using the
516
     * given graphics and the given x and y position.
517
     *
518
     * @param c The component that owns this icon.
519
     * @param g The Graphics object to paint with.
520
     * @param x The x coordinate.
521
     * @param y The y coordinate.
522
     */
523
    public void paintIcon(Component c, Graphics g, int x, int y)
524
    {
525
      // Nothing to do here.
526
    }
527
  }
528
 
529
  /** The icon displayed for ERROR_MESSAGE. */
530
  private static MessageIcon errorIcon = new MessageIcon()
531
    {
532
      public void paintIcon(Component c, Graphics g, int x, int y)
533
      {
534
        Polygon oct = new Polygon(new int[] { 0, 0, 9, 27, 36, 36, 27, 9 },
535
                                  new int[] { 9, 27, 36, 36, 27, 9, 0, 0 }, 8);
536
        g.translate(x, y);
537
 
538
        Color saved = g.getColor();
539
        g.setColor(Color.RED);
540
 
541
        g.fillPolygon(oct);
542
 
543
        g.setColor(Color.BLACK);
544
        g.drawRect(13, 16, 10, 4);
545
 
546
        g.setColor(saved);
547
        g.translate(-x, -y);
548
      }
549
    };
550
 
551
  /** The icon displayed for INFORMATION_MESSAGE. */
552
  private static MessageIcon infoIcon = new MessageIcon()
553
    {
554
      public void paintIcon(Component c, Graphics g, int x, int y)
555
      {
556
        g.translate(x, y);
557
        Color saved = g.getColor();
558
 
559
        // Should be purple.
560
        g.setColor(Color.RED);
561
 
562
        g.fillOval(0, 0, ICON_SIZE, ICON_SIZE);
563
 
564
        g.setColor(Color.BLACK);
565
        g.drawOval(16, 6, 4, 4);
566
 
567
        Polygon bottomI = new Polygon(new int[] { 15, 15, 13, 13, 23, 23, 21, 21 },
568
                                      new int[] { 12, 28, 28, 30, 30, 28, 28, 12 },
569
                                      8);
570
        g.drawPolygon(bottomI);
571
 
572
        g.setColor(saved);
573
        g.translate(-x, -y);
574
      }
575
    };
576
 
577
  /** The icon displayed for WARNING_MESSAGE. */
578
  private static MessageIcon warningIcon = new MessageIcon()
579
    {
580
      public void paintIcon(Component c, Graphics g, int x, int y)
581
      {
582
        g.translate(x, y);
583
        Color saved = g.getColor();
584
        g.setColor(Color.YELLOW);
585
 
586
        Polygon triangle = new Polygon(new int[] { 0, 18, 36 },
587
                                       new int[] { 36, 0, 36 }, 3);
588
        g.fillPolygon(triangle);
589
 
590
        g.setColor(Color.BLACK);
591
 
592
        Polygon excl = new Polygon(new int[] { 15, 16, 20, 21 },
593
                                   new int[] { 8, 26, 26, 8 }, 4);
594
        g.drawPolygon(excl);
595
        g.drawOval(16, 30, 4, 4);
596
 
597
        g.setColor(saved);
598
        g.translate(-x, -y);
599
      }
600
    };
601
 
602
  /** The icon displayed for MESSAGE_ICON. */
603
  private static MessageIcon questionIcon = new MessageIcon()
604
    {
605
      public void paintIcon(Component c, Graphics g, int x, int y)
606
      {
607
        g.translate(x, y);
608
        Color saved = g.getColor();
609
        g.setColor(Color.GREEN);
610
 
611
        g.fillRect(0, 0, ICON_SIZE, ICON_SIZE);
612
 
613
        g.setColor(Color.BLACK);
614
 
615
        g.drawOval(11, 2, 16, 16);
616
        g.drawOval(14, 5, 10, 10);
617
 
618
        g.setColor(Color.GREEN);
619
        g.fillRect(0, 10, ICON_SIZE, ICON_SIZE - 10);
620
 
621
        g.setColor(Color.BLACK);
622
 
623
        g.drawLine(11, 10, 14, 10);
624
 
625
        g.drawLine(24, 10, 17, 22);
626
        g.drawLine(27, 10, 20, 22);
627
        g.drawLine(17, 22, 20, 22);
628
 
629
        g.drawOval(17, 25, 3, 3);
630
 
631
        g.setColor(saved);
632
        g.translate(-x, -y);
633
      }
634
    };
635
 
636
  /**
637
   * Creates a new BasicOptionPaneUI object.
638
   */
639
  public BasicOptionPaneUI()
640
  {
641
    // Nothing to do here.
642
  }
643
 
644
  /**
645
   * This method is messaged to add the buttons to the given container.
646
   *
647
   * @param container The container to add components to.
648
   * @param buttons The buttons to add. (If it is an instance of component,
649
   *        the Object is added directly. If it is an instance of Icon, it is
650
   *        packed into a label and added. For all other cases, the string
651
   *        representation of the Object is retreived and packed into a
652
   *        label.)
653
   * @param initialIndex The index of the component that is the initialValue.
654
   */
655
  protected void addButtonComponents(Container container, Object[] buttons,
656
                                     int initialIndex)
657
  {
658
    if (buttons == null)
659
      return;
660
    for (int i = 0; i < buttons.length; i++)
661
      {
662
        if (buttons[i] != null)
663
          {
664
            Component toAdd;
665
            if (buttons[i] instanceof Component)
666
              toAdd = (Component) buttons[i];
667
            else
668
              {
669
                if (buttons[i] instanceof Icon)
670
                  toAdd = new JButton((Icon) buttons[i]);
671
                else
672
                  toAdd = new JButton(buttons[i].toString());
673
                hasCustomComponents = true;
674
              }
675
            if (toAdd instanceof JButton)
676
              ((JButton) toAdd).addActionListener(createButtonActionListener(i));
677
            if (i == initialIndex)
678
              initialFocusComponent = toAdd;
679
            container.add(toAdd);
680
          }
681
      }
682
    selectInitialValue(optionPane);
683
  }
684
 
685
  /**
686
   * This method adds the appropriate icon the given container.
687
   *
688
   * @param top The container to add an icon to.
689
   */
690
  protected void addIcon(Container top)
691
  {
692
    JLabel iconLabel = null;
693
    Icon icon = getIcon();
694
    if (icon != null)
695
      {
696
        iconLabel = new JLabel(icon);
697
        configureLabel(iconLabel);
698
        top.add(iconLabel, BorderLayout.WEST);
699
      }
700
  }
701
 
702
  /**
703
   * A helper method that returns an instance of GridBagConstraints to be used
704
   * for creating the message area.
705
   *
706
   * @return An instance of GridBagConstraints.
707
   */
708
  private static GridBagConstraints createConstraints()
709
  {
710
    GridBagConstraints constraints = new GridBagConstraints();
711
    constraints.gridx = GridBagConstraints.REMAINDER;
712
    constraints.gridy = GridBagConstraints.REMAINDER;
713
    constraints.gridwidth = 0;
714
    constraints.anchor = GridBagConstraints.LINE_START;
715
    constraints.fill = GridBagConstraints.NONE;
716
    constraints.insets = new Insets(0, 0, 3, 0);
717
 
718
    return constraints;
719
  }
720
 
721
  /**
722
   * This method creates the proper object (if necessary) to represent msg.
723
   * (If msg is an instance of Component, it will add it directly. If it is
724
   * an icon, then it will pack it in a label and add it. Otherwise, it gets
725
   * treated as a string. If the string is longer than maxll, a box is
726
   * created and the burstStringInto is called with the box as the container.
727
   * The box is then added to the given container. Otherwise, the string is
728
   * packed in a label and placed in the given container.) This method is
729
   * also used for adding the inputComponent to the container.
730
   *
731
   * @param container The container to add to.
732
   * @param cons The constraints when adding.
733
   * @param msg The message to add.
734
   * @param maxll The max line length.
735
   * @param internallyCreated Whether the msg is internally created.
736
   */
737
  protected void addMessageComponents(Container container,
738
                                      GridBagConstraints cons, Object msg,
739
                                      int maxll, boolean internallyCreated)
740
  {
741
    if (msg == null)
742
      return;
743
    hasCustomComponents = internallyCreated;
744
    if (msg instanceof Object[])
745
      {
746
        Object[] arr = (Object[]) msg;
747
        for (int i = 0; i < arr.length; i++)
748
          addMessageComponents(container, cons, arr[i], maxll,
749
                               internallyCreated);
750
        return;
751
      }
752
    else if (msg instanceof Component)
753
      {
754
        container.add((Component) msg, cons);
755
        cons.gridy++;
756
      }
757
    else if (msg instanceof Icon)
758
      {
759
        JLabel label = new JLabel((Icon) msg);
760
        configureLabel(label);
761
        container.add(label, cons);
762
        cons.gridy++;
763
      }
764
    else
765
      {
766
        // Undocumented behaviour.
767
        // if msg.toString().length greater than maxll
768
        // it will create a box and burst the string.
769
        // otherwise, it will just create a label and re-call
770
        // this method with the label o.O
771
        if (msg.toString().length() > maxll || msg.toString().contains("\n"))
772
          {
773
            Box tmp = new Box(BoxLayout.Y_AXIS);
774
            burstStringInto(tmp, msg.toString(), maxll);
775
            addMessageComponents(container, cons, tmp, maxll, true);
776
          }
777
        else
778
          {
779
            JLabel label = new JLabel(msg.toString());
780
            configureLabel(label);
781
            addMessageComponents(container, cons, label, maxll, true);
782
          }
783
      }
784
  }
785
 
786
  /**
787
   * This method creates instances of d (recursively if necessary based on
788
   * maxll) and adds to c.
789
   *
790
   * @param c The container to add to.
791
   * @param d The string to burst.
792
   * @param maxll The max line length.
793
   */
794
  protected void burstStringInto(Container c, String d, int maxll)
795
  {
796
    if (d == null || c == null)
797
      return;
798
 
799
    int newlineIndex = d.indexOf('\n');
800
    String line;
801
    String remainder;
802
    if (newlineIndex >= 0 && newlineIndex < maxll)
803
      {
804
        line = d.substring(0, newlineIndex);
805
        remainder = d.substring(newlineIndex + 1);
806
      }
807
    else
808
      {
809
        line = d.substring(0, maxll);
810
        remainder = d.substring(maxll);
811
      }
812
    JLabel label = new JLabel(line);
813
    configureLabel(label);
814
    c.add(label);
815
 
816
    // If there is nothing left to burst, then we can stop.
817
    if (remainder.length() == 0)
818
      return;
819
 
820
    // Recursively call ourselves to burst the remainder of the string,
821
    if (remainder.length() > maxll || remainder.contains("\n"))
822
      burstStringInto(c, remainder, maxll);
823
    else
824
      {
825
        // Add the remainder to the container and be done.
826
        JLabel l = new JLabel(remainder);
827
        configureLabel(l);
828
        c.add(l);
829
      }
830
  }
831
 
832
  /**
833
   * This method returns true if the given JOptionPane contains custom
834
   * components.
835
   *
836
   * @param op The JOptionPane to check.
837
   *
838
   * @return True if the JOptionPane contains custom components.
839
   */
840
  public boolean containsCustomComponents(JOptionPane op)
841
  {
842
    return hasCustomComponents;
843
  }
844
 
845
  /**
846
   * This method creates a button action listener for the given button index.
847
   *
848
   * @param buttonIndex The index of the button in components.
849
   *
850
   * @return A new ButtonActionListener.
851
   */
852
  protected ActionListener createButtonActionListener(int buttonIndex)
853
  {
854
    return new ButtonActionListener(buttonIndex);
855
  }
856
 
857
  /**
858
   * This method creates the button area.
859
   *
860
   * @return A new Button Area.
861
   */
862
  protected Container createButtonArea()
863
  {
864
    JPanel buttonPanel = new JPanel();
865
    Border b = UIManager.getBorder("OptionPane.buttonAreaBorder");
866
    if (b != null)
867
      buttonPanel.setBorder(b);
868
 
869
    buttonPanel.setLayout(createLayoutManager());
870
    addButtonComponents(buttonPanel, getButtons(), getInitialValueIndex());
871
 
872
    return buttonPanel;
873
  }
874
 
875
  /**
876
   * This method creates a new LayoutManager for the button area.
877
   *
878
   * @return A new LayoutManager for the button area.
879
   */
880
  protected LayoutManager createLayoutManager()
881
  {
882
    return new ButtonAreaLayout(getSizeButtonsToSameWidth(), 6);
883
  }
884
 
885
  /**
886
   * This method creates the message area.
887
   *
888
   * @return A new message area.
889
   */
890
  protected Container createMessageArea()
891
  {
892
    JPanel messageArea = new JPanel();
893
    Border messageBorder = UIManager.getBorder("OptionPane.messageAreaBorder");
894
    if (messageBorder != null)
895
      messageArea.setBorder(messageBorder);
896
 
897
    messageArea.setLayout(new BorderLayout());
898
    addIcon(messageArea);
899
 
900
    JPanel rightSide = new JPanel();
901
    rightSide.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
902
    rightSide.setLayout(new GridBagLayout());
903
    GridBagConstraints con = createConstraints();
904
 
905
    addMessageComponents(rightSide, con, getMessage(),
906
                         getMaxCharactersPerLineCount(), false);
907
 
908
    if (optionPane.getWantsInput())
909
      {
910
        Object[] selection = optionPane.getSelectionValues();
911
 
912
        if (selection == null)
913
          inputComponent = new JTextField(15);
914
        else if (selection.length < 20)
915
          inputComponent = new JComboBox(selection);
916
        else
917
          inputComponent = new JList(selection);
918
        if (inputComponent != null)
919
          {
920
            addMessageComponents(rightSide, con, inputComponent,
921
                                 getMaxCharactersPerLineCount(), false);
922
            resetSelectedValue();
923
            selectInitialValue(optionPane);
924
          }
925
      }
926
 
927
    messageArea.add(rightSide, BorderLayout.CENTER);
928
 
929
    return messageArea;
930
  }
931
 
932
  /**
933
   * This method creates a new PropertyChangeListener for listening to the
934
   * JOptionPane.
935
   *
936
   * @return A new PropertyChangeListener.
937
   */
938
  protected PropertyChangeListener createPropertyChangeListener()
939
  {
940
    return new PropertyChangeHandler();
941
  }
942
 
943
  /**
944
   * This method creates a Container that will separate the message and button
945
   * areas.
946
   *
947
   * @return A Container that will separate the message and button areas.
948
   */
949
  protected Container createSeparator()
950
  {
951
    // The reference implementation returns null here. When overriding
952
    // to return something non-null, the component gets added between
953
    // the message area and the button area. See installComponents().
954
    return null;
955
  }
956
 
957
  /**
958
   * This method creates a new BasicOptionPaneUI for the given component.
959
   *
960
   * @param x The component to create a UI for.
961
   *
962
   * @return A new BasicOptionPaneUI.
963
   */
964
  public static ComponentUI createUI(JComponent x)
965
  {
966
    return new BasicOptionPaneUI();
967
  }
968
 
969
  /**
970
   * This method returns the buttons for the JOptionPane. If no options are
971
   * set, a set of options will be created based upon the optionType.
972
   *
973
   * @return The buttons that will be added.
974
   */
975
  protected Object[] getButtons()
976
  {
977
    if (optionPane.getOptions() != null)
978
      return optionPane.getOptions();
979
    switch (optionPane.getOptionType())
980
      {
981
      case JOptionPane.YES_NO_OPTION:
982
        return new Object[] { YES_STRING, NO_STRING };
983
      case JOptionPane.YES_NO_CANCEL_OPTION:
984
        return new Object[] { YES_STRING, NO_STRING, CANCEL_STRING };
985
      case JOptionPane.OK_CANCEL_OPTION:
986
        return new Object[] { OK_STRING, CANCEL_STRING };
987
      case JOptionPane.DEFAULT_OPTION:
988
        return (optionPane.getWantsInput()) ?
989
               new Object[] { OK_STRING, CANCEL_STRING } :
990
               (optionPane.getMessageType() == JOptionPane.QUESTION_MESSAGE) ?
991
               new Object[] { YES_STRING, NO_STRING, CANCEL_STRING } :
992
               // ERROR_MESSAGE, INFORMATION_MESSAGE, WARNING_MESSAGE, PLAIN_MESSAGE
993
               new Object[] { OK_STRING };
994
      }
995
    return null;
996
  }
997
 
998
  /**
999
   * This method will return the icon the user has set or the icon that will
1000
   * be used based on message type.
1001
   *
1002
   * @return The icon to use in the JOptionPane.
1003
   */
1004
  protected Icon getIcon()
1005
  {
1006
    if (optionPane.getIcon() != null)
1007
      return optionPane.getIcon();
1008
    else
1009
      return getIconForType(optionPane.getMessageType());
1010
  }
1011
 
1012
  /**
1013
   * This method returns the icon for the given messageType.
1014
   *
1015
   * @param messageType The type of message.
1016
   *
1017
   * @return The icon for the given messageType.
1018
   */
1019
  protected Icon getIconForType(int messageType)
1020
  {
1021
    Icon tmp = null;
1022
    switch (messageType)
1023
      {
1024
      case JOptionPane.ERROR_MESSAGE:
1025
        tmp = errorIcon;
1026
        break;
1027
      case JOptionPane.INFORMATION_MESSAGE:
1028
        tmp = infoIcon;
1029
        break;
1030
      case JOptionPane.WARNING_MESSAGE:
1031
        tmp = warningIcon;
1032
        break;
1033
      case JOptionPane.QUESTION_MESSAGE:
1034
        tmp = questionIcon;
1035
        break;
1036
      }
1037
    return tmp;
1038
    // FIXME: Don't cast till the default icons are in.
1039
    // return new IconUIResource(tmp);
1040
  }
1041
 
1042
  /**
1043
   * This method returns the index of the initialValue in the options array.
1044
   *
1045
   * @return The index of the initalValue.
1046
   */
1047
  protected int getInitialValueIndex()
1048
  {
1049
    Object[] buttons = getButtons();
1050
 
1051
    if (buttons == null)
1052
      return -1;
1053
 
1054
    Object select = optionPane.getInitialValue();
1055
 
1056
    for (int i = 0; i < buttons.length; i++)
1057
      {
1058
        if (select == buttons[i])
1059
          return i;
1060
      }
1061
    return 0;
1062
  }
1063
 
1064
  /**
1065
   * This method returns the maximum number of characters that should be
1066
   * placed on a line.
1067
   *
1068
   * @return The maximum number of characteres that should be placed on a
1069
   *         line.
1070
   */
1071
  protected int getMaxCharactersPerLineCount()
1072
  {
1073
    return optionPane.getMaxCharactersPerLineCount();
1074
  }
1075
 
1076
  /**
1077
   * This method returns the maximum size.
1078
   *
1079
   * @param c The JComponent to measure.
1080
   *
1081
   * @return The maximum size.
1082
   */
1083
  public Dimension getMaximumSize(JComponent c)
1084
  {
1085
    return getPreferredSize(c);
1086
  }
1087
 
1088
  /**
1089
   * This method returns the message of the JOptionPane.
1090
   *
1091
   * @return The message.
1092
   */
1093
  protected Object getMessage()
1094
  {
1095
    return optionPane.getMessage();
1096
  }
1097
 
1098
  /**
1099
   * This method returns the minimum size of the JOptionPane.
1100
   *
1101
   * @return The minimum size.
1102
   */
1103
  public Dimension getMinimumOptionPaneSize()
1104
  {
1105
    return minimumSize;
1106
  }
1107
 
1108
  /**
1109
   * This method returns the minimum size.
1110
   *
1111
   * @param c The JComponent to measure.
1112
   *
1113
   * @return The minimum size.
1114
   */
1115
  public Dimension getMinimumSize(JComponent c)
1116
  {
1117
    return getPreferredSize(c);
1118
  }
1119
 
1120
  /**
1121
   * This method returns the preferred size of the JOptionPane. The preferred
1122
   * size is the maximum of the size desired by the layout and the minimum
1123
   * size.
1124
   *
1125
   * @param c The JComponent to measure.
1126
   *
1127
   * @return The preferred size.
1128
   */
1129
  public Dimension getPreferredSize(JComponent c)
1130
  {
1131
    Dimension d = optionPane.getLayout().preferredLayoutSize(optionPane);
1132
    Dimension d2 = getMinimumOptionPaneSize();
1133
 
1134
    int w = Math.max(d.width, d2.width);
1135
    int h = Math.max(d.height, d2.height);
1136
    return new Dimension(w, h);
1137
  }
1138
 
1139
  /**
1140
   * This method returns whether all buttons should have the same width.
1141
   *
1142
   * @return Whether all buttons should have the same width.
1143
   */
1144
  protected boolean getSizeButtonsToSameWidth()
1145
  {
1146
    return true;
1147
  }
1148
 
1149
  /**
1150
   * This method installs components for the JOptionPane.
1151
   */
1152
  protected void installComponents()
1153
  {
1154
    // First thing is the message area.
1155
    optionPane.add(createMessageArea());
1156
 
1157
    // Add separator when createSeparator() is overridden to return
1158
    // something other than null.
1159
    Container sep = createSeparator();
1160
    if (sep != null)
1161
      optionPane.add(sep);
1162
 
1163
    // Last thing is the button area.
1164
    optionPane.add(createButtonArea());
1165
  }
1166
 
1167
  /**
1168
   * This method installs defaults for the JOptionPane.
1169
   */
1170
  protected void installDefaults()
1171
  {
1172
    LookAndFeel.installColorsAndFont(optionPane, "OptionPane.background",
1173
                                     "OptionPane.foreground",
1174
                                     "OptionPane.font");
1175
    LookAndFeel.installBorder(optionPane, "OptionPane.border");
1176
    optionPane.setOpaque(true);
1177
 
1178
    minimumSize = UIManager.getDimension("OptionPane.minimumSize");
1179
 
1180
    // FIXME: Image icons don't seem to work properly right now.
1181
    // Once they do, replace the synthetic icons with these ones.
1182
 
1183
    /*
1184
    warningIcon = (IconUIResource) defaults.getIcon("OptionPane.warningIcon");
1185
    infoIcon = (IconUIResource) defaults.getIcon("OptionPane.informationIcon");
1186
    errorIcon = (IconUIResource) defaults.getIcon("OptionPane.errorIcon");
1187
    questionIcon = (IconUIResource) defaults.getIcon("OptionPane.questionIcon");
1188
    */
1189
  }
1190
 
1191
  /**
1192
   * This method installs keyboard actions for the JOptionpane.
1193
   */
1194
  protected void installKeyboardActions()
1195
  {
1196
    // Install the input map.
1197
    Object[] bindings =
1198
      (Object[]) SharedUIDefaults.get("OptionPane.windowBindings");
1199
    InputMap inputMap = LookAndFeel.makeComponentInputMap(optionPane,
1200
                                                          bindings);
1201
    SwingUtilities.replaceUIInputMap(optionPane,
1202
                                     JComponent.WHEN_IN_FOCUSED_WINDOW,
1203
                                     inputMap);
1204
 
1205
    // FIXME: The JDK uses a LazyActionMap for parentActionMap
1206
    SwingUtilities.replaceUIActionMap(optionPane, getActionMap());
1207
  }
1208
 
1209
  /**
1210
   * Fetches the action map from  the UI defaults, or create a new one
1211
   * if the action map hasn't been initialized.
1212
   *
1213
   * @return the action map
1214
   */
1215
  private ActionMap getActionMap()
1216
  {
1217
    ActionMap am = (ActionMap) UIManager.get("OptionPane.actionMap");
1218
    if (am == null)
1219
      {
1220
        am = createDefaultActions();
1221
        UIManager.getLookAndFeelDefaults().put("OptionPane.actionMap", am);
1222
      }
1223
    return am;
1224
  }
1225
 
1226
  private ActionMap createDefaultActions()
1227
  {
1228
    ActionMapUIResource am = new ActionMapUIResource();
1229
    Action action = new OptionPaneCloseAction();
1230
 
1231
    am.put("close", action);
1232
    return am;
1233
  }
1234
 
1235
  /**
1236
   * This method installs listeners for the JOptionPane.
1237
   */
1238
  protected void installListeners()
1239
  {
1240
    propertyChangeListener = createPropertyChangeListener();
1241
 
1242
    optionPane.addPropertyChangeListener(propertyChangeListener);
1243
  }
1244
 
1245
  /**
1246
   * This method installs the UI for the JOptionPane.
1247
   *
1248
   * @param c The JComponent to install the UI for.
1249
   */
1250
  public void installUI(JComponent c)
1251
  {
1252
    if (c instanceof JOptionPane)
1253
      {
1254
        optionPane = (JOptionPane) c;
1255
 
1256
        installDefaults();
1257
        installComponents();
1258
        installListeners();
1259
        installKeyboardActions();
1260
      }
1261
  }
1262
 
1263
  /**
1264
   * Changes the inputValue property in the JOptionPane based on the current
1265
   * value of the inputComponent.
1266
   */
1267
  protected void resetInputValue()
1268
  {
1269
    if (optionPane.getWantsInput() && inputComponent != null)
1270
      {
1271
        Object output = null;
1272
        if (inputComponent instanceof JTextField)
1273
          output = ((JTextField) inputComponent).getText();
1274
        else if (inputComponent instanceof JComboBox)
1275
          output = ((JComboBox) inputComponent).getSelectedItem();
1276
        else if (inputComponent instanceof JList)
1277
          output = ((JList) inputComponent).getSelectedValue();
1278
 
1279
        if (output != null)
1280
          optionPane.setInputValue(output);
1281
      }
1282
  }
1283
 
1284
  /**
1285
   * This method requests focus to the inputComponent (if one is present) and
1286
   * the initialFocusComponent otherwise.
1287
   *
1288
   * @param op The JOptionPane.
1289
   */
1290
  public void selectInitialValue(JOptionPane op)
1291
  {
1292
    if (inputComponent != null)
1293
      {
1294
        inputComponent.requestFocus();
1295
        return;
1296
      }
1297
    if (initialFocusComponent != null)
1298
      initialFocusComponent.requestFocus();
1299
  }
1300
 
1301
  /**
1302
   * This method resets the value in the inputComponent to the
1303
   * initialSelectionValue property.
1304
   * This is package-private to avoid an accessor method.
1305
   */
1306
  void resetSelectedValue()
1307
  {
1308
    if (inputComponent != null)
1309
      {
1310
        Object init = optionPane.getInitialSelectionValue();
1311
        if (init == null)
1312
          return;
1313
        if (inputComponent instanceof JTextField)
1314
          ((JTextField) inputComponent).setText((String) init);
1315
        else if (inputComponent instanceof JComboBox)
1316
          ((JComboBox) inputComponent).setSelectedItem(init);
1317
        else if (inputComponent instanceof JList)
1318
          {
1319
            //  ((JList) inputComponent).setSelectedValue(init, true);
1320
          }
1321
      }
1322
  }
1323
 
1324
  /**
1325
   * This method uninstalls all the components in the JOptionPane.
1326
   */
1327
  protected void uninstallComponents()
1328
  {
1329
    optionPane.removeAll();
1330
    buttonContainer = null;
1331
    messageAreaContainer = null;
1332
  }
1333
 
1334
  /**
1335
   * This method uninstalls the defaults for the JOptionPane.
1336
   */
1337
  protected void uninstallDefaults()
1338
  {
1339
    optionPane.setFont(null);
1340
    optionPane.setForeground(null);
1341
    optionPane.setBackground(null);
1342
 
1343
    minimumSize = null;
1344
 
1345
    // FIXME: ImageIcons don't seem to work properly
1346
 
1347
    /*
1348
    warningIcon = null;
1349
    errorIcon = null;
1350
    questionIcon = null;
1351
    infoIcon = null;
1352
    */
1353
  }
1354
 
1355
  /**
1356
   * This method uninstalls keyboard actions for the JOptionPane.
1357
   */
1358
  protected void uninstallKeyboardActions()
1359
  {
1360
    SwingUtilities.replaceUIInputMap(optionPane, JComponent.
1361
                                     WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, null);
1362
    SwingUtilities.replaceUIActionMap(optionPane, null);
1363
  }
1364
 
1365
  /**
1366
   * This method uninstalls listeners for the JOptionPane.
1367
   */
1368
  protected void uninstallListeners()
1369
  {
1370
    optionPane.removePropertyChangeListener(propertyChangeListener);
1371
    propertyChangeListener = null;
1372
  }
1373
 
1374
  /**
1375
   * This method uninstalls the UI for the given JComponent.
1376
   *
1377
   * @param c The JComponent to uninstall for.
1378
   */
1379
  public void uninstallUI(JComponent c)
1380
  {
1381
    uninstallKeyboardActions();
1382
    uninstallListeners();
1383
    uninstallComponents();
1384
    uninstallDefaults();
1385
 
1386
    optionPane = null;
1387
  }
1388
 
1389
  /**
1390
   * Applies the proper UI configuration to labels that are added to
1391
   * the OptionPane.
1392
   *
1393
   * @param l the label to configure
1394
   */
1395
  private void configureLabel(JLabel l)
1396
  {
1397
    Color c = UIManager.getColor("OptionPane.messageForeground");
1398
    if (c != null)
1399
      l.setForeground(c);
1400
    Font f = UIManager.getFont("OptionPane.messageFont");
1401
    if (f != null)
1402
      l.setFont(f);
1403
  }
1404
}

powered by: WebSVN 2.1.0

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