001: /*
002: * @(#)JideButton.java
003: *
004: * Copyright 2002-2003 JIDE Software Inc. All rights reserved.
005: */
006: package com.jidesoft.swing;
007:
008: import com.jidesoft.plaf.LookAndFeelFactory;
009: import com.jidesoft.plaf.UIDefaultsLookup;
010: import com.jidesoft.plaf.basic.ThemePainter;
011:
012: import javax.swing.*;
013: import java.awt.*;
014:
015: /**
016: * JideButton is a replacement for JButton when it is used on toolbar
017: * (or command bar in the case of JIDE Action Framework).
018: */
019: public class JideButton extends JButton implements Alignable,
020: ButtonStyle, ComponentStateSupport {
021:
022: private static final String uiClassID = "JideButtonUI";
023:
024: /**
025: * Bound property name for orientation property.
026: *
027: * @deprecated use PROPERTY_ORIENTATION instead. The string values of both constants are the same.
028: */
029: public static final String PROPERTY_ORIENTATION_CHANGED = "orientation";
030:
031: /**
032: * Bound property name for always show hyperlink property.
033: */
034: public static final String PROPERTY_ALWAYS_SHOW_HYPERLINK = "alwaysShowHyperlink";
035:
036: private boolean _alwaysShowHyperlink = false;
037:
038: private int _buttonStyle = TOOLBAR_STYLE;
039:
040: /**
041: * By default, if a JideButton is added to a popup menu, clicking on the button will
042: * dismiss the popup menu. However if you change the default behavior, you can use
043: * this client property and set it to Boolean.FALSE.
044: */
045: public static final String CLIENT_PROPERTY_HIDE_POPUPMENU = "JideButton.hidePopupMenu";
046:
047: /**
048: * Creates a button with no set text or icon.
049: */
050: public JideButton() {
051: this (null, null);
052: }
053:
054: /**
055: * Creates a button with an icon.
056: *
057: * @param icon the Icon image to display on the button
058: */
059: public JideButton(Icon icon) {
060: this (null, icon);
061: }
062:
063: /**
064: * Creates a button with text.
065: *
066: * @param text the text of the button
067: */
068: public JideButton(String text) {
069: this (text, null);
070: }
071:
072: /**
073: * Creates a button where properties are taken from the
074: * <code>Action</code> supplied.
075: *
076: * @param a the <code>Action</code> used to specify the new button
077: * @since 1.3
078: */
079: public JideButton(Action a) {
080: this ();
081: setAction(a);
082: }
083:
084: /**
085: * Creates a button with initial text and an icon.
086: *
087: * @param text the text of the button
088: * @param icon the Icon image to display on the button
089: */
090: public JideButton(String text, Icon icon) {
091: // Create the model
092: setModel(new DefaultButtonModel());
093: // initialize
094: init(text, icon);
095: setRolloverEnabled(true);
096: setFocusable(true);
097: setRequestFocusEnabled(false);
098: }
099:
100: /**
101: * Resets the UI property to a value from the current look and
102: * feel.
103: *
104: * @see JComponent#updateUI
105: */
106: @Override
107: public void updateUI() {
108: if (UIDefaultsLookup.get(uiClassID) == null) {
109: LookAndFeelFactory.installJideExtension();
110: }
111: setUI(UIManager.getUI(this ));
112: }
113:
114: /**
115: * Returns a string that specifies the name of the L&F class
116: * that renders this component.
117: *
118: * @return the string "ButtonUI"
119: * @see JComponent#getUIClassID
120: * @see UIDefaults#getUI
121: */
122: @Override
123: public String getUIClassID() {
124: return uiClassID;
125: }
126:
127: private int _orientation;
128:
129: /**
130: * The button orientation.
131: *
132: * @return the orientation.
133: */
134: public int getOrientation() {
135: return _orientation;
136: }
137:
138: public void setOrientation(int orientation) {
139: int old = _orientation;
140: if (old != orientation) {
141: _orientation = orientation;
142: firePropertyChange(PROPERTY_ORIENTATION, old, orientation);
143: }
144: }
145:
146: /**
147: * return ture if it supports vertical orientation.
148: *
149: * @return ture if it supports vertical orientation
150: */
151: public boolean supportVerticalOrientation() {
152: return true;
153: }
154:
155: /**
156: * return ture if it supports horizontal orientation.
157: *
158: * @return ture if it supports horizontal orientation
159: */
160: public boolean supportHorizontalOrientation() {
161: return true;
162: }
163:
164: /**
165: * Gets the button style.
166: *
167: * @return the button style.
168: */
169: public int getButtonStyle() {
170: return _buttonStyle;
171: }
172:
173: /**
174: * Sets the button style.
175: *
176: * @param buttonStyle one of the following values: {@link #TOOLBAR_STYLE} (default),
177: * {@link #TOOLBOX_STYLE}, {@link #FLAT_STYLE} and {@link #HYPERLINK_STYLE}.
178: */
179: public void setButtonStyle(int buttonStyle) {
180: if (buttonStyle < 0 || buttonStyle > HYPERLINK_STYLE) {
181: throw new IllegalArgumentException(
182: "Only TOOLBAR_STYLE, TOOLBOX_STYLE, FLAT_STYLE and HYPERLINK_STYLE are supported");
183: }
184: if (buttonStyle == _buttonStyle)
185: return;
186:
187: int oldStyle = _buttonStyle;
188: _buttonStyle = buttonStyle;
189:
190: firePropertyChange(BUTTON_STYLE_PROPERTY, oldStyle,
191: _buttonStyle);
192: }
193:
194: /**
195: * Checks the alwaysShowHyperlink property value.
196: *
197: * @return true if the hyperlink is always visible. False if the hyperlink will be visible only when mouse rolls over.
198: */
199: public boolean isAlwaysShowHyperlink() {
200: return _alwaysShowHyperlink;
201: }
202:
203: /**
204: * Sets the property if hyperlink (the underline) should be visible all the time. By default the hyperlink is visible
205: * when mouse is over the button. If set to true, the hyperlink will always be visible.
206: * <p/>
207: * Please notes, this is an option only available when button style is set to HYPERLINK_STYLE.
208: *
209: * @param alwaysShowHyperlink a boolean value. True means the button will always show hyperlink. False means it will show hyperlink only
210: * when mouse is over the button.
211: */
212: public void setAlwaysShowHyperlink(boolean alwaysShowHyperlink) {
213: if (_alwaysShowHyperlink != alwaysShowHyperlink) {
214: boolean old = _alwaysShowHyperlink;
215: _alwaysShowHyperlink = alwaysShowHyperlink;
216: firePropertyChange(PROPERTY_ALWAYS_SHOW_HYPERLINK, old,
217: alwaysShowHyperlink);
218: }
219: }
220:
221: @Override
222: public Cursor getCursor() {
223: if (getButtonStyle() == HYPERLINK_STYLE
224: && isRolloverEnabled()
225: && getModel().isRollover()
226: && ((getText() != null && getText().length() > 0) || getIcon() != null)) {
227: return Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
228: } else {
229: return super .getCursor();
230: }
231: }
232:
233: private Color _rolloverBackground;
234: private Color _selectedBackground;
235: private Color _pressedBackground;
236: private Color _rolloverForeground;
237: private Color _selectedForeground;
238: private Color _pressedForeground;
239:
240: private Color getRolloverBackground() {
241: return _rolloverBackground;
242: }
243:
244: private void setRolloverBackground(Color rolloverBackground) {
245: _rolloverBackground = rolloverBackground;
246: }
247:
248: private Color getSelectedBackground() {
249: return _selectedBackground;
250: }
251:
252: private void setSelectedBackground(Color selectedBackground) {
253: _selectedBackground = selectedBackground;
254: }
255:
256: private Color getPressedBackground() {
257: return _pressedBackground;
258: }
259:
260: private void setPressedBackground(Color pressedBackground) {
261: _pressedBackground = pressedBackground;
262: }
263:
264: private Color getRolloverForeground() {
265: return _rolloverForeground;
266: }
267:
268: private void setRolloverForeground(Color rolloverForeground) {
269: _rolloverForeground = rolloverForeground;
270: }
271:
272: private Color getSelectedForeground() {
273: return _selectedForeground;
274: }
275:
276: private void setSelectedForeground(Color selectedForeground) {
277: _selectedForeground = selectedForeground;
278: }
279:
280: private Color getPressedForeground() {
281: return _pressedForeground;
282: }
283:
284: private void setPressedForeground(Color pressedForeground) {
285: _pressedForeground = pressedForeground;
286: }
287:
288: /**
289: * Gets the background for different states. The states are defined in ThemePainter as constants.
290: * Not all states are supported by all components. If the state is not supported or background is never set,
291: * it will return null.
292: * <p/>
293: * Please note, each L&F will have its own way to paint the different backgrounds. This method allows you to customize it
294: * for each component to use a different background. So if you want the background to be used, don't use a ColorUIResource because
295: * UIResource is considered as a setting set by the L&F and any L&F can choose to ignore it.
296: *
297: * @param state
298: * @return the background for different states.
299: */
300: public Color getBackgroundOfState(int state) {
301: switch (state) {
302: case ThemePainter.STATE_DEFAULT:
303: return getBackground();
304: case ThemePainter.STATE_ROLLOVER:
305: return getRolloverBackground();
306: case ThemePainter.STATE_SELECTED:
307: return getSelectedBackground();
308: case ThemePainter.STATE_PRESSED:
309: return getPressedBackground();
310: }
311: return null;
312: }
313:
314: /**
315: * Sets the background for different states. The states are defined in ThemePainter as constants.
316: * Not all states are supported by all components. If the state is not supported or background is never set,
317: * it will return null.
318: * <p/>
319: * Please note, each L&F will have its own way to paint the different backgrounds. This method allows you to customize it
320: * for each component to use a different background. So if you want the background to be used, don't use a ColorUIResource because
321: * UIResource is considered as a setting set by the L&F and any L&F can choose to ignore it.
322: *
323: * @param state
324: * @param color
325: */
326: public void setBackgroundOfState(int state, Color color) {
327: switch (state) {
328: case ThemePainter.STATE_DEFAULT:
329: setBackground(color);
330: break;
331: case ThemePainter.STATE_ROLLOVER:
332: setRolloverBackground(color);
333: break;
334: case ThemePainter.STATE_SELECTED:
335: setSelectedBackground(color);
336: break;
337: case ThemePainter.STATE_PRESSED:
338: setPressedBackground(color);
339: break;
340: }
341: }
342:
343: /**
344: * Gets the foreground for different states. The states are defined in ThemePainter as constants.
345: * Not all states are supported by all components. If the state is not supported or foreground is never set,
346: * it will return null.
347: * <p/>
348: * Please note, each L&F will have its own way to paint the different foregrounds. This method allows you to customize it
349: * for each component to use a different foreground. So if you want the foreground to be used, don't use a ColorUIResource because
350: * UIResource is considered as a setting set by the L&F and any L&F can choose to ignore it.
351: *
352: * @param state
353: * @return the foreground for different states.
354: */
355: public Color getForegroundOfState(int state) {
356: switch (state) {
357: case ThemePainter.STATE_DEFAULT:
358: return getForeground();
359: case ThemePainter.STATE_ROLLOVER:
360: return getRolloverForeground();
361: case ThemePainter.STATE_SELECTED:
362: return getSelectedForeground();
363: case ThemePainter.STATE_PRESSED:
364: return getPressedForeground();
365: }
366: return null;
367: }
368:
369: /**
370: * Sets the foreground for different states. The states are defined in ThemePainter as constants.
371: * Not all states are supported by all components. If the state is not supported or foreground is never set,
372: * it will return null.
373: * <p/>
374: * Please note, each L&F will have its own way to paint the different foregrounds. This method allows you to customize it
375: * for each component to use a different foreground. So if you want the foreground to be used, don't use a ColorUIResource because
376: * UIResource is considered as a setting set by the L&F and any L&F can choose to ignore it.
377: *
378: * @param state
379: * @param color
380: */
381: public void setForegroundOfState(int state, Color color) {
382: switch (state) {
383: case ThemePainter.STATE_DEFAULT:
384: setForeground(color);
385: break;
386: case ThemePainter.STATE_ROLLOVER:
387: setRolloverForeground(color);
388: break;
389: case ThemePainter.STATE_SELECTED:
390: setSelectedForeground(color);
391: break;
392: case ThemePainter.STATE_PRESSED:
393: setPressedForeground(color);
394: break;
395: }
396: }
397: }
|