001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /**
018: * @author Alexander T. Simbirtsev
019: * @version $Revision$
020: */package javax.swing.plaf.basic;
021:
022: import java.awt.BorderLayout;
023: import java.awt.Color;
024: import java.awt.Component;
025: import java.awt.Container;
026: import java.awt.Dimension;
027: import java.awt.GridBagConstraints;
028: import java.awt.GridBagLayout;
029: import java.awt.Insets;
030: import java.awt.LayoutManager;
031: import java.awt.Window;
032: import java.awt.event.ActionEvent;
033: import java.awt.event.ActionListener;
034: import java.awt.event.WindowEvent;
035: import java.awt.event.WindowFocusListener;
036: import java.beans.PropertyChangeEvent;
037: import java.beans.PropertyChangeListener;
038:
039: import javax.swing.AbstractAction;
040: import javax.swing.AbstractButton;
041: import javax.swing.ActionMap;
042: import javax.swing.Box;
043: import javax.swing.BoxLayout;
044: import javax.swing.Icon;
045: import javax.swing.JButton;
046: import javax.swing.JComboBox;
047: import javax.swing.JComponent;
048: import javax.swing.JLabel;
049: import javax.swing.JOptionPane;
050: import javax.swing.JPanel;
051: import javax.swing.JRootPane;
052: import javax.swing.JTextField;
053: import javax.swing.LookAndFeel;
054: import javax.swing.SwingConstants;
055: import javax.swing.SwingUtilities;
056: import javax.swing.UIManager;
057: import javax.swing.border.Border;
058: import javax.swing.plaf.ActionMapUIResource;
059: import javax.swing.plaf.ComponentUI;
060: import javax.swing.plaf.OptionPaneUI;
061:
062: import org.apache.harmony.x.swing.StringConstants;
063: import org.apache.harmony.x.swing.Utilities;
064:
065: import org.apache.harmony.x.swing.internal.nls.Messages;
066:
067: public class BasicOptionPaneUI extends OptionPaneUI {
068:
069: public static class ButtonAreaLayout implements LayoutManager {
070: protected boolean syncAllWidths;
071: protected int padding;
072: protected boolean centersChildren = true;
073:
074: public ButtonAreaLayout(final boolean syncAllWidths,
075: final int padding) {
076: this .syncAllWidths = syncAllWidths;
077: this .padding = padding;
078: }
079:
080: public void setSyncAllWidths(final boolean syncAllWidths) {
081: this .syncAllWidths = syncAllWidths;
082: }
083:
084: public boolean getSyncAllWidths() {
085: return syncAllWidths;
086: }
087:
088: public void setPadding(final int padding) {
089: this .padding = padding;
090: }
091:
092: public int getPadding() {
093: return padding;
094: }
095:
096: public void setCentersChildren(final boolean centersChildren) {
097: this .centersChildren = centersChildren;
098: }
099:
100: public boolean getCentersChildren() {
101: return centersChildren;
102: }
103:
104: public void layoutContainer(final Container parent) {
105: Insets insets = parent.getInsets();
106: int childX = insets.left;
107: int childY = insets.top;
108:
109: int numChildren = parent.getComponentCount();
110: int maxChildWidth = getMaxChildWidth(parent);
111: int extraWidthSpace = parent.getSize().width
112: - preferredLayoutSize(parent).width;
113: int realPadding = padding;
114: if (extraWidthSpace > 0) {
115: if (centersChildren) {
116: childX += extraWidthSpace / 2;
117: } else {
118: realPadding = (numChildren > 0) ? extraWidthSpace
119: / (numChildren - 1) : 0;
120: }
121: }
122: boolean isLTR = parent.getComponentOrientation()
123: .isLeftToRight();
124: for (int i = 0; i < numChildren; i++) {
125: Component child = parent.getComponent(isLTR ? i
126: : numChildren - 1 - i);
127: Dimension prefSize = child.getPreferredSize();
128: int childWidth = syncAllWidths ? maxChildWidth
129: : prefSize.width;
130: int childHeight = prefSize.height;
131:
132: child.setLocation(childX, childY);
133: child.setSize(childWidth, childHeight);
134: childX += realPadding + childWidth;
135: }
136: }
137:
138: public Dimension minimumLayoutSize(final Container parent) {
139: return preferredLayoutSize(parent);
140: }
141:
142: private int getMaxChildWidth(final Container parent) {
143: int result = 0;
144: for (int i = 0; i < parent.getComponentCount(); i++) {
145: Dimension prefSize = parent.getComponent(i)
146: .getPreferredSize();
147: if (prefSize.width > result) {
148: result = prefSize.width;
149: }
150: }
151: return (result > 0) ? result : 10;
152: }
153:
154: private int getMaxChildHeight(final Container parent) {
155: int result = 0;
156: for (int i = 0; i < parent.getComponentCount(); i++) {
157: Dimension prefSize = parent.getComponent(i)
158: .getPreferredSize();
159: if (prefSize.height > result) {
160: result = prefSize.height;
161: }
162: }
163: return (result > 0) ? result : 10;
164: }
165:
166: public Dimension preferredLayoutSize(final Container parent) {
167: if (parent == null) {
168: return new Dimension();
169: }
170:
171: int totalWidth = 0;
172: int totalHeight = getMaxChildHeight(parent);
173: int numChildren = parent.getComponentCount();
174: if (syncAllWidths) {
175: int maxChildWidth = getMaxChildWidth(parent);
176: totalWidth = (maxChildWidth + padding) * numChildren
177: - padding;
178: } else {
179: for (int i = 0; i < numChildren; i++) {
180: Dimension prefSize = parent.getComponent(i)
181: .getPreferredSize();
182: totalWidth += (prefSize.width > 0) ? prefSize.width
183: : 10;
184: }
185: totalWidth += padding * (numChildren - 1);
186: }
187:
188: return Utilities.addInsets(new Dimension(totalWidth,
189: totalHeight), parent.getInsets());
190: }
191:
192: public void addLayoutComponent(final String name,
193: final Component c) {
194: }
195:
196: public void removeLayoutComponent(final Component c) {
197: }
198:
199: };
200:
201: public class PropertyChangeHandler implements
202: PropertyChangeListener {
203: public void propertyChange(final PropertyChangeEvent event) {
204: if (event.getSource() != BasicOptionPaneUI.this .optionPane) {
205: return;
206: }
207:
208: final JOptionPane pane = BasicOptionPaneUI.this .optionPane;
209: final String propName = event.getPropertyName();
210:
211: if (JOptionPane.ICON_PROPERTY.equals(propName)
212: || JOptionPane.MESSAGE_PROPERTY.equals(propName)
213: || JOptionPane.OPTIONS_PROPERTY.equals(propName)
214: || JOptionPane.INITIAL_VALUE_PROPERTY
215: .equals(propName)) {
216:
217: uninstallComponents();
218: installComponents();
219: pane.revalidate();
220: } else if (JOptionPane.SELECTION_VALUES_PROPERTY
221: .equals(propName)
222: || JOptionPane.WANTS_INPUT_PROPERTY
223: .equals(propName)) {
224:
225: initValues(pane);
226: pane.revalidate();
227: } else if (JOptionPane.INITIAL_SELECTION_VALUE_PROPERTY
228: .equals(propName)) {
229: setInputValue(event.getNewValue());
230: } else if (StringConstants.ANCESTOR_PROPERTY_NAME
231: .equals(propName)
232: && (event.getOldValue() == null)) {
233:
234: selectInitialValue(pane);
235: String soundEventName = getSoundEffectName();
236: ((BasicLookAndFeel) UIManager.getLookAndFeel())
237: .fireSoundAction(pane, PROPERTY_PREFIX
238: + soundEventName);
239: }
240: }
241:
242: private void initValues(final JOptionPane pane) {
243: uninstallComponents();
244: if (pane.getWantsInput()) {
245: final Object[] selectionValues = pane
246: .getSelectionValues();
247: final Object initialValue = pane
248: .getInitialSelectionValue();
249: inputComponent = (selectionValues == null) ? createTextField(
250: pane, initialValue)
251: : createComboBox(selectionValues, initialValue);
252: } else {
253: inputComponent = null;
254: }
255: installComponents();
256: }
257:
258: private JComponent createComboBox(
259: final Object[] selectionValues,
260: final Object initialValue) {
261: JComboBox comboBox = new JComboBox(selectionValues);
262: comboBox.setSelectedItem(initialValue);
263: return comboBox;
264: }
265:
266: private JComponent createTextField(final JOptionPane pane,
267: Object initialValue) {
268: final JTextField result = new JTextField();
269: result.addActionListener(new ActionListener() {
270: public void actionPerformed(final ActionEvent e) {
271: pane.setInputValue(result.getText());
272: if (initialFocusComponent instanceof AbstractButton) {
273: ((AbstractButton) initialFocusComponent)
274: .doClick();
275: }
276: }
277: });
278: setTextFieldValue(result, initialValue);
279: return result;
280: }
281: }
282:
283: public class ButtonActionListener implements ActionListener {
284: protected int buttonIndex;
285:
286: public ButtonActionListener(final int buttonIndex) {
287: this .buttonIndex = buttonIndex;
288: }
289:
290: public void actionPerformed(final ActionEvent e) {
291: JOptionPane pane = BasicOptionPaneUI.this .optionPane;
292: Object[] options = pane.getOptions();
293: if (!Utilities.isEmptyArray(options)) {
294: pane.setValue(options[buttonIndex]);
295: } else {
296: pane.setValue(new Integer(buttonIndex));
297: }
298:
299: Object[] buttons = getButtons();
300: assert !Utilities.isEmptyArray(buttons)
301: && buttonIndex < buttons.length;
302: if (cancelButton.text != null
303: && !cancelButton.text.equals(buttons[buttonIndex])) {
304: ((BasicOptionPaneUI) pane.getUI()).resetInputValue();
305: }
306: CloseAction.doClose(pane);
307: }
308: };
309:
310: private static class ButtonInfo {
311: public int mnemonic;
312: public String text;
313:
314: public String toString() {
315: return text;
316: }
317: }
318:
319: private static class CloseAction extends AbstractAction {
320: public static void doClose(final JOptionPane pane) {
321: if (JOptionPane.UNINITIALIZED_VALUE.equals(pane
322: .getInputValue())) {
323: pane.setInputValue(null);
324: }
325: pane.putClientProperty("closeOwner", Boolean.TRUE);
326: }
327:
328: public void actionPerformed(final ActionEvent e) {
329: doClose((JOptionPane) e.getSource());
330: }
331: };
332:
333: private static class WindowFocusGainedListener implements
334: WindowFocusListener {
335: private final JComponent focusTarget;
336:
337: public WindowFocusGainedListener(final JComponent focusTarget) {
338: this .focusTarget = focusTarget;
339: }
340:
341: public void windowGainedFocus(final WindowEvent e) {
342: focusTarget.requestFocusInWindow();
343: e.getWindow().removeWindowFocusListener(this );
344: }
345:
346: public void windowLostFocus(final WindowEvent e) {
347: }
348: }
349:
350: public static final int MinimumWidth = 262;
351: public static final int MinimumHeight = 90;
352:
353: protected JOptionPane optionPane;
354: protected Dimension minimumSize;
355: protected JComponent inputComponent;
356: protected Component initialFocusComponent;
357: protected boolean hasCustomComponents;
358: protected PropertyChangeListener propertyChangeListener;
359:
360: private static final int NUM_DEFAULT_MESSAGES = 4;
361:
362: private static final int DEFAULT_BUTTON_PADDING = 6;
363: private static final String PROPERTY_PREFIX = "OptionPane.";
364: private Icon[] defaultIcons;
365: private static final CloseAction closeAction = new CloseAction();
366:
367: private String inputTitleText;
368: private String messageTitleText;
369: private String defaultTitleText;
370:
371: private final ButtonInfo yesButton = new ButtonInfo();
372: private final ButtonInfo noButton = new ButtonInfo();
373: private final ButtonInfo okButton = new ButtonInfo();
374: private final ButtonInfo cancelButton = new ButtonInfo();
375:
376: private int buttonClickThreshhold;
377:
378: private Border messageAreaBorder;
379: private Color messageForeground;
380: private Border buttonAreaBorder;
381:
382: public static ComponentUI createUI(final JComponent c) {
383: return new BasicOptionPaneUI();
384: }
385:
386: public void installUI(final JComponent c) {
387: optionPane = (JOptionPane) c;
388: installDefaults();
389: optionPane.setLayout(createLayoutManager());
390: installComponents();
391: installListeners();
392: installKeyboardActions();
393: }
394:
395: public void uninstallUI(final JComponent c) {
396: uninstallKeyboardActions();
397: uninstallListeners();
398: uninstallComponents();
399: uninstallDefaults();
400: optionPane = null;
401: }
402:
403: public Dimension getMinimumOptionPaneSize() {
404: return (minimumSize != null) ? minimumSize : new Dimension(
405: MinimumWidth, MinimumHeight);
406: }
407:
408: public Dimension getPreferredSize(final JComponent c) {
409: if (c == null) {
410: return null;
411: }
412:
413: Dimension layoutSize = (c.getLayout() != null) ? c.getLayout()
414: .preferredLayoutSize(c) : null;
415: Dimension minimumSize = getMinimumOptionPaneSize();
416: if (layoutSize == null) {
417: return minimumSize;
418: }
419: return new Dimension(Math.max(layoutSize.width,
420: minimumSize.width), Math.max(layoutSize.height,
421: minimumSize.height));
422: }
423:
424: public void selectInitialValue(final JOptionPane op) {
425: JRootPane rootPane = op.getRootPane();
426: if (rootPane != null
427: && initialFocusComponent instanceof JButton) {
428: rootPane.setDefaultButton((JButton) initialFocusComponent);
429: }
430:
431: JComponent focusOwner = (inputComponent != null) ? inputComponent
432: : ((initialFocusComponent instanceof JComponent) ? (JComponent) initialFocusComponent
433: : null);
434: if (focusOwner != null) {
435: Window w = SwingUtilities.getWindowAncestor(focusOwner);
436: if (w != null) {
437: w.addWindowFocusListener(new WindowFocusGainedListener(
438: focusOwner));
439: }
440: }
441: }
442:
443: public boolean containsCustomComponents(final JOptionPane op) {
444: return hasCustomComponents;
445: }
446:
447: protected void installDefaults() {
448: LookAndFeel.installColorsAndFont(optionPane, PROPERTY_PREFIX
449: + "background", PROPERTY_PREFIX + "foreground",
450: PROPERTY_PREFIX + "font");
451: LookAndFeel.installBorder(optionPane, PROPERTY_PREFIX
452: + "border");
453: minimumSize = UIManager.getDimension(PROPERTY_PREFIX
454: + "minimumSize");
455:
456: defaultTitleText = UIManager.getString(PROPERTY_PREFIX
457: + "titleText");
458: messageTitleText = UIManager.getString(PROPERTY_PREFIX
459: + "messageDialogTitle");
460: inputTitleText = UIManager.getString(PROPERTY_PREFIX
461: + "inputDialogTitle");
462:
463: okButton.text = UIManager.getString(PROPERTY_PREFIX
464: + "okButtonText");
465: yesButton.text = UIManager.getString(PROPERTY_PREFIX
466: + "yesButtonText");
467: noButton.text = UIManager.getString(PROPERTY_PREFIX
468: + "noButtonText");
469: cancelButton.text = UIManager.getString(PROPERTY_PREFIX
470: + "cancelButtonText");
471:
472: okButton.mnemonic = UIManager.getInt(PROPERTY_PREFIX
473: + "okButtonMnemonic");
474: yesButton.mnemonic = UIManager.getInt(PROPERTY_PREFIX
475: + "yesButtonMnemonic");
476: noButton.mnemonic = UIManager.getInt(PROPERTY_PREFIX
477: + "noButtonMnemonic");
478: cancelButton.mnemonic = UIManager.getInt(PROPERTY_PREFIX
479: + "cancelButtonMnemonic");
480:
481: buttonClickThreshhold = UIManager.getInt(PROPERTY_PREFIX
482: + "buttonClickThreshhold");
483:
484: messageAreaBorder = UIManager.getBorder(PROPERTY_PREFIX
485: + "messageAreaBorder");
486: messageForeground = UIManager.getColor(PROPERTY_PREFIX
487: + "messageForeground");
488: buttonAreaBorder = UIManager.getBorder(PROPERTY_PREFIX
489: + "buttonAreaBorder");
490: }
491:
492: protected void uninstallDefaults() {
493: LookAndFeel.uninstallBorder(optionPane);
494: }
495:
496: protected void installComponents() {
497: installTitle();
498: optionPane.add(createMessageArea());
499: Container separator = createSeparator();
500: if (separator != null) {
501: optionPane.add(separator);
502: }
503: optionPane.add(createButtonArea());
504: optionPane.setMinimumSize(getMinimumOptionPaneSize());
505: if (!optionPane.getWantsInput()) {
506: inputComponent = null;
507: }
508: if (!optionPane.getComponentOrientation().isLeftToRight()) {
509: optionPane.applyComponentOrientation(optionPane
510: .getComponentOrientation());
511: }
512: }
513:
514: protected void uninstallComponents() {
515: optionPane.removeAll();
516: inputComponent = null;
517: }
518:
519: protected LayoutManager createLayoutManager() {
520: return new BoxLayout(optionPane, BoxLayout.Y_AXIS);
521: }
522:
523: protected void installListeners() {
524: propertyChangeListener = createPropertyChangeListener();
525: optionPane.addPropertyChangeListener(propertyChangeListener);
526: }
527:
528: protected void uninstallListeners() {
529: if (optionPane != null) {
530: optionPane
531: .removePropertyChangeListener(propertyChangeListener);
532: }
533: propertyChangeListener = null;
534: }
535:
536: protected PropertyChangeListener createPropertyChangeListener() {
537: return new PropertyChangeHandler();
538: }
539:
540: protected void installKeyboardActions() {
541: SwingUtilities.replaceUIInputMap(optionPane,
542: JComponent.WHEN_IN_FOCUSED_WINDOW, LookAndFeel
543: .makeComponentInputMap(optionPane,
544: (Object[]) UIManager
545: .get(PROPERTY_PREFIX
546: + "windowBindings")));
547:
548: ActionMap actionMap = new ActionMapUIResource();
549: actionMap.put(StringConstants.CLOSE_ACTION, closeAction);
550: actionMap.setParent(((BasicLookAndFeel) UIManager
551: .getLookAndFeel()).getAudioActionMap());
552: SwingUtilities.replaceUIActionMap(optionPane, actionMap);
553: }
554:
555: protected void uninstallKeyboardActions() {
556: SwingUtilities.replaceUIInputMap(optionPane,
557: JComponent.WHEN_IN_FOCUSED_WINDOW, null);
558: SwingUtilities.replaceUIActionMap(optionPane, null);
559: }
560:
561: protected Container createMessageArea() {
562: Object message = getMessage();
563: JComponent messageArea = new JPanel(new BorderLayout());
564: messageArea.setBorder(messageAreaBorder);
565: JPanel messageAndGapPanel = new JPanel();
566: messageAndGapPanel.setLayout(new BoxLayout(messageAndGapPanel,
567: BoxLayout.X_AXIS));
568: messageArea.add(messageAndGapPanel, BorderLayout.CENTER);
569:
570: if (getIcon() != null) {
571: JPanel gapPanel = new JPanel();
572: gapPanel.setPreferredSize(new Dimension(15, 1));
573: messageAndGapPanel.add(gapPanel);
574: }
575: JPanel plainTextPanel = new JPanel(new GridBagLayout());
576: messageAndGapPanel.add(plainTextPanel);
577:
578: hasCustomComponents |= (message instanceof Component);
579: GridBagConstraints constrains = createConstrains();
580: addMessageComponents(plainTextPanel, constrains, message,
581: getMaxCharactersPerLineCount(), true);
582:
583: if (inputComponent != null) {
584: addMessageComponents(plainTextPanel, constrains,
585: inputComponent, getMaxCharactersPerLineCount(),
586: true);
587: }
588:
589: addIcon(messageArea);
590:
591: return messageArea;
592: }
593:
594: protected void addMessageComponents(final Container container,
595: final GridBagConstraints cons, final Object msg,
596: final int maxll, final boolean internallyCreated) {
597:
598: if (msg == null) {
599: return;
600: }
601:
602: if (msg instanceof Component) {
603: addToContainer(container, cons, (Component) msg);
604: } else if (msg instanceof Icon) {
605: addMessageComponents(container, cons,
606: new JLabel((Icon) msg), maxll, true);
607: } else if (msg instanceof Object[]) {
608: final Object[] array = (Object[]) msg;
609: for (int i = 0; i < array.length; i++) {
610: addMessageComponents(container, cons, array[i], maxll,
611: internallyCreated);
612: }
613: } else {
614: addMessageComponents(container, cons, msg.toString(),
615: maxll, internallyCreated);
616: }
617: }
618:
619: protected Object getMessage() {
620: return (optionPane != null) ? optionPane.getMessage() : null;
621: }
622:
623: protected void addIcon(final Container top) {
624: final JLabel label = new JLabel(getIcon());
625: label.setVerticalAlignment(SwingConstants.TOP);
626: top.add(label, BorderLayout.LINE_START);
627: }
628:
629: protected Icon getIcon() {
630: if (optionPane == null) {
631: return null;
632: }
633:
634: Icon icon = optionPane.getIcon();
635: return (icon != null) ? icon : getIconForType(optionPane
636: .getMessageType());
637: }
638:
639: protected Icon getIconForType(final int messageType) {
640: if (optionPane == null) {
641: throw new NullPointerException(Messages.getString(
642: "swing.03", "optionPane")); //$NON-NLS-1$ //$NON-NLS-2$
643: }
644:
645: if (defaultIcons == null) {
646: installIcons();
647: }
648:
649: if (messageType < 0 || NUM_DEFAULT_MESSAGES <= messageType) {
650: return null;
651: }
652:
653: return defaultIcons[messageType];
654: }
655:
656: protected int getMaxCharactersPerLineCount() {
657: return optionPane.getMaxCharactersPerLineCount();
658: }
659:
660: protected void burstStringInto(final Container c, final String d,
661: final int maxll) {
662: String str = d;
663: int firstSpace;
664: GridBagConstraints constrains = createConstrains();
665: while (str.length() > maxll
666: && (firstSpace = findSpaceToCutAt(str, maxll)) > 0) {
667: addLabel(c, str.substring(0, firstSpace), constrains);
668: str = str.substring(firstSpace);
669: str = trimFristSpace(str);
670: }
671: if (str.length() > 0) {
672: addLabel(c, str, constrains);
673: }
674: }
675:
676: protected Container createSeparator() {
677: return null;
678: }
679:
680: protected Container createButtonArea() {
681: JPanel buttonArea = new JPanel();
682: buttonArea.setLayout(new ButtonAreaLayout(
683: getSizeButtonsToSameWidth(), DEFAULT_BUTTON_PADDING));
684: buttonArea.setBorder(buttonAreaBorder);
685: addButtonComponents(buttonArea, getButtons(),
686: getInitialValueIndex());
687:
688: return buttonArea;
689: }
690:
691: protected void addButtonComponents(final Container container,
692: final Object[] buttons, final int initialIndex) {
693:
694: if (Utilities.isEmptyArray(buttons)) {
695: return;
696: }
697:
698: int horMargin = getHorizontalButtonMarginSize(buttons.length);
699: for (int iButton = 0; iButton < buttons.length; iButton++) {
700: Object curButton = buttons[iButton];
701: if (curButton instanceof Component) {
702: hasCustomComponents = true;
703: } else {
704: curButton = createButton(curButton, iButton, horMargin,
705: buttonClickThreshhold);
706: }
707: container.add((Component) curButton);
708: if (iButton == initialIndex) {
709: initialFocusComponent = (Component) curButton;
710: }
711: }
712: }
713:
714: protected ActionListener createButtonActionListener(
715: final int buttonIndex) {
716: return new ButtonActionListener(buttonIndex);
717: }
718:
719: protected Object[] getButtons() {
720: if (optionPane == null) {
721: return null;
722: }
723:
724: Object[] result = optionPane.getOptions();
725: if (!Utilities.isEmptyArray(result)) {
726: return result;
727: }
728: switch (optionPane.getOptionType()) {
729: case JOptionPane.DEFAULT_OPTION:
730: result = new Object[] { okButton };
731: break;
732: case JOptionPane.YES_NO_OPTION:
733: result = new Object[] { yesButton, noButton };
734: break;
735: case JOptionPane.YES_NO_CANCEL_OPTION:
736: result = new Object[] { yesButton, noButton, cancelButton };
737: break;
738: case JOptionPane.OK_CANCEL_OPTION:
739: result = new Object[] { okButton, cancelButton };
740: break;
741: default:
742: assert false : "illegal option";
743: }
744:
745: return result;
746: }
747:
748: protected boolean getSizeButtonsToSameWidth() {
749: return true;
750: }
751:
752: protected int getInitialValueIndex() {
753: if (optionPane == null) {
754: return -1;
755: }
756:
757: Object[] options = optionPane.getOptions();
758: if (Utilities.isEmptyArray(options)) {
759: return 0;
760: }
761:
762: Object value = optionPane.getInitialValue();
763: if (value == null) {
764: return -1;
765: }
766:
767: for (int i = options.length - 1; i >= 0; i--) {
768: if (value.equals(options[i])) {
769: return i;
770: }
771: }
772:
773: return -1;
774: }
775:
776: protected void resetInputValue() {
777: optionPane.setInputValue(getInputValue());
778: }
779:
780: private Object getInputValue() {
781: if (inputComponent == null) {
782: return null;
783: }
784:
785: if (inputComponent instanceof JTextField) {
786: return ((JTextField) inputComponent).getText();
787: } else if (inputComponent instanceof JComboBox) {
788: return ((JComboBox) inputComponent).getSelectedItem();
789: }
790:
791: return null;
792: }
793:
794: private void setInputValue(final Object value) {
795: if (inputComponent == null) {
796: return;
797: }
798:
799: if (inputComponent instanceof JTextField) {
800: setTextFieldValue((JTextField) inputComponent, value);
801: } else if (inputComponent instanceof JComboBox) {
802: ((JComboBox) inputComponent).setSelectedItem(value);
803: }
804: }
805:
806: private void setTextFieldValue(final JTextField textField,
807: final Object value) {
808: String text = (value != null) ? value.toString() : null;
809: textField.setText(text);
810: if (text != null) {
811: textField.setSelectionStart(0);
812: textField.setSelectionEnd(text.length());
813: }
814: }
815:
816: private void installTitle() {
817: String title = null;
818: switch (optionPane.getOptionType()) {
819: case JOptionPane.DEFAULT_OPTION:
820: title = messageTitleText;
821: break;
822: case JOptionPane.YES_NO_OPTION:
823: title = defaultTitleText;
824: break;
825: case JOptionPane.YES_NO_CANCEL_OPTION:
826: title = defaultTitleText;
827: break;
828: case JOptionPane.OK_CANCEL_OPTION:
829: title = inputTitleText;
830: break;
831: default:
832: assert false : "illegal option";
833: }
834: optionPane.putClientProperty("defaultTitle", title);
835: }
836:
837: private String getSoundEffectName() {
838: switch (optionPane.getMessageType()) {
839: case JOptionPane.ERROR_MESSAGE:
840: return "errorSound";
841: case JOptionPane.INFORMATION_MESSAGE:
842: return "informationSound";
843: case JOptionPane.WARNING_MESSAGE:
844: return "warningSound";
845: case JOptionPane.QUESTION_MESSAGE:
846: return "questionSound";
847: }
848:
849: return null;
850: }
851:
852: private void installIcons() {
853: if (defaultIcons == null) {
854: defaultIcons = new Icon[NUM_DEFAULT_MESSAGES];
855: }
856:
857: defaultIcons[JOptionPane.ERROR_MESSAGE] = UIManager
858: .getIcon(PROPERTY_PREFIX + "errorIcon");
859: defaultIcons[JOptionPane.INFORMATION_MESSAGE] = UIManager
860: .getIcon(PROPERTY_PREFIX + "informationIcon");
861: defaultIcons[JOptionPane.QUESTION_MESSAGE] = UIManager
862: .getIcon(PROPERTY_PREFIX + "questionIcon");
863: defaultIcons[JOptionPane.WARNING_MESSAGE] = UIManager
864: .getIcon(PROPERTY_PREFIX + "warningIcon");
865: }
866:
867: private void addLabel(final Container c, final String str,
868: final GridBagConstraints cons) {
869: final JLabel label = new JLabel(str);
870: label.setForeground(messageForeground);
871: label.setAlignmentX(0);
872: addToContainer(c, cons, label);
873: }
874:
875: private String trimFristSpace(final String str) {
876: return (str.indexOf(' ') == 0) ? str.substring(1) : str;
877: }
878:
879: private int findSpaceToCutAt(final String str, final int maxCharNum) {
880: int prevIndex = str.indexOf(' ');
881: int newIndex = prevIndex;
882: while (newIndex <= maxCharNum && newIndex < str.length()
883: && newIndex != -1) {
884: prevIndex = newIndex;
885: newIndex = str.indexOf(' ', prevIndex + 1);
886: }
887:
888: return prevIndex;
889: }
890:
891: private int getHorizontalButtonMarginSize(final int numButtons) {
892: return (numButtons <= 2) ? 8 : ((numButtons == 3) ? 4 : 14);
893: }
894:
895: private JButton createButton(final Object curButton,
896: final int iButton, final int horMargin, final int threshold) {
897: JButton result;
898: int mnemonic = 0;
899: if (curButton instanceof Icon) {
900: result = new JButton((Icon) curButton);
901: } else if (curButton instanceof ButtonInfo) {
902: result = new JButton(((ButtonInfo) curButton).text);
903: mnemonic = ((ButtonInfo) curButton).mnemonic;
904: } else {
905: result = new JButton(curButton.toString());
906: }
907: result.setMultiClickThreshhold(threshold);
908: result.addActionListener(createButtonActionListener(iButton));
909: result.setMnemonic(mnemonic);
910: result.setMargin(new Insets(2, horMargin, 2, horMargin));
911: return result;
912: }
913:
914: private void addMessageComponents(final Container container,
915: final GridBagConstraints cons, final String str,
916: final int maxll, final boolean internallyCreated) {
917: if (Utilities.isEmptyString(str)) {
918: return;
919: }
920:
921: final int strLength = str.length();
922: final int strDelimIndex = str.indexOf("\n");
923: if (strDelimIndex < 0) {
924: if (strLength <= maxll) {
925: addLabel(container, str, cons);
926: } else {
927: final Box box = new Box(BoxLayout.Y_AXIS);
928: box.setAlignmentX(0);
929: burstStringInto(box, str, maxll);
930: addMessageComponents(container, cons, box, maxll, true);
931: }
932: } else {
933: final boolean leadingDelimiter = strDelimIndex == 0;
934: final Object leadingMsg = leadingDelimiter ? (Object) createStringDelimiter()
935: : str.substring(0, strDelimIndex);
936: addMessageComponents(container, cons, leadingMsg, maxll,
937: leadingDelimiter);
938: addMessageComponents(container, cons, str.substring(
939: strDelimIndex + 1, strLength), maxll,
940: internallyCreated);
941: }
942: }
943:
944: private void addToContainer(final Container container,
945: final GridBagConstraints constrains, final Component child) {
946:
947: constrains.gridy++;
948: container.add(child, constrains);
949: }
950:
951: private Component createStringDelimiter() {
952: return new Component() {
953: public Dimension getPreferredSize() {
954: return new Dimension(1, Utilities.getFontMetrics(
955: optionPane).getHeight());
956: }
957: };
958: }
959:
960: private GridBagConstraints createConstrains() {
961: return new GridBagConstraints(0, 0, GridBagConstraints.NONE,
962: GridBagConstraints.BOTH, 1.0, 0,
963: GridBagConstraints.LINE_START,
964: GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0),
965: 0, 0);
966:
967: }
968: }
|