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.UIResource;
039: import javax.swing.plaf.basic.BasicCheckBoxMenuItemUI;
040:
041: import org.jvnet.lafwidget.animation.FadeStateListener;
042: import org.jvnet.substance.utils.*;
043: import org.jvnet.substance.utils.icon.CheckBoxMenuItemIcon;
044: import org.jvnet.substance.utils.menu.MenuUtilities;
045: import org.jvnet.substance.utils.menu.MenuUtilities.MenuPropertyListener;
046:
047: /**
048: * UI for check box menu items in <b>Substance</b> look and feel.
049: *
050: * @author Kirill Grouchnikov
051: */
052: public class SubstanceCheckBoxMenuItemUI extends
053: BasicCheckBoxMenuItemUI implements SubstanceMenu {
054: /**
055: * Rollover listener.
056: */
057: protected RolloverMenuItemListener substanceRolloverListener;
058:
059: /**
060: * Listener for fade animations.
061: */
062: protected FadeStateListener substanceFadeStateListener;
063:
064: /**
065: * Listens on all changes to the underlying menu item.
066: */
067: protected MenuPropertyListener substanceMenuPropertyListener;
068:
069: /**
070: * Property change listener. Listens on changes to
071: * {@link AbstractButton#MODEL_CHANGED_PROPERTY} property.
072: */
073: protected PropertyChangeListener substancePropertyListener;
074:
075: /*
076: * (non-Javadoc)
077: *
078: * @see javax.swing.plaf.ComponentUI#createUI(javax.swing.JComponent)
079: */
080: public static ComponentUI createUI(JComponent b) {
081: JCheckBoxMenuItem item = (JCheckBoxMenuItem) b;
082: // add rollover listener
083: item.setRolloverEnabled(true);
084: return new SubstanceCheckBoxMenuItemUI();
085: }
086:
087: /*
088: * (non-Javadoc)
089: *
090: * @see javax.swing.plaf.basic.BasicMenuItemUI#installListeners()
091: */
092: @Override
093: protected void installListeners() {
094: super .installListeners();
095:
096: // Improving performance on big menus.
097: this .substanceMenuPropertyListener = new MenuPropertyListener(
098: this .menuItem);
099: this .substanceMenuPropertyListener.install();
100: // fix for defect 109 - storing reference to rollover listener
101: this .substanceRolloverListener = new RolloverMenuItemListener(
102: this .menuItem);
103: this .menuItem.addMouseListener(this .substanceRolloverListener);
104:
105: this .substanceFadeStateListener = new FadeStateListener(
106: this .menuItem, this .menuItem.getModel(),
107: SubstanceCoreUtilities.getFadeCallback(this .menuItem,
108: this .menuItem.getModel(), true, false,
109: this .menuItem));
110: this .substanceFadeStateListener.registerListeners();
111:
112: this .substancePropertyListener = new PropertyChangeListener() {
113: public void propertyChange(PropertyChangeEvent evt) {
114: if (AbstractButton.MODEL_CHANGED_PROPERTY.equals(evt
115: .getPropertyName())) {
116: if (substanceFadeStateListener != null)
117: substanceFadeStateListener
118: .unregisterListeners();
119: substanceFadeStateListener = new FadeStateListener(
120: menuItem, menuItem.getModel(),
121: SubstanceCoreUtilities.getFadeCallback(
122: menuItem, menuItem.getModel(),
123: true, false, menuItem));
124: substanceFadeStateListener.registerListeners();
125: }
126: if ("font".equals(evt.getPropertyName())) {
127: SwingUtilities.invokeLater(new Runnable() {
128: public void run() {
129: menuItem.updateUI();
130: }
131: });
132: }
133: }
134: };
135: this .menuItem
136: .addPropertyChangeListener(this .substancePropertyListener);
137: }
138:
139: /*
140: * (non-Javadoc)
141: *
142: * @see javax.swing.plaf.basic.BasicMenuItemUI#uninstallListeners()
143: */
144: @Override
145: protected void uninstallListeners() {
146: super .uninstallListeners();
147:
148: // Improving performance on big menus.
149: this .substanceMenuPropertyListener.uninstall();
150: this .substanceMenuPropertyListener = null;
151:
152: // fix for defect 109 - unregistering rollover listener
153: this .menuItem
154: .removeMouseListener(this .substanceRolloverListener);
155: this .substanceRolloverListener = null;
156:
157: this .menuItem
158: .removePropertyChangeListener(this .substancePropertyListener);
159: this .substancePropertyListener = null;
160:
161: this .substanceFadeStateListener.unregisterListeners();
162: this .substanceFadeStateListener = null;
163: }
164:
165: /*
166: * (non-Javadoc)
167: *
168: * @see javax.swing.plaf.basic.BasicMenuItemUI#installDefaults()
169: */
170: @Override
171: protected void installDefaults() {
172: super .installDefaults();
173: if (this .checkIcon == null
174: || this .checkIcon instanceof UIResource) {
175: this .checkIcon = new CheckBoxMenuItemIcon(
176: this .menuItem,
177: 1 + SubstanceSizeUtils
178: .getMenuCheckMarkSize(SubstanceSizeUtils
179: .getComponentFontSize(this .menuItem)));
180: }
181: this .defaultTextIconGap = SubstanceSizeUtils
182: .getMenuTextIconGap(SubstanceSizeUtils
183: .getComponentFontSize(this .menuItem));
184: }
185:
186: /*
187: * (non-Javadoc)
188: *
189: * @see org.jvnet.substance.SubstanceMenu#getAssociatedMenuItem()
190: */
191: public JMenuItem getAssociatedMenuItem() {
192: return this .menuItem;
193: }
194:
195: /*
196: * (non-Javadoc)
197: *
198: * @see org.jvnet.substance.SubstanceMenu#getAcceleratorFont()
199: */
200: public Font getAcceleratorFont() {
201: return this .acceleratorFont;
202: }
203:
204: /*
205: * (non-Javadoc)
206: *
207: * @see org.jvnet.substance.SubstanceMenu#getArrowIcon()
208: */
209: public Icon getArrowIcon() {
210: return this .arrowIcon;
211: }
212:
213: /*
214: * (non-Javadoc)
215: *
216: * @see org.jvnet.substance.SubstanceMenu#getCheckIcon()
217: */
218: public Icon getCheckIcon() {
219: return this .checkIcon;
220: }
221:
222: /*
223: * (non-Javadoc)
224: *
225: * @see org.jvnet.substance.SubstanceMenu#getDefaultTextIconGap()
226: */
227: public int getDefaultTextIconGap() {
228: return this .defaultTextIconGap;
229: }
230:
231: /*
232: * (non-Javadoc)
233: *
234: * @see javax.swing.plaf.basic.BasicMenuItemUI#getPreferredMenuItemSize(javax.swing.JComponent,
235: * javax.swing.Icon, javax.swing.Icon, int)
236: */
237: @Override
238: protected Dimension getPreferredMenuItemSize(JComponent c,
239: Icon checkIcon, Icon arrowIcon, int defaultTextIconGap) {
240: Dimension super Dim = super .getPreferredMenuItemSize(c,
241: checkIcon, arrowIcon, defaultTextIconGap);
242: return new Dimension(MenuUtilities.getPreferredWidth(menuItem),
243: super Dim.height);
244: }
245:
246: /*
247: * (non-Javadoc)
248: *
249: * @see javax.swing.plaf.basic.BasicMenuItemUI#paintMenuItem(java.awt.Graphics,
250: * javax.swing.JComponent, javax.swing.Icon, javax.swing.Icon,
251: * java.awt.Color, java.awt.Color, int)
252: */
253: @Override
254: protected void paintMenuItem(Graphics g, JComponent c,
255: Icon checkIcon, Icon arrowIcon, Color background,
256: Color foreground, int defaultTextIconGap) {
257: MenuUtilities.paintMenuItem(g, menuItem, checkIcon, arrowIcon,
258: defaultTextIconGap);
259: }
260: }
|