/*******************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Tiny Look and Feel * * (C) Copyright 2003 - 2005 by Hans Bickel * * * The
* starting point for Tiny Look and Feel was the XP Look and Feel written * by
* Stefan Krause. * The original header of this file was: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* XP Look and Feel * * (C) Copyright 2002, by Stefan Krause, Taufik Romdhane
* and Contributors * * * The XP Look and Feel started as as extension to the
* Metouia Look and Feel. * The original header of this file was: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Metouia Look And Feel: a free pluggable look and feel for java *
* http://mlf.sourceforge.net * (C) Copyright 2002, by Taoufik Romdhane and
* Contributors. * * This library is free software; you can redistribute it
* and/or modify it * under the terms of the GNU Lesser General Public License
* as published by * the Free Software Foundation; either version 2.1 of the
* License, or (at * your option) any later version. * * This library is
* distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY;
* without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more
* details. * * You should have received a copy of the GNU General Public
* License along * with this program; if not, write to the Free Software
* Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. * *
* Original Author: Taoufik Romdhane * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
package de.muntjak.tinylookandfeel;
import java.awt.Color;
import java.awt.Font;
import java.awt.Insets;
import java.awt.KeyboardFocusManager;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.AccessControlException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.plaf.BorderUIResource;
import javax.swing.plaf.ColorUIResource;
import javax.swing.plaf.InsetsUIResource;
import javax.swing.plaf.basic.BasicBorders;
import javax.swing.plaf.metal.MetalLookAndFeel;
import javax.swing.plaf.metal.MetalTheme;
import de.muntjak.tinylookandfeel.borders.TinyButtonBorder;
import de.muntjak.tinylookandfeel.borders.TinyFrameBorder;
import de.muntjak.tinylookandfeel.borders.TinyInternalFrameBorder;
import de.muntjak.tinylookandfeel.borders.TinyPopupMenuBorder;
import de.muntjak.tinylookandfeel.borders.TinyProgressBarBorder;
import de.muntjak.tinylookandfeel.borders.TinyScrollPaneBorder;
import de.muntjak.tinylookandfeel.borders.TinyTableHeaderBorder;
import de.muntjak.tinylookandfeel.borders.TinyTableHeaderRolloverBorder;
import de.muntjak.tinylookandfeel.borders.TinyTableScrollPaneBorder;
import de.muntjak.tinylookandfeel.borders.TinyTextFieldBorder;
import de.muntjak.tinylookandfeel.borders.TinyToolBarBorder;
import de.muntjak.tinylookandfeel.borders.TinyToolTipBorder;
/**
* TinyLookAndFeel
*
* @version 1.0
* @author Hans Bickel
*/
@SuppressWarnings (
{ "all" } )
public class TinyLookAndFeel extends MetalLookAndFeel
{
/** Will be set to true in ControlPanel.main */
public static boolean controlPanelInstantiated = false;
// this constant is the minimum width for TitlePane.TitlePaneLayout,
// it is from interest only if a frame or dialog is decorated.
static final int MINIMUM_FRAME_WIDTH = 104;
// the minimum width for internal frames and palettes
static final int MINIMUM_INTERNAL_FRAME_WIDTH = 32;
// -1 = unspecified
// 0 = JRE v1.4
// 1 = JRE v1.5 or higher
private static int is1dot4 = -1;
public static final String VERSION_STRING = "1.3.8";
public static final String DATE_STRING = "2007-6-17";
protected static TinyDefaultTheme defaultTheme;
/**
* The installation state of the TinyLaF Look and Feel.
*/
private static boolean isInstalled = false;
/**
* The installation state of the TinyLaF Theme.
*/
private static boolean themeHasBeenSet = false;
/**
* UIManager.setLookAndFeel calls this method before the first call (and
* typically the only call) to getDefaults(). Subclasses should do any
* one-time setup they need here, rather than in a static initializer, because
* look and feel class objects may be loaded just to discover that
* isSupportedLookAndFeel() returns false.
*
* @see #uninitialize
* @see UIManager#setLookAndFeel
*/
public void initialize ()
{
super.initialize ();
if ( !isInstalled )
{
isInstalled = true;
// Note: We must know (for TinyMouseHandler) on
// which JRE version we are running. Because we
// might be an applet, we execute a privileged block.
if ( is1dot4 == -1 )
{
String version = ( String ) AccessController
.doPrivileged ( new PrivilegedAction ()
{
public Object run ()
{
return System.getProperty ( "java.version" );
}
} );
if ( version != null )
{
is1dot4 = version.startsWith ( "1.0" ) || version.startsWith ( "1.1" )
|| version.startsWith ( "1.2" ) || version.startsWith ( "1.3" )
|| version.startsWith ( "1.4" ) ? 0 : 1;
}
else
{
// give up - assume we are 1.5 or higher
is1dot4 = 1;
}
}
searchDefaultTheme ();
UIManager.installLookAndFeel ( new UIManager.LookAndFeelInfo ( "TinyLaF",
"de.muntjak.tinylookandfeel.TinyLookAndFeel" ) );
}
// Execute this one even if isInstalled is true
// New in 1.3.6
if ( !"false".equals ( System.getProperty ( "altClosesMenu" ) ) )
{
KeyboardFocusManager.getCurrentKeyboardFocusManager ()
.addKeyEventPostProcessor ( TinyMenuUI.altProcessor );
}
}
/**
* @return true if we are running Java 1.4 or lower, false otherwise
*/
public static boolean is1dot4 ()
{
return ( is1dot4 == 0 );
}
public void uninitialize ()
{
super.uninitialize ();
KeyboardFocusManager.getCurrentKeyboardFocusManager ()
.removeKeyEventPostProcessor ( TinyMenuUI.altProcessor );
}
private void searchDefaultTheme ()
{
// only if running without the control panel
if ( controlPanelInstantiated )
return;
String loadedFrom = null;
URL defaultURL = TinyLookAndFeel.class.getResource ( "/"
+ Theme.DEFAULT_THEME );
if ( Theme.loadTheme ( defaultURL, Theme.CUSTOM_STYLE ) )
{
Theme.style = Theme.CUSTOM_STYLE;
loadedFrom = defaultURL.toExternalForm ();
}
else
{
defaultURL = Thread.currentThread ().getContextClassLoader ()
.getResource ( Theme.DEFAULT_THEME );
if ( Theme.loadTheme ( defaultURL, Theme.CUSTOM_STYLE ) )
{
Theme.style = Theme.CUSTOM_STYLE;
loadedFrom = defaultURL.toExternalForm ();
}
else
{
try
{
defaultURL = new File ( System.getProperty ( "user.home" ),
Theme.DEFAULT_THEME ).toURI ().toURL ();
if ( Theme.loadTheme ( defaultURL, Theme.CUSTOM_STYLE ) )
{
Theme.style = Theme.CUSTOM_STYLE;
loadedFrom = defaultURL.toExternalForm ();
}
else
{
defaultURL = new File ( System.getProperty ( "user.dir" ),
Theme.DEFAULT_THEME ).toURI ().toURL ();
if ( Theme.loadTheme ( defaultURL, Theme.CUSTOM_STYLE ) )
{
Theme.style = Theme.CUSTOM_STYLE;
loadedFrom = defaultURL.toExternalForm ();
}
// else we give up
}
}
catch ( MalformedURLException ignore )
{
}
// AccessControlException is thrown when running
// with Java Web Start
catch ( AccessControlException ignore )
{
}
}
}
}
/**
* Return a string that identifies this look and feel. This string will be
* used by applications/services that want to recognize well known look and
* feel implementations. Presently the well known names are "Motif",
* "Windows", "Mac", "Metal". Note that a LookAndFeel derived from a well
* known superclass that doesn't make any fundamental changes to the look or
* feel shouldn't override this method.
*
* @return The TinyLaF Look and Feel identifier.
*/
public String getID ()
{
return "TinyLaF";
}
/**
* Return a short string that identifies this look and feel, e.g. "CDE/Motif".
* This string should be appropriate for a menu item. Distinct look and feels
* should have different names, e.g. a subclass of MotifLookAndFeel that
* changes the way a few components are rendered should be called "CDE/Motif
* My Way"; something that would be useful to a user trying to select a L&F
* from a list of names.
*
* @return The look and feel short name.
*/
public String getName ()
{
return "TinyLaF";
}
/**
* Return a one line description of this look and feel implementation, e.g.
* "The CDE/Motif Look and Feel". This string is intended for the user, e.g.
* in the title of a window or in a ToolTip message.
*
* @return The look and feel short description.
*/
public String getDescription ()
{
return "TinyLaF";
}
/**
* If the underlying platform has a "native" look and feel, and this is an
* implementation of it, return true. For example a CDE/Motif look and
* implementation would return true when the underlying platform was Solaris.
*/
public boolean isNativeLookAndFeel ()
{
return false;
}
/**
* Return true if the underlying platform supports and or permits this look
* and feel. This method returns false if the look and feel depends on special
* resources or legal agreements that aren't defined for the current platform.
*/
public final boolean isSupportedLookAndFeel ()
{
return true;
}
public boolean getSupportsWindowDecorations ()
{
return true;
}
/**
* Initializes the uiClassID to BasicComponentUI mapping. The JComponent
* classes define their own uiClassID constants. This table must map those
* constants to a BasicComponentUI class of the appropriate type.
*
* @param table The ui defaults table.
*/
protected void initClassDefaults ( UIDefaults table )
{
super.initClassDefaults ( table );
table.putDefaults ( new Object []
{ "ButtonUI", "de.muntjak.tinylookandfeel.TinyButtonUI", "CheckBoxUI",
"de.muntjak.tinylookandfeel.TinyCheckBoxUI", "TextFieldUI",
"de.muntjak.tinylookandfeel.TinyTextFieldUI", "TextAreaUI",
"de.muntjak.tinylookandfeel.TinyTextAreaUI",
/* New in 1.3.6: Removed entry for FormattedTextFieldUI */
"PasswordFieldUI", "de.muntjak.tinylookandfeel.TinyPasswordFieldUI",
"EditorPaneUI", "de.muntjak.tinylookandfeel.TinyEditorPaneUI",
"TextPaneUI", "de.muntjak.tinylookandfeel.TinyTextPaneUI", "SliderUI",
"de.muntjak.tinylookandfeel.TinySliderUI", "SpinnerUI",
"de.muntjak.tinylookandfeel.TinySpinnerUI", "ToolBarUI",
"de.muntjak.tinylookandfeel.TinyToolBarUI", "ToolBarSeparatorUI",
"de.muntjak.tinylookandfeel.TinyToolBarSeparatorUI", "MenuBarUI",
"de.muntjak.tinylookandfeel.TinyMenuBarUI", "MenuUI",
"de.muntjak.tinylookandfeel.TinyMenuUI", "MenuItemUI",
"de.muntjak.tinylookandfeel.TinyMenuItemUI", "CheckBoxMenuItemUI",
"de.muntjak.tinylookandfeel.TinyCheckBoxMenuItemUI",
"RadioButtonMenuItemUI",
"de.muntjak.tinylookandfeel.TinyRadioButtonMenuItemUI", "ScrollBarUI",
"de.muntjak.tinylookandfeel.TinyScrollBarUI", "TabbedPaneUI",
"de.muntjak.tinylookandfeel.TinyTabbedPaneUI", "ToggleButtonUI",
"de.muntjak.tinylookandfeel.TinyButtonUI", "ScrollPaneUI",
"de.muntjak.tinylookandfeel.TinyScrollPaneUI", "ProgressBarUI",
"de.muntjak.tinylookandfeel.TinyProgressBarUI", "InternalFrameUI",
"de.muntjak.tinylookandfeel.TinyInternalFrameUI", "RadioButtonUI",
"de.muntjak.tinylookandfeel.TinyRadioButtonUI", "ComboBoxUI",
"de.muntjak.tinylookandfeel.TinyComboBoxUI", "PopupMenuSeparatorUI",
"de.muntjak.tinylookandfeel.TinyPopupMenuSeparatorUI", "SeparatorUI",
"de.muntjak.tinylookandfeel.TinySeparatorUI", "SplitPaneUI",
"de.muntjak.tinylookandfeel.TinySplitPaneUI", "FileChooserUI",
"de.muntjak.tinylookandfeel.TinyFileChooserUI", "ListUI",
"de.muntjak.tinylookandfeel.TinyListUI", "TreeUI",
"de.muntjak.tinylookandfeel.TinyTreeUI", "LabelUI",
"de.muntjak.tinylookandfeel.TinyLabelUI", "TableUI",
"de.muntjak.tinylookandfeel.TinyTableUI", "TableHeaderUI",
"de.muntjak.tinylookandfeel.TinyTableHeaderUI", "ToolTipUI",
"de.muntjak.tinylookandfeel.TinyToolTipUI", "RootPaneUI",
"de.muntjak.tinylookandfeel.TinyRootPaneUI", "DesktopPaneUI",
"de.muntjak.tinylookandfeel.TinyDesktopPaneUI" } );
}
/**
* Creates the default theme and installs it. The TinyDefaultTheme is used as
* default.
*/
protected void createDefaultTheme ()
{
// if(JFrame.isDefaultLookAndFeelDecorated()) {
// System.setProperty("sun.awt.noerasebackground", "true");
// }
// Note: up to 1.3.02, the if-clause below prevented
// the theme from being re-loaded when refreshing an Applet page
// if(!themeHasBeenSet) {
defaultTheme = new TinyDefaultTheme ();
setCurrentTheme ( defaultTheme );
// }
}
/**
* Sets the current color theme. Warning: The theme must be an instance of
* TinyDefaultTheme!
*
* @param theme the theme to install.
*/
public static void setCurrentTheme ( MetalTheme theme )
{
MetalLookAndFeel.setCurrentTheme ( theme );
themeHasBeenSet = true;
}
/**
* Initializes the default values for many ui widgets and puts them in the
* given ui defaults table. Here is the place where borders can be changed.
*
* @param table The ui defaults table.
*/
protected void initComponentDefaults ( UIDefaults table )
{
super.initComponentDefaults ( table );
// Replace Metal borders:
Border border = new EmptyBorder ( 0, 0, 0, 0 );
table.put ( "Button.border", new BorderUIResource.CompoundBorderUIResource (
new TinyButtonBorder (), new BasicBorders.MarginBorder () ) );
table.put ( "FormattedTextField.border", new TinyTextFieldBorder () );
table.put ( "TextField.border", new TinyTextFieldBorder () );
table.put ( "PasswordField.border", new TinyTextFieldBorder () );
table.put ( "ComboBox.border", border );
table.put ( "Table.scrollPaneBorder", new TinyTableScrollPaneBorder () );
table.put ( "TableHeader.cellBorder", new TinyTableHeaderBorder () );
table.put ( "TableHeader.cellRolloverBorder",
new TinyTableHeaderRolloverBorder () );
table.put ( "Spinner.border", new TinyTextFieldBorder ( new Insets ( 2, 2,
2, 2 ) ) );
table.put ( "ProgressBar.border", new TinyProgressBarBorder () );
table.put ( "ToolBar.border", new TinyToolBarBorder () );
table.put ( "ToolTip.border", new BorderUIResource ( new TinyToolTipBorder (
true ) ) );
table.put ( "ToolTip.borderInactive", new BorderUIResource (
new TinyToolTipBorder ( false ) ) );
border = new TinyInternalFrameBorder ();
table.put ( "InternalFrame.border", border );
table.put ( "InternalFrame.paletteBorder", border );
table.put ( "InternalFrame.optionDialogBorder", border );
border = new EmptyBorder ( 2, 4, 2, 4 );
table.put ( "Menu.border", border );
table.put ( "MenuItem.border", border );
table.put ( "CheckBoxMenuItem.border", border );
table.put ( "RadioButtonMenuItem.border", border );
table.put ( "PopupMenu.border", new TinyPopupMenuBorder () );
table.put ( "ScrollPane.border", new TinyScrollPaneBorder () );
table.put ( "Slider.trackWidth", new Integer ( 4 ) );
// Note: Margins correspond to borders. In TinyLaF 1.2 checkboxes
// and radio buttons had the Metal border which itself adds insets
// of (2, 2, 2, 2) - so a 1.3 checkbox/radio button has the same
// visible margin as a 1.2 checkbox/radio button because margins
// in 1.2 where (0, 0, 0, 0)
table.put ( "CheckBox.border", new BasicBorders.MarginBorder () );
table.put ( "RadioButton.border", new BasicBorders.MarginBorder () );
table.put ( "RadioButton.margin", new InsetsUIResource ( 2, 2, 2, 2 ) );
table.put ( "CheckBox.margin", new InsetsUIResource ( 2, 2, 2, 2 ) );
// Tweak some subtle values:
table.put ( "SplitPane.dividerSize", new Integer ( 7 ) );
table.put ( "InternalFrame.normalTitleFont", new Font ( "dialog",
Font.BOLD, 13 ) );
// New in 1.3.7 - value is evaluated at
// javax.swing.plaf.basic.BasicFileChooserUI.installDefaults(JFileChooser)
if ( System.getProperty ( "os.name" ).toLowerCase ().startsWith ( "linux" ) )
{
table.put ( "FileChooser.readOnly", Boolean.TRUE );
}
table.put ( "TabbedPane.tabInsets", new Insets ( 1, 6, 4, 6 ) );
table.put ( "TabbedPane.selectedTabPadInsets", new Insets ( 2, 2, 1, 2 ) );
table.put ( "TabbedPane.unselected", new ColorUIResource ( 0, 0, 0 ) );
table.put ( "TabbedPane.tabAreaInsets", new Insets ( 6, 2, 0, 0 ) );
table.put ( "TabbedPane.contentBorderInsets", new Insets ( 1, 1, 3, 3 ) );
table.put ( "PopupMenu.foreground", new Color ( 255, 0, 0 ) );
table.put ( "RootPane.colorChooserDialogBorder", TinyFrameBorder
.getInstance () );
table.put ( "RootPane.errorDialogBorder", TinyFrameBorder.getInstance () );
table.put ( "RootPane.fileChooserDialogBorder", TinyFrameBorder
.getInstance () );
table.put ( "RootPane.frameBorder", TinyFrameBorder.getInstance () );
table.put ( "RootPane.informationDialogBorder", TinyFrameBorder
.getInstance () );
table.put ( "RootPane.plainDialogBorder", TinyFrameBorder.getInstance () );
table
.put ( "RootPane.questionDialogBorder", TinyFrameBorder.getInstance () );
table.put ( "RootPane.warningDialogBorder", TinyFrameBorder.getInstance () );
table.put ( "CheckBoxMenuItem.checkIcon", MenuItemIconFactory
.getCheckBoxMenuItemIcon () );
table.put ( "RadioButtonMenuItem.checkIcon", MenuItemIconFactory
.getRadioButtonMenuItemIcon () );
table.put ( "Menu.arrowIcon", MenuItemIconFactory.getMenuArrowIcon () );
table.put ( "InternalFrame.frameTitleHeight", new Integer ( 25 ) );
table.put ( "InternalFrame.paletteTitleHeight", new Integer ( 16 ) );
table
.put ( "InternalFrame.icon", loadIcon ( "InternalFrameIcon.png", this ) );
table.put ( "Tree.expandedIcon", loadIcon ( "TreeMinusIcon.png", this ) );
table.put ( "Tree.collapsedIcon", loadIcon ( "TreePlusIcon.png", this ) );
table.put ( "Tree.openIcon", loadIcon ( "TreeFolderOpenedIcon.png", this ) );
table
.put ( "Tree.closedIcon", loadIcon ( "TreeFolderClosedIcon.png", this ) );
table.put ( "Tree.leafIcon", loadIcon ( "TreeLeafIcon.png", this ) );
table
.put ( "FileView.directoryIcon", loadIcon ( "DirectoryIcon.png", this ) );
table.put ( "FileView.computerIcon", loadIcon ( "ComputerIcon.png", this ) );
table.put ( "FileView.fileIcon", loadIcon ( "FileIcon.png", this ) );
table
.put ( "FileView.floppyDriveIcon", loadIcon ( "FloppyIcon.png", this ) );
table
.put ( "FileView.hardDriveIcon", loadIcon ( "HarddiskIcon.png", this ) );
table.put ( "FileChooser.detailsViewIcon", loadIcon (
"FileDetailsIcon.png", this ) );
table.put ( "FileChooser.homeFolderIcon", loadIcon ( "HomeFolderIcon.png",
this ) );
table.put ( "FileChooser.listViewIcon",
loadIcon ( "FileListIcon.png", this ) );
table.put ( "FileChooser.newFolderIcon", loadIcon ( "NewFolderIcon.png",
this ) );
table.put ( "FileChooser.upFolderIcon", loadIcon (
"ParentDirectoryIcon.png", this ) );
table.put ( "OptionPane.errorIcon", loadIcon ( "ErrorIcon.png", this ) );
table.put ( "OptionPane.informationIcon", loadIcon ( "InformationIcon.png",
this ) );
table.put ( "OptionPane.warningIcon", loadIcon ( "WarningIcon.png", this ) );
table
.put ( "OptionPane.questionIcon", loadIcon ( "QuestionIcon.png", this ) );
}
public static Icon getUncolorizedSystemIcon ( int index )
{
switch ( index )
{
case 0 :
return loadIcon ( "InternalFrameIcon.png", null );
case 1 :
return loadIcon ( "TreeFolderClosedIcon.png", null );
case 2 :
return loadIcon ( "TreeFolderOpenedIcon.png", null );
case 3 :
return loadIcon ( "TreeLeafIcon.png", null );
case 4 :
return loadIcon ( "TreeMinusIcon.png", null );
case 5 :
return loadIcon ( "TreePlusIcon.png", null );
case 6 :
return loadIcon ( "ComputerIcon.png", null );
case 7 :
return loadIcon ( "FloppyIcon.png", null );
case 8 :
return loadIcon ( "HarddiskIcon.png", null );
case 9 :
return loadIcon ( "DirectoryIcon.png", null );
case 10 :
return loadIcon ( "FileIcon.png", null );
case 11 :
return loadIcon ( "ParentDirectoryIcon.png", null );
case 12 :
return loadIcon ( "HomeFolderIcon.png", null );
case 13 :
return loadIcon ( "NewFolderIcon.png", null );
case 14 :
return loadIcon ( "FileListIcon.png", null );
case 15 :
return loadIcon ( "FileDetailsIcon.png", null );
case 16 :
return loadIcon ( "InformationIcon.png", null );
case 17 :
return loadIcon ( "QuestionIcon.png", null );
case 18 :
return loadIcon ( "WarningIcon.png", null );
default :
return loadIcon ( "ErrorIcon.png", null );
}
}
public static String getSystemIconName ( int index )
{
switch ( index )
{
case 0 :
return "InternalFrame.icon";
case 1 :
return "Tree.closedIcon";
case 2 :
return "Tree.openIcon";
case 3 :
return "Tree.leafIcon";
case 4 :
return "Tree.expandedIcon";
case 5 :
return "Tree.collapsedIcon";
case 6 :
return "FileView.computerIcon";
case 7 :
return "FileView.floppyDriveIcon";
case 8 :
return "FileView.hardDriveIcon";
case 9 :
return "FileView.directoryIcon";
case 10 :
return "FileView.fileIcon";
case 11 :
return "FileChooser.upFolderIcon";
case 12 :
return "FileChooser.homeFolderIcon";
case 13 :
return "FileChooser.newFolderIcon";
case 14 :
return "FileChooser.listViewIcon";
case 15 :
return "FileChooser.detailsViewIcon";
case 16 :
return "OptionPane.informationIcon";
case 17 :
return "OptionPane.questionIcon";
case 18 :
return "OptionPane.warningIcon";
default :
return "OptionPane.errorIcon";
}
}
/**
* Loads an image icon.
*
* @param file The image file name.
* @param invoker The refence of the invoking class, whose classloader will be
* used for loading the image.
*/
public static ImageIcon loadIcon ( final String fileName, final Object invoker )
{
// This should work for both applications and applets
URL url = Thread.currentThread ().getContextClassLoader ().getResource (
"de/muntjak/tinylookandfeel/icons/" + fileName );
if ( url == null )
{
// Another try
url = TinyLookAndFeel.class
.getResource ( "/de/muntjak/tinylookandfeel/icons/" + fileName );
if ( url == null )
{
System.err.println ( "TinyLaF: Icon directory could not be resolved." );
return null;
}
}
return new ImageIcon ( url );
}
}