2
* Copyright (c) 2005-2010 Laf-Widget Kirill Grouchnikov. All Rights Reserved.
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions are met:
7
* o Redistributions of source code must retain the above copyright notice,
8
* this list of conditions and the following disclaimer.
10
* o Redistributions in binary form must reproduce the above copyright notice,
11
* this list of conditions and the following disclaimer in the documentation
12
* and/or other materials provided with the distribution.
14
* o Neither the name of Laf-Widget Kirill Grouchnikov nor the names of
15
* its contributors may be used to endorse or promote products derived
16
* from this software without specific prior written permission.
18
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
package org.pushingpixels.lafwidget;
33
import java.lang.reflect.Field;
34
import java.lang.reflect.Method;
37
import javax.swing.JInternalFrame.JDesktopIcon;
38
import javax.swing.plaf.TabbedPaneUI;
39
import javax.swing.plaf.basic.BasicTabbedPaneUI;
40
import javax.swing.text.JTextComponent;
42
import org.pushingpixels.lafwidget.desktop.DesktopIconHoverPreviewWidget;
43
import org.pushingpixels.lafwidget.menu.MenuSearchWidget;
44
import org.pushingpixels.lafwidget.tabbed.TabHoverPreviewWidget;
45
import org.pushingpixels.lafwidget.tabbed.TabOverviewDialogWidget;
46
import org.pushingpixels.lafwidget.text.LockBorderWidget;
47
import org.pushingpixels.lafwidget.text.PasswordStrengthCheckerWidget;
48
import org.pushingpixels.lafwidget.utils.LafConstants;
49
import org.pushingpixels.lafwidget.utils.LafConstants.PasswordStrength;
52
* LAF-specific support for widgets. Each LAF should override relevant functions
53
* based on the internal implementation. Note that if
54
* {@link LafWidgetRepository#setLafSupport(LafWidgetSupport)} is called with a
55
* custom implementation, that implementation should not throw exceptions in any
58
* @author Kirill Grouchnikov
60
public class LafWidgetSupport {
62
* Returns the component for desktop icon hover (internal frame preview)
63
* functionality. Is used in the {@link DesktopIconHoverPreviewWidget}
68
* @return The component for desktop icon hover (internal frame preview)
71
public JComponent getComponentForHover(JDesktopIcon desktopIcon) {
76
* Returns indication whether the menu search functionality should be
77
* installed on the specified menu bar. Is used in the
78
* {@link MenuSearchWidget} widget.
82
* @return <code>true</code> if the menu search functionality should be
83
* installed on the specified menu bar, <code>false</code>
86
public boolean toInstallMenuSearch(JMenuBar menuBar) {
87
return (MenuSearchWidget.getMenuItemCount(menuBar) > 40);
91
* Returns indication whether additional functionality should be installed
92
* on the specified component.
96
* @return <code>true</code> if additional functionality should be installed
97
* on the specified component, <code>false</code> otherwise.
99
public boolean toInstallExtraElements(Component comp) {
104
* Returns the search icon that matches the specified parameters. Is used in
105
* the {@link MenuSearchWidget} widget.
108
* Search icon dimension.
109
* @param componentOrientation
110
* The orientation for the search icon. Should be considered in
111
* the implementation code for proper RTL support.
112
* @return The search icon that matches the specified parameters.
114
public Icon getSearchIcon(int dimension,
115
ComponentOrientation componentOrientation) {
116
return LafWidgetUtilities.getSearchIcon(dimension, componentOrientation
121
* Returns the icon that matches the specified number. This function is used
122
* in {@link MenuSearchWidget} to set icons on menu search results. See
123
* default implementation in {@link LafWidgetUtilities#getHexaMarker(int)}
124
* that returns binary-based icons for numbers from 0 to 15. Is used in the
125
* {@link MenuSearchWidget} widget.
129
* @return The icon that matches the specified number.
131
public Icon getNumberIcon(int number) {
132
return LafWidgetUtilities.getHexaMarker(number);
136
* Marks the specified button as <code>flat</code>. A flat button doesn't
137
* show its background unless selected, armed, pressed or (possibly) hovered
138
* over. Some LAFs have flat buttons on toolbars. Is used in
139
* {@link MenuSearchWidget} and {@link TabOverviewDialogWidget} widgets.
142
* Button to mark as flat.
144
public void markButtonAsFlat(AbstractButton button) {
148
* Returns the index of the rollover tab in the specified tabbed pane. Is
149
* used in the {@link TabHoverPreviewWidget} widget.
153
* @return The index of the rollover tab in the specified tabbed pane.
154
* @throws UnsupportedOperationException
155
* In the base implementation.
157
public int getRolloverTabIndex(JTabbedPane tabbedPane) {
158
TabbedPaneUI ui = tabbedPane.getUI();
159
if (ui instanceof BasicTabbedPaneUI) {
161
Class<?> clazz = ui.getClass();
162
while (clazz != null) {
164
Method mtd = clazz.getDeclaredMethod("getRolloverTab",
167
mtd.setAccessible(true);
168
int result = (Integer) mtd
169
.invoke(ui, new Object[0]);
172
} catch (NoSuchMethodException nsme) {
174
clazz = clazz.getSuperclass();
176
} catch (Throwable t) {
177
// ignore all fall through
180
throw new UnsupportedOperationException();
184
* Sets the tab area insets for the specified tabbed pane. Is used in the
185
* {@link TabOverviewDialogWidget} widget.
189
* @param tabAreaInsets
191
* @throws UnsupportedOperationException
192
* In the base implementation.
194
public void setTabAreaInsets(JTabbedPane tabbedPane, Insets tabAreaInsets) {
195
Insets old = this.getTabAreaInsets(tabbedPane);
196
TabbedPaneUI ui = tabbedPane.getUI();
197
if (ui instanceof BasicTabbedPaneUI) {
199
Class<?> clazz = ui.getClass();
200
while (clazz != null) {
202
Field fld = clazz.getDeclaredField("tabAreaInsets");
204
fld.setAccessible(true);
205
fld.set(ui, tabAreaInsets);
206
// Fire a property change event so that the tabbed
207
// pane can revalidate itself
208
LafWidgetUtilities.firePropertyChangeEvent(
209
tabbedPane, "tabAreaInsets", old,
213
} catch (NoSuchFieldException nsfe) {
215
clazz = clazz.getSuperclass();
217
} catch (Throwable t) {
218
// ignore all fall through
221
throw new UnsupportedOperationException();
225
* Returns the tab area insets for the specified tabbed pane.Is used in the
226
* {@link TabOverviewDialogWidget} widget.
230
* @return The tab area insets for the specified tabbed pane.
232
public Insets getTabAreaInsets(JTabbedPane tabbedPane) {
233
TabbedPaneUI ui = tabbedPane.getUI();
234
if (ui instanceof BasicTabbedPaneUI) {
236
Class<?> clazz = ui.getClass();
237
while (clazz != null) {
239
Field fld = clazz.getDeclaredField("tabAreaInsets");
241
fld.setAccessible(true);
242
Insets result = (Insets) fld.get(ui);
245
} catch (NoSuchFieldException nsfe) {
247
clazz = clazz.getSuperclass();
249
} catch (Throwable t) {
250
// ignore all fall through
253
Insets result = UIManager.getInsets("TabbedPane.tabAreaInsets");
255
result = new Insets(0, 0, 0, 0);
260
* Returns the tab rectangle for the specified tab in a tabbed pane.Is used
261
* in the {@link TabHoverPreviewWidget} widget.
267
* @return The tab rectangle for the specified parameters.
268
* @throws UnsupportedOperationException
269
* In the base implementation.
271
public Rectangle getTabRectangle(JTabbedPane tabbedPane, int tabIndex) {
272
TabbedPaneUI ui = tabbedPane.getUI();
273
if (ui instanceof BasicTabbedPaneUI) {
275
Class<?> clazz = ui.getClass();
276
while (clazz != null) {
278
Field fld = clazz.getDeclaredField("rects");
280
fld.setAccessible(true);
281
Rectangle[] rects = (Rectangle[]) fld.get(ui);
282
return rects[tabIndex];
284
} catch (NoSuchFieldException nsfe) {
286
clazz = clazz.getSuperclass();
288
} catch (Throwable t) {
289
// ignore all fall through
292
throw new UnsupportedOperationException();
296
* Paints password strength marker. Is used in the
297
* {@link PasswordStrengthCheckerWidget} widget. The default implementation
298
* uses orange color for {@link org.pushingpixels.lafwidget.utils.LafConstants.PasswordStrength#WEAK}
299
* passwords, yellow color for {@link org.pushingpixels.lafwidget.utils.LafConstants.PasswordStrength#MEDIUM}
300
* passwords and green color for
301
* {@link org.pushingpixels.lafwidget.utils.LafConstants.PasswordStrength#STRONG} passwords.
306
* X coordinate for the marker.
308
* Y coordinate for the marker.
316
public void paintPasswordStrengthMarker(Graphics g, int x, int y,
317
int width, int height, PasswordStrength pStrength) {
318
Graphics2D g2 = (Graphics2D) g.create();
319
if (pStrength == PasswordStrength.WEAK)
320
g2.setColor(Color.orange);
321
if (pStrength == PasswordStrength.MEDIUM)
322
g2.setColor(Color.yellow);
323
if (pStrength == PasswordStrength.STRONG)
324
g2.setColor(Color.green);
325
g2.fillRect(x, y, width, height);
330
* Checks whether the specified component should show a lock icon. Is used
331
* in the {@link LockBorderWidget} widget.
335
* @return <code>true</code> if the specified component should show a lock
336
* icon, <code>false</code> otherwise.
338
public boolean hasLockIcon(Component comp) {
339
// check the HAS_LOCK_ICON property
340
boolean isEditableTextComponent = (comp instanceof JTextComponent) ? ((JTextComponent) comp)
343
if (comp instanceof JComponent) {
344
if (!isEditableTextComponent
345
&& Boolean.TRUE.equals(((JComponent) comp)
346
.getClientProperty(LafWidget.HAS_LOCK_ICON)))
348
if (Boolean.FALSE.equals(((JComponent) comp)
349
.getClientProperty(LafWidget.HAS_LOCK_ICON)))
352
if (!isEditableTextComponent
353
&& Boolean.TRUE.equals(UIManager.get(LafWidget.HAS_LOCK_ICON)))
360
* Returns the lock icon. Is used in {@link LockBorderWidget} widget.
362
* @return Lock icon. Should be sufficiently small (preferrably not more
363
* than 5-6 pixels wide).
365
public Icon getLockIcon(Component c) {
366
return LafWidgetUtilities.getSmallLockIcon();
370
* Returns the arrow icon (the icon used in combo box drop button, scroll
374
* One of {@link SwingConstants#NORTH} or
375
* {@link SwingConstants#SOUTH}.
376
* @return Arrow icon.
378
public Icon getArrowIcon(int orientation) {
383
* Returns the size of the lookup icon. Override to handle high DPI mode.
385
* @return The size of the lookup icon.
387
public int getLookupIconSize() {
392
* Returns the size of the lookup button. Override to handle high DPI mode.
394
* @return The size of the lookup button.
396
public int getLookupButtonSize() {