Java图标常量-静态常量可以吗?

Java图标常量-静态常量可以吗?,java,icons,constants,Java,Icons,Constants,我在一个应用程序中使用了许多图标——让我们以确定/取消图标为例。目前,它们可能是一个勾号和一个叉号(tick.png,cross.png),但我可能想在将来替换它们。另外,我希望将资源路径保留在一个位置 这样行吗: public class Icons { public static Icon OK = new ImageIcon(Icons.class.getResource("/icons/tick.png"); public static Icon CANCEL = new

我在一个应用程序中使用了许多图标——让我们以确定/取消图标为例。目前,它们可能是一个勾号和一个叉号(tick.png,cross.png),但我可能想在将来替换它们。另外,我希望将资源路径保留在一个位置

这样行吗:

public class Icons {
    public static Icon OK = new ImageIcon(Icons.class.getResource("/icons/tick.png");
    public static Icon CANCEL = new ImageIcon(Icons.class.getResource("/icons/cross.png");
}
或者我应该用另一种方式来做?我不介意在运行时依赖映像文件的存在,因为它们在.jar中

解决方案

我使用了Bent的想法进行初始化,并最终确定了常数:

public final class Icons {
    private static final Logger logger = Logger.getLogger(Icons.class);

    public static final Icon OK = icon("/icons/add.png");
    public static final Icon CANCEL = icon("/icons/cancel.png");

    private static Icon icon(String path) {
        URL resource = Icons.class.getResource(path);
        if(resource==null) {
            logger.error("Resource "+path+" does not exist");
            return new ImageIcon();
        }
        return new ImageIcon(resource);
    }
}

您可能希望将常量标记为final。

这似乎是一种相当简单的方法。虽然我会用与它们的名称相同的名称来命名这些图像(“ok.png”、“cancel.png”)。并确保删除或重命名图像可能会导致问题。我发现有两个问题,这两个问题都可以接受:

  • 如果您的图标找不到或由于某些原因无法加载,调试将变得很困难。在静态初始值设定项中运行的代码可能很棘手,因为很容易“释放”异常
  • 该类可能永远不会被卸载,因此图标使用的资源永远不会被释放
  • 如果您可以确保图标始终存在,甚至可以通过将初始化放在静态初始值设定项块中并添加良好的异常处理和日志记录来处理图标,那么1可能是可以接受的

    第2个可能是可以接受的,因为图标通常在应用程序的整个运行时使用,并且在应用程序退出之前,它们不会被释放


    总而言之,我认为这很好。

    如果您想将图标保持为静态常量,我会将ImageIcon对象的实例化提取到一个静态方法中

    public static final Icon ok = icon("ok.png");
    
    
    private static Icon icon(String path) {
    
        URL resource = Icons.class.getResource("/icons/" + path);
        if (resource == null) {
            // Log something...
            return null;
        }
        return new ImageIcon(resource);
    }
    
    通过这种方式,您可以在出现故障时进行控制,并且不必在实例化中重复自己

    此外,我将使常数为最终值


    一种更通用的方法是使用反射来检查Icons类,并为类中的每个公共静态Icon字段加载资源。这样,您只需声明一个新的图标常量,相应的资源将根据常量的名称自动加载。如果你想要更多的提示,请留下评论。

    这似乎是做事情的标准方式,但我以前遇到过一些问题

    如果您将Eclipse与Maven一起使用,并将这些图标存储在Maven的资源目录中,那么当Eclipse执行其自动构建时,它不会将图标文件复制到目标/类目录中。当找不到图标时,这将导致运行时异常


    您必须至少手动执行一次maven程序包,才能将图标放在正确的位置。

    OK和CANCEL应为Icon类型,而不是ImageIcon类型。没有必要将ImageIcon作为其公共契约的一部分公开。这是一个很好的观点——这就是我快速键入示例所得到的!FixedI是这样的,尽管a)它可能应该返回图标而不是ImageIcon,b)返回空图标可能比返回空图标更好。反射?讨厌。enum会更好。如果我们有“抽象枚举”,那将非常有用。我不使用(或不喜欢)Eclipse或Maven,所以这不是问题。不管怎么说,这是一个工具问题,所以如果我遇到这样的问题,我会倾向于修复工具。有用的提示。