mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 03:50:02 +02:00
GP-1981 externalized icons for XTRA modules. Added loadIcon method in
ResourceManager. Created api for integrating Options with Theming. Fixed issue with system property mappings. Created dynamic icons for the close and drop-down menu item icons.
This commit is contained in:
parent
0971c0088c
commit
d466dbf06b
32 changed files with 637 additions and 260 deletions
|
@ -1,22 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package generic;
|
||||
|
||||
public class Images {
|
||||
public static String BOMB = "images/core.png";
|
||||
public static String BIG_BOMB = "images/core24.png";
|
||||
}
|
|
@ -99,7 +99,8 @@ public abstract class AbstractThemeReader {
|
|||
return IconValue.parse(key, value);
|
||||
}
|
||||
catch (ParseException e) {
|
||||
error(lineNumber, "Could not parse Icon value: " + value + "because " + e.getMessage());
|
||||
error(lineNumber,
|
||||
"Could not parse Icon value: \"" + value + "\" because: " + e.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -61,6 +61,7 @@ public class Gui {
|
|||
private static GThemeValueMap applicationDarkDefaults = new GThemeValueMap();
|
||||
private static GThemeValueMap javaDefaults = new GThemeValueMap();
|
||||
private static GThemeValueMap currentValues = new GThemeValueMap();
|
||||
private static GThemeValueMap systemValues = new GThemeValueMap();
|
||||
|
||||
private static ThemeFileLoader themeFileLoader = new ThemeFileLoader();
|
||||
private static ThemePreferenceManager themePreferenceManager = new ThemePreferenceManager();
|
||||
|
@ -114,6 +115,72 @@ public class Gui {
|
|||
notifyThemeChanged(new AllValuesChangedThemeEvent(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores the current color value for the given color id to the value established by the
|
||||
* current theme.
|
||||
* @param id the color id to restore back to the original theme value
|
||||
*/
|
||||
public static void restoreColor(String id) {
|
||||
if (changedValuesMap.containsColor(id)) {
|
||||
Gui.setColor(changedValuesMap.getColor(id));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores the current font value for the given font id to the value established by the
|
||||
* current theme.
|
||||
* @param id the font id to restore back to the original theme value
|
||||
*/
|
||||
public static void restoreFont(String id) {
|
||||
if (changedValuesMap.containsFont(id)) {
|
||||
Gui.setFont(changedValuesMap.getFont(id));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores the current icon value for the given icon id to the value established by the
|
||||
* current theme.
|
||||
* @param id the icon id to restore back to the original theme value
|
||||
*/
|
||||
public static void restoreIcon(String id) {
|
||||
if (changedValuesMap.containsIcon(id)) {
|
||||
Gui.setIcon(changedValuesMap.getIcon(id));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the color associated with the given id has been changed from the current
|
||||
* theme value for that id.
|
||||
* @param id the color id to check if it has been changed
|
||||
* @return true if the color associated with the given id has been changed from the current
|
||||
* theme value for that id.
|
||||
*/
|
||||
public static boolean isChangedColor(String id) {
|
||||
return changedValuesMap.containsColor(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the font associated with the given id has been changed from the current
|
||||
* theme value for that id.
|
||||
* @param id the font id to check if it has been changed
|
||||
* @return true if the font associated with the given id has been changed from the current
|
||||
* theme value for that id.
|
||||
*/
|
||||
public static boolean isChangedFont(String id) {
|
||||
return changedValuesMap.containsFont(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the Icon associated with the given id has been changed from the current
|
||||
* theme value for that id.
|
||||
* @param id the Icon id to check if it has been changed
|
||||
* @return true if the Icon associated with the given id has been changed from the current
|
||||
* theme value for that id.
|
||||
*/
|
||||
public static boolean isChangedIcon(String id) {
|
||||
return changedValuesMap.containsIcon(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the application's active theme to the given theme.
|
||||
* @param theme the theme to make active
|
||||
|
@ -125,8 +192,8 @@ public class Gui {
|
|||
lookAndFeelManager = lookAndFeel.getLookAndFeelManager();
|
||||
try {
|
||||
lookAndFeelManager.installLookAndFeel();
|
||||
notifyThemeChanged(new AllValuesChangedThemeEvent(true));
|
||||
themePreferenceManager.saveThemeToPreferences(theme);
|
||||
notifyThemeChanged(new AllValuesChangedThemeEvent(true));
|
||||
}
|
||||
catch (Exception e) {
|
||||
Msg.error(Gui.class,
|
||||
|
@ -388,6 +455,10 @@ public class Gui {
|
|||
return gIcon;
|
||||
}
|
||||
|
||||
public static void setSystemDefaults(GThemeValueMap map) {
|
||||
systemValues = map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the map of JavaDefaults defined by the current {@link LookAndFeel}.
|
||||
* @param map the default theme values defined by the {@link LookAndFeel}
|
||||
|
@ -442,6 +513,7 @@ public class Gui {
|
|||
*/
|
||||
public static GThemeValueMap getDefaults() {
|
||||
GThemeValueMap currentDefaults = new GThemeValueMap(javaDefaults);
|
||||
currentDefaults.load(systemValues);
|
||||
currentDefaults.load(applicationDefaults);
|
||||
if (activeTheme.useDarkDefaults()) {
|
||||
currentDefaults.load(applicationDarkDefaults);
|
||||
|
@ -626,6 +698,7 @@ public class Gui {
|
|||
GThemeValueMap map = new GThemeValueMap();
|
||||
|
||||
map.load(javaDefaults);
|
||||
map.load(systemValues);
|
||||
map.load(applicationDefaults);
|
||||
if (activeTheme.useDarkDefaults()) {
|
||||
map.load(applicationDarkDefaults);
|
||||
|
|
|
@ -149,11 +149,15 @@ public class IconValue extends ThemeValue<Icon> {
|
|||
return new IconValue(id, icon, modifier);
|
||||
}
|
||||
|
||||
private static Icon getIcon(String baseIconString) {
|
||||
private static Icon getIcon(String baseIconString) throws ParseException {
|
||||
if (EMPTY_ICON_STRING.equals(baseIconString)) {
|
||||
return new EmptyIcon(STANDARD_EMPTY_ICON_SIZE, STANDARD_EMPTY_ICON_SIZE);
|
||||
}
|
||||
return ResourceManager.loadImage(baseIconString);
|
||||
Icon icon = ResourceManager.loadIcon(baseIconString);
|
||||
if (icon == null) {
|
||||
throw new ParseException("Can't find icon for \"" + baseIconString + "\"", 0);
|
||||
}
|
||||
return icon;
|
||||
}
|
||||
|
||||
private static IconValue parseRefIcon(String id, String value) throws ParseException {
|
||||
|
|
|
@ -84,6 +84,7 @@ public abstract class LookAndFeelManager {
|
|||
IllegalAccessException, UnsupportedLookAndFeelException {
|
||||
|
||||
cleanUiDefaults();
|
||||
Gui.setSystemDefaults(systemToLafMap);
|
||||
doInstallLookAndFeel();
|
||||
installJavaDefaults();
|
||||
fixupLookAndFeelIssues();
|
||||
|
@ -262,7 +263,6 @@ public abstract class LookAndFeelManager {
|
|||
*/
|
||||
private void installJavaDefaults() {
|
||||
GThemeValueMap javaDefaults = extractJavaDefaults();
|
||||
javaDefaults.load(systemToLafMap); // add in our system color mappings
|
||||
ThemeGrouper grouper = getThemeGrouper();
|
||||
grouper.group(javaDefaults);
|
||||
Gui.setJavaDefaults(javaDefaults);
|
||||
|
@ -331,7 +331,6 @@ public abstract class LookAndFeelManager {
|
|||
Icon icon = UIManager.getIcon(id);
|
||||
values.addIcon(new IconValue(id, icon));
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
|
|
|
@ -131,6 +131,10 @@ public abstract class AbstractOptions implements Options {
|
|||
public synchronized void registerOption(String optionName, OptionType type, Object defaultValue,
|
||||
HelpLocation help, String description, PropertyEditor editor) {
|
||||
|
||||
if (type == OptionType.COLOR_TYPE) {
|
||||
// Msg.warn(this, "Registering color: " + optionName,
|
||||
// ReflectionUtilities.createJavaFilteredThrowable());
|
||||
}
|
||||
if (type == OptionType.NO_TYPE) {
|
||||
throw new IllegalArgumentException(
|
||||
"Can't register an option of type: " + OptionType.NO_TYPE);
|
||||
|
@ -151,7 +155,7 @@ public abstract class AbstractOptions implements Options {
|
|||
ReflectionUtilities.createJavaFilteredThrowable());
|
||||
}
|
||||
|
||||
Option currentOption = getExistingComptibleOption(optionName, type, defaultValue);
|
||||
Option currentOption = getExistingComptibleOption(optionName, type);
|
||||
if (currentOption != null) {
|
||||
currentOption.updateRegistration(description, help, defaultValue, editor);
|
||||
return;
|
||||
|
@ -163,8 +167,31 @@ public abstract class AbstractOptions implements Options {
|
|||
valueMap.put(optionName, option);
|
||||
}
|
||||
|
||||
private Option getExistingComptibleOption(String optionName, OptionType type,
|
||||
Object defaultValue) {
|
||||
@Override
|
||||
public void registerThemeColorOption(String optionName, String colorId, HelpLocation help,
|
||||
String description) {
|
||||
Option currentOption = getExistingComptibleOption(optionName, OptionType.COLOR_TYPE);
|
||||
if (currentOption != null && currentOption instanceof ThemeColorOption) {
|
||||
currentOption.updateRegistration(description, help, null, null);
|
||||
return;
|
||||
}
|
||||
Option option = new ThemeColorOption(optionName, colorId, description, help);
|
||||
valueMap.put(optionName, option);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerThemeFontOption(String optionName, String fontId, HelpLocation help,
|
||||
String description) {
|
||||
Option currentOption = getExistingComptibleOption(optionName, OptionType.FONT_TYPE);
|
||||
if (currentOption != null && currentOption instanceof ThemeFontOption) {
|
||||
currentOption.updateRegistration(description, help, null, null);
|
||||
return;
|
||||
}
|
||||
Option option = new ThemeFontOption(optionName, fontId, description, help);
|
||||
valueMap.put(optionName, option);
|
||||
}
|
||||
|
||||
private Option getExistingComptibleOption(String optionName, OptionType type) {
|
||||
|
||||
// There are several cases where an existing option may exist when registering an option
|
||||
// 1) the option was accessed before it was registered
|
||||
|
|
|
@ -149,6 +149,32 @@ public interface Options {
|
|||
public void registerOption(String optionName, OptionType type, Object defaultValue,
|
||||
HelpLocation help, String description, PropertyEditor editor);
|
||||
|
||||
/**
|
||||
* Registers a theme color as an option. Doing this allows the color to be edited in the
|
||||
* options Gui, but all changes result in a theme change and not an options change. In other
|
||||
* words, changes to this option causes a theme change and is saved to a theme instead of in
|
||||
* the tool with normal options
|
||||
* @param optionName the option name to bind to a theme color id
|
||||
* @param colorId the theme color id to be affected if a users changes this color option
|
||||
* @param help the {@link HelpLocation} for more information on how this color is used
|
||||
* @param description a short description of how this color is used
|
||||
*/
|
||||
public void registerThemeColorOption(String optionName, String colorId, HelpLocation help,
|
||||
String description);
|
||||
|
||||
/**
|
||||
* Registers a theme font as an option. Doing this allows the font to be edited in the
|
||||
* options Gui, but all changes result in a theme change and not an options change. In other
|
||||
* words, changes to this option causes a theme change and is saved to a theme instead of in
|
||||
* the tool with normal options
|
||||
* @param optionName the option name to bind to a theme font id
|
||||
* @param fontId the theme font id to be affected if a users changes this font option
|
||||
* @param help the {@link HelpLocation} for more information on how this font is used
|
||||
* @param description a short description of how this font is used
|
||||
*/
|
||||
public void registerThemeFontOption(String optionName, String fontId, HelpLocation help,
|
||||
String description);
|
||||
|
||||
/**
|
||||
* Register the options editor that will handle the editing for all the options or a sub group of options.
|
||||
* @param editor the custom editor panel to be used to edit the options or sub group of options.
|
||||
|
|
|
@ -92,6 +92,18 @@ public class SubOptions implements Options {
|
|||
options.registerOption(prefix + optionName, type, defaultValue, help, description, editor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerThemeColorOption(String optionName, String colorId, HelpLocation help,
|
||||
String description) {
|
||||
options.registerThemeColorOption(prefix + optionName, colorId, help, description);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerThemeFontOption(String optionName, String fontId, HelpLocation help,
|
||||
String description) {
|
||||
options.registerThemeFontOption(prefix + optionName, fontId, help, description);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putObject(String optionName, Object obj) {
|
||||
options.putObject(prefix + optionName, obj);
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.framework.options;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
import generic.theme.Gui;
|
||||
import ghidra.util.HelpLocation;
|
||||
|
||||
/**
|
||||
* Options implementation for theme color options. A ThemeColorOption is an option that, when
|
||||
* changed, affects the current theme and is saved in the theme, instead of being saved with
|
||||
* normal non-theme related options.
|
||||
*/
|
||||
public class ThemeColorOption extends Option {
|
||||
|
||||
private String colorId;
|
||||
|
||||
public ThemeColorOption(String optionName, String colorId, String description,
|
||||
HelpLocation help) {
|
||||
super(optionName, OptionType.COLOR_TYPE, description, help, null, true, null);
|
||||
this.colorId = colorId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getCurrentValue() {
|
||||
return Gui.getColor(colorId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doSetCurrentValue(Object value) {
|
||||
Gui.setColor(colorId, (Color) value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDefault() {
|
||||
return !Gui.isChangedColor(colorId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restoreDefault() {
|
||||
Gui.restoreColor(colorId);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.framework.options;
|
||||
|
||||
import java.awt.Font;
|
||||
|
||||
import generic.theme.Gui;
|
||||
import ghidra.util.HelpLocation;
|
||||
|
||||
/**
|
||||
* Options implementation for theme font options. A ThemeFontOption is an option that, when
|
||||
* changed, affects the current theme and is saved in the theme, instead of being saved with
|
||||
* normal non-theme related options.
|
||||
*/
|
||||
public class ThemeFontOption extends Option {
|
||||
|
||||
private String fontId;
|
||||
|
||||
public ThemeFontOption(String optionName, String fontId, String description,
|
||||
HelpLocation help) {
|
||||
super(optionName, OptionType.FONT_TYPE, description, help, null, true, null);
|
||||
this.fontId = fontId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Font getCurrentValue() {
|
||||
return Gui.getFont(fontId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doSetCurrentValue(Object value) {
|
||||
Gui.setFont(fontId, (Font) value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDefault() {
|
||||
return !Gui.isChangedFont(fontId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restoreDefault() {
|
||||
Gui.restoreFont(fontId);
|
||||
}
|
||||
|
||||
}
|
|
@ -24,7 +24,6 @@ import java.net.URL;
|
|||
import javax.swing.Icon;
|
||||
import javax.swing.ImageIcon;
|
||||
|
||||
import generic.Images;
|
||||
import generic.util.image.ImageUtils;
|
||||
import ghidra.util.Msg;
|
||||
|
||||
|
@ -123,6 +122,6 @@ public class IconProvider {
|
|||
}
|
||||
|
||||
private URL getDefaultUrl() {
|
||||
return ResourceManager.getResource(Images.BOMB);
|
||||
return ResourceManager.getResource(ResourceManager.BOMB);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,13 +15,13 @@
|
|||
*/
|
||||
package resources;
|
||||
|
||||
import java.awt.Image;
|
||||
import java.awt.MediaTracker;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -30,7 +30,6 @@ import javax.swing.*;
|
|||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import generic.Images;
|
||||
import generic.theme.GIcon;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.util.Msg;
|
||||
|
@ -48,15 +47,17 @@ import utility.module.ModuleUtilities;
|
|||
* as opposed to using the flawed constructor {@link ImageIcon#ImageIcon(Image)}.
|
||||
*/
|
||||
public class ResourceManager {
|
||||
public final static String EXTERNAL_ICON_PREFIX = "[EXTERNAL]";
|
||||
private final static String DEFAULT_ICON_FILENAME = Images.BOMB;
|
||||
private static ImageIcon DEFAULT_ICON;
|
||||
private static Map<String, ImageIcon> iconMap = new HashMap<>();
|
||||
public static final String BOMB = "images/core.png";
|
||||
public static final String BIG_BOMB = "images/core24.png";
|
||||
public static final String EXTERNAL_ICON_PREFIX = "[EXTERNAL]";
|
||||
|
||||
private static final Map<String, ImageIcon> iconMap = new HashMap<>();
|
||||
|
||||
private static List<String> defaultSearchPaths;
|
||||
private static List<String> testSearchPaths;
|
||||
|
||||
private static ClassLoader classLoader = ResourceManager.class.getClassLoader();
|
||||
private static final ImageIcon DEFAULT_ICON = loadDefaultIcon();
|
||||
|
||||
/**
|
||||
* Finds a resource with a given name. This method returns null if no
|
||||
|
@ -441,26 +442,6 @@ public class ResourceManager {
|
|||
if (icon instanceof GIcon) {
|
||||
return ((GIcon) icon).getId();
|
||||
}
|
||||
|
||||
/*
|
||||
TODO - not sure why we wanted just the name and not the entire URL? Delete this
|
||||
after a bit
|
||||
|
||||
if (iconName == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int pos = iconName.lastIndexOf(File.separator);
|
||||
if (pos >= 0) {
|
||||
iconName = iconName.substring(pos + 1);
|
||||
}
|
||||
else {
|
||||
pos = iconName.lastIndexOf("/");
|
||||
if (pos >= 0) {
|
||||
iconName = iconName.substring(pos + 1);
|
||||
}
|
||||
}
|
||||
*/
|
||||
return iconName;
|
||||
}
|
||||
|
||||
|
@ -496,7 +477,7 @@ public class ResourceManager {
|
|||
if (loadImage == null) {
|
||||
return null;
|
||||
}
|
||||
return (ImageIcon) getScaledIcon(loadImage, width, height);
|
||||
return getScaledIcon(loadImage, width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -520,24 +501,43 @@ public class ResourceManager {
|
|||
return icon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the icon specified by iconPath. The iconPath can be either a path to a resource on
|
||||
* the classpath or a relative or absolute path to an icon on the file system. If the iconPath
|
||||
* is a path to a classpath resource, then it will be searched directly or also with an "images/"
|
||||
* prepended to the path. For example, if there exists an icon "home.gif" on the classpath that
|
||||
* was stored in the standard "images" resource directory, then it exists on the classpath
|
||||
* as "images/home.gif". That icon will be found if the iconPath is either "images/home.gif" or
|
||||
* just as "home.gif".
|
||||
*
|
||||
* @param iconPath name of file to load, e.g., "images/home.gif"
|
||||
* @return an Icon from the given iconPath or null, if no such icon can be found
|
||||
*/
|
||||
|
||||
public static Icon loadIcon(String iconPath) {
|
||||
ImageIcon icon = iconMap.get(iconPath);
|
||||
if (icon == null) {
|
||||
icon = doLoadIcon(iconPath);
|
||||
iconMap.put(iconPath, icon == null ? DEFAULT_ICON : icon);
|
||||
}
|
||||
|
||||
return icon == DEFAULT_ICON ? null : icon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the image specified by filename; returns the default bomb icon
|
||||
* if problems occur trying to load the file.
|
||||
*
|
||||
* @param filename name of file to load, e.g., "images/home.gif"
|
||||
* @param iconPath name of file to load, e.g., "images/home.gif"
|
||||
* @return the image icon stored in the bytes
|
||||
*/
|
||||
public static ImageIcon loadImage(String filename) {
|
||||
ImageIcon icon = iconMap.get(filename);
|
||||
public static ImageIcon loadImage(String iconPath) {
|
||||
ImageIcon icon = iconMap.get(iconPath);
|
||||
if (icon == null) {
|
||||
icon = doLoadIcon(filename);
|
||||
if (icon == null) {
|
||||
Msg.warn(ResourceManager.class, "Can't resolve icon: " + filename);
|
||||
icon = new UnresolvedIcon(filename, getDefaultIcon());
|
||||
}
|
||||
iconMap.put(filename, icon);
|
||||
icon = doLoadIcon(iconPath);
|
||||
iconMap.put(iconPath, icon == null ? DEFAULT_ICON : icon);
|
||||
}
|
||||
return icon;
|
||||
return icon == null ? new UnresolvedIcon(iconPath, DEFAULT_ICON) : icon;
|
||||
}
|
||||
|
||||
public static Set<Icon> getLoadedUrlIcons() {
|
||||
|
@ -551,7 +551,7 @@ public class ResourceManager {
|
|||
return icons;
|
||||
}
|
||||
|
||||
private static ImageIcon doLoadIcon(String path) {
|
||||
private static UrlImageIcon doLoadIcon(String path) {
|
||||
|
||||
// if the has the "external prefix", it is an icon in the user's application directory
|
||||
if (path.startsWith(EXTERNAL_ICON_PREFIX)) {
|
||||
|
@ -628,14 +628,6 @@ public class ResourceManager {
|
|||
}
|
||||
|
||||
public static ImageIcon getDefaultIcon() {
|
||||
if (DEFAULT_ICON == null) {
|
||||
URL url = getResource(DEFAULT_ICON_FILENAME);
|
||||
if (url == null) {
|
||||
Msg.error(ResourceManager.class,
|
||||
"Could not find default icon: " + DEFAULT_ICON_FILENAME);
|
||||
}
|
||||
DEFAULT_ICON = new UrlImageIcon(DEFAULT_ICON_FILENAME, url);
|
||||
}
|
||||
return DEFAULT_ICON;
|
||||
}
|
||||
|
||||
|
@ -645,6 +637,16 @@ public class ResourceManager {
|
|||
return list;
|
||||
}
|
||||
|
||||
private static ImageIcon loadDefaultIcon() {
|
||||
URL url = getResource(BOMB);
|
||||
if (url != null) {
|
||||
return new UrlImageIcon(BOMB, url);
|
||||
}
|
||||
Msg.error(ResourceManager.class,
|
||||
"Could not find default icon: " + BOMB);
|
||||
return getImageIcon(new ColorIcon3D(Color.RED, 16, 16));
|
||||
}
|
||||
|
||||
private static void filterImages(Set<String> set) {
|
||||
Iterator<String> it = set.iterator();
|
||||
while (it.hasNext()) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue