001: /*
002: * Copyright (c) 2005-2008 Substance Kirill Grouchnikov. All Rights Reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * o Redistributions of source code must retain the above copyright notice,
008: * this list of conditions and the following disclaimer.
009: *
010: * o Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: *
014: * o Neither the name of Substance Kirill Grouchnikov nor the names of
015: * its contributors may be used to endorse or promote products derived
016: * from this software without specific prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
020: * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
021: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
022: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
023: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
025: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
026: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
027: * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
028: * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029: */
030: package org.jvnet.substance;
031:
032: import java.awt.*;
033: import java.beans.PropertyChangeEvent;
034: import java.beans.PropertyChangeListener;
035:
036: import javax.swing.*;
037: import javax.swing.plaf.ComponentUI;
038: import javax.swing.plaf.basic.BasicMenuItemUI;
039:
040: import org.jvnet.lafwidget.animation.FadeStateListener;
041: import org.jvnet.substance.utils.SubstanceCoreUtilities;
042: import org.jvnet.substance.utils.SubstanceSizeUtils;
043: import org.jvnet.substance.utils.menu.MenuUtilities;
044: import org.jvnet.substance.utils.menu.MenuUtilities.MenuPropertyListener;
045:
046: /**
047: * UI for menu items in <b>Substance</b> look and feel.
048: *
049: * @author Kirill Grouchnikov
050: */
051: public class SubstanceMenuItemUI extends BasicMenuItemUI implements
052: SubstanceMenu {
053: /**
054: * Listener for fade animations.
055: */
056: protected FadeStateListener substanceFadeStateListener;
057:
058: /**
059: * Listens on all changes to the underlying menu item.
060: */
061: protected MenuPropertyListener substanceMenuPropertyListener;
062:
063: /**
064: * Property change listener. Listens on changes to
065: * {@link AbstractButton#MODEL_CHANGED_PROPERTY} property.
066: */
067: protected PropertyChangeListener substancePropertyListener;
068:
069: /*
070: * (non-Javadoc)
071: *
072: * @see javax.swing.plaf.ComponentUI#createUI(javax.swing.JComponent)
073: */
074: public static ComponentUI createUI(JComponent c) {
075: return new SubstanceMenuItemUI();
076: }
077:
078: /*
079: * (non-Javadoc)
080: *
081: * @see javax.swing.plaf.basic.BasicMenuItemUI#installListeners()
082: */
083: @Override
084: protected void installListeners() {
085: super .installListeners();
086:
087: // Improving performance on big menus.
088: this .substanceMenuPropertyListener = new MenuPropertyListener(
089: this .menuItem);
090: this .substanceMenuPropertyListener.install();
091:
092: this .substanceFadeStateListener = new FadeStateListener(
093: this .menuItem, this .menuItem.getModel(),
094: SubstanceCoreUtilities.getFadeCallback(this .menuItem,
095: this .menuItem.getModel(), true, false,
096: this .menuItem));
097: this .substanceFadeStateListener.registerListeners();
098:
099: this .substancePropertyListener = new PropertyChangeListener() {
100: public void propertyChange(PropertyChangeEvent evt) {
101: if (AbstractButton.MODEL_CHANGED_PROPERTY.equals(evt
102: .getPropertyName())) {
103: if (substanceFadeStateListener != null)
104: substanceFadeStateListener
105: .unregisterListeners();
106: substanceFadeStateListener = new FadeStateListener(
107: menuItem, menuItem.getModel(),
108: SubstanceCoreUtilities.getFadeCallback(
109: menuItem, menuItem.getModel(),
110: true, false, menuItem));
111: substanceFadeStateListener.registerListeners();
112: }
113: }
114: };
115: this .menuItem
116: .addPropertyChangeListener(this .substancePropertyListener);
117: }
118:
119: /*
120: * (non-Javadoc)
121: *
122: * @see javax.swing.plaf.basic.BasicMenuItemUI#installDefaults()
123: */
124: @Override
125: protected void installDefaults() {
126: super .installDefaults();
127:
128: this .defaultTextIconGap = SubstanceSizeUtils
129: .getMenuTextIconGap(SubstanceSizeUtils
130: .getComponentFontSize(this .menuItem));
131: }
132:
133: /*
134: * (non-Javadoc)
135: *
136: * @see javax.swing.plaf.basic.BasicMenuItemUI#uninstallListeners()
137: */
138: @Override
139: protected void uninstallListeners() {
140: // Improving performance on big menus.
141: this .substanceMenuPropertyListener.uninstall();
142: this .substanceMenuPropertyListener = null;
143:
144: this .menuItem
145: .removePropertyChangeListener(this .substancePropertyListener);
146: this .substancePropertyListener = null;
147:
148: this .substanceFadeStateListener.unregisterListeners();
149: this .substanceFadeStateListener = null;
150:
151: super .uninstallListeners();
152: }
153:
154: /*
155: * (non-Javadoc)
156: *
157: * @see org.jvnet.substance.SubstanceMenu#getAssociatedMenuItem()
158: */
159: public JMenuItem getAssociatedMenuItem() {
160: return this .menuItem;
161: }
162:
163: /*
164: * (non-Javadoc)
165: *
166: * @see org.jvnet.substance.SubstanceMenu#getAcceleratorFont()
167: */
168: public Font getAcceleratorFont() {
169: return this .acceleratorFont;
170: }
171:
172: /*
173: * (non-Javadoc)
174: *
175: * @see org.jvnet.substance.SubstanceMenu#getArrowIcon()
176: */
177: public Icon getArrowIcon() {
178: return this .arrowIcon;
179: }
180:
181: /*
182: * (non-Javadoc)
183: *
184: * @see org.jvnet.substance.SubstanceMenu#getCheckIcon()
185: */
186: public Icon getCheckIcon() {
187: return null;
188: }
189:
190: /*
191: * (non-Javadoc)
192: *
193: * @see org.jvnet.substance.SubstanceMenu#getDefaultTextIconGap()
194: */
195: public int getDefaultTextIconGap() {
196: return this .defaultTextIconGap;
197: }
198:
199: /*
200: * (non-Javadoc)
201: *
202: * @see javax.swing.plaf.basic.BasicMenuItemUI#getPreferredMenuItemSize(javax.swing.JComponent,
203: * javax.swing.Icon, javax.swing.Icon, int)
204: */
205: @Override
206: protected Dimension getPreferredMenuItemSize(JComponent c,
207: Icon checkIcon, Icon arrowIcon, int defaultTextIconGap) {
208: Dimension super Dim = super .getPreferredMenuItemSize(c,
209: checkIcon, arrowIcon, defaultTextIconGap);
210: return new Dimension(MenuUtilities.getPreferredWidth(menuItem),
211: super Dim.height);
212: }
213:
214: /*
215: * (non-Javadoc)
216: *
217: * @see javax.swing.plaf.basic.BasicMenuItemUI#paintMenuItem(java.awt.Graphics,
218: * javax.swing.JComponent, javax.swing.Icon, javax.swing.Icon,
219: * java.awt.Color, java.awt.Color, int)
220: */
221: @Override
222: protected void paintMenuItem(Graphics g, JComponent c,
223: Icon checkIcon, Icon arrowIcon, Color background,
224: Color foreground, int defaultTextIconGap) {
225: MenuUtilities.paintMenuItem(g, menuItem, checkIcon, arrowIcon,
226: defaultTextIconGap);
227: }
228: }
|