如何方便Netbeans Designer使用hashmap加载使用枚举反向查找的JPanel? [英] How to facilitate Netbeans Designer to load JPanel-s that use an enum reverse-lookup using hashmap?

查看:211
本文介绍了如何方便Netbeans Designer使用hashmap加载使用枚举反向查找的JPanel?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个多萝西·迪克斯,当我发现事情的根源时撰写这个问题不过,我决定发布它,因为它让我们办公室里的每个人都陷入僵局,我可以在google或stackoverflow搜索中找不到任何帮助。这是一个很好的例子,一旦你提出正确的问题,你可能会看到光。



虽然标题可能听起来很复杂,一个似乎没有答案的真正简单的问题。这个中心是一个枚举



状态

  public enum Status 
{
INVALID(INVALID ,
ISSUED(发行),
取消(已取消);

private final String displayName;

private final static Map< String,Status> displayMap = new HashMap(4);


私人状态(字符串显示){
this.displayName = display;
mapDisplayName(this.displayName,this);
}


public String getDisplayName(){
return displayName;
}

public static状态parseString(String statusStr){
return displayMap.get(statusStr);
}

private static void mapDisplayName(final String displayName,final Status state){
displayMap.put(displayName,state);
}
}

当然的想法是使用 displayMap 作为反向查找。与$ getDisplayName()方法无关。



此枚举的 getDisplayName( )调用在子面板中用于初始化与组合框一起使用的静态数组,例如:

  public class JPanelStatus extends javax.swing.JPanel {

private final String [] STATUS_LABELS = {
Status.ISSUED .getDisplayName(),
Status.CANCELLED .getDisplayName()
};

public JPanelStatus(){
initComponents();

jComboBoxStatus.setModel(new DefaultComboBoxModel<>(STATUS_LABELS));

}

}

其中在主要的JPanel中引用。当我在Netbeans Designer中查看这个 JPanelStatus 子面板时,工作正常。但是,当我加载主窗体时,它会失败,并且异常(例如,预览设计]功能



显示初始化失败:

  java.lang.NoClassDefFoundError:无法初始化类au.com.project.State 
在au.com.project.client.JPanelStatus。< init>(JPanelStatus.java:35)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance (NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
在java.lang.reflect.Constructor.newInstance(Constructor.java:423)
... ...

Netbeans IDE日志添加了以下额外信息: p

 信息:无法初始化类au.com.project.State 
/ pre>

通过一个消除过程 - Co发布不相关的代码 - 一旦我在State枚举中注释了HashMap put()调用,我发现表单将加载。



这很有趣。我说。它看起来像一个副作用,从 put()。而离开它是 - 一个小的 Spock ,它很快给了我一样的错误从没有JPanel和没有Netbeans的命令行。



错误是由我造成的,尝试从Enum构造函数中使用HashMap。它不会写成。



所以我改变了标题来命中真正的问题 - 实际上,如何使用HashMap对枚举进行反向查找?

解决方案

问题来自于HashMap如何在 Status 枚举中声明如何初始化枚举。



Java枚举中的第一件事必须是值列表,如下所示:INVALID,ISSUED和CANCELED。每个人都需要知道的是,在对象创建(Class或Enum)期间,首先运行的是一个 Java 。 Init是愚蠢的,通过声明性代码线性运行,先到先得。



枚举的前3个x语句调用构造函数 - 这意味着语句:

  private final static Map< String,Status> displayMap = new HashMap(4); 

尚未执行, displayMap null 。另外,一个 static {} 块在相同的1-2-3 -...序列中执行,也不起作用。



遗憾的是,Netbeans / Designer堆栈跟踪或IDE日志都没有报告NullPointerException - 单元测试。一旦你有一个NPE,它集中精神。



解决方案:displayMap displayMap 在初始构造函数调用时未初始化不能 static final ,因为您不能在构造函数中初始化静态成员。必须在第一次通话时使用以下示例中的一些变体来初始化:



状态 / strong>

  public enum Status 
{
INVALID(INVALID),
发行(已发行),
取消(已取消);

private static Map< String,Status> displayMap;

私人状态(字符串显示){
this.displayName = display;
mapDisplayName(this.displayName,this);
}


private static void mapDisplayName(final String displayName,final Status state){
if(null == displayMap){
displayMap =新的HashMap(7);
}
displayMap.put(displayName,state);
}
}

然后它运行顺利。



警告



不要分配 null 在displayMap声明 - 这是有效的:




  • 如果(null == displayMap)在第一次调用Enum构造函数时,{...} 块成功分配了HashMap。

  • 在处理所有枚举值声明之后。
  • Init将为声明的变量调用任何初始化。

  • 如果 displayMap = null; 被声明它将替换使用新的空HashMap填充HashMap,带有3个x值。



可能相关问题:




This has become a Dorothy Dix as I found the root of the matter while I was composing this question. Nevertheless, I decided to post it because it had everyone in our office stumped and I could find nothing helpful in the google or stackoverflow searches. This is a good example of once you ask the right question, you may see the light.

While the title might sounds complicated, it is a really simple problem that seemed to have no answer. At the centre of this is an enum:

Status

    public enum Status 
    {
        INVALID     ( "INVALID"  ),
        ISSUED      ( "Issued"   ),
        CANCELLED   ( "Cancelled");

        private final   String displayName;

        private final static    Map<String,Status>    displayMap = new HashMap( 4 );


        private Status( String display  ){
            this.displayName = display;
            mapDisplayName( this.displayName, this );
        }


        public String getDisplayName(){
            return displayName;
        }

        public static Status parseString( String statusStr ) {
            return displayMap.get(  statusStr );
        }

        private static void mapDisplayName( final String displayName, final Status state ){
            displayMap.put( displayName,  state );
        }
    }

The idea of course is to use the displayMap as a reverse-lookup. Nothing to do with the getDisplayName() method at all.

This enum's getDisplayName() call is used in a sub-panel to initialise a static array used with a combobox, like:

    public class JPanelStatus extends javax.swing.JPanel { 

        private final       String[]    STATUS_LABELS = {
                                            Status.ISSUED     .getDisplayName(),
                                            Status.CANCELLED  .getDisplayName()
                                        };

        public JPanelStatus(){
            initComponents();
              :
            jComboBoxStatus.setModel( new DefaultComboBoxModel<>( STATUS_LABELS ) );
              :
        }
       :
    }

Which is referenced in the main JPanel. When I view this JPanelStatus sub-panel in the Netbeans Designer, it works fine. As does the [Preview Design] function.

However when I load the main form, it fails and the exception show an initialisation failure:

  java.lang.NoClassDefFoundError: Could not initialize class au.com.project.State
    at au.com.project.client.JPanelStatus.<init>(JPanelStatus.java:35)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
  ... ... ...

The Netbeans IDE log added the following extra information :-p

INFO: Could not initialize class au.com.project.State

Through a process of elimination -- Commenting-out unrelated code -- I discovered the form will load once I comment-out the HashMap put() call in the State enum.

"That is interesting.", I say. It looked like a side-effect from the put(). And in away it is -- A small Spock which quickly gave me the same error from the command line without the JPanel and without Netbeans.

The error is caused by me, trying to use a HashMap from within the Enum constructor. It won't work as written.

So I changed the title to hit at the true problem -- Which is actually, how to use a HashMap to do a reverse-lookup for an enum?

解决方案

The problem comes from how the HashMap is declared within the Status enum due to HOW enums are initialised.

The first thing in a Java Enum must be the list of values, here: "INVALID", "ISSUED", and "CANCELLED". The next thing everyone needs to know is that there is a secret Java stage that runs first during Object creation (Class or Enum). Init is dumb, is runs linearly through the declarative code first-come, first-served.

The first 3 x statements of an enum call the constructor -- That means the statement:

    private final static  Map<String,Status>  displayMap = new HashMap( 4 );

Has NOT yet been executed, and displayMap is null. Also, a static { } block is executed in that same 1-2-3-... sequence and does not work either.

Unfortunately none of the Netbeans/Designer stack-trace or IDE log reported a NullPointerException -- The unit test does. Once you have a NPE, it focuses the mind. displayMap is uninitialised when the first constructor call is made.

Solution: The displayMap cannot be static final, because you may not initialise static members in a constructor. It must be initialised on the first call, using some variation of the example shown:

Status

    public enum Status
    {
        INVALID     ( "INVALID"  ),
        ISSUED      ( "Issued"   ),
        CANCELLED   ( "Cancelled");

        private static    Map<String,Status>   displayMap;

        private Status( String display  ){
            this.displayName = display;
            mapDisplayName( this.displayName, this );
        }
          :

        private static void mapDisplayName( final String displayName, final Status state ){
            if( null ==  displayMap  ){
                displayMap = new HashMap( 7 );
            }
            displayMap.put( displayName,  state );
        }
    }

And then it all runs quite smoothly.

Caveat:

Do NOT assign null in the displayMap declaration -- That was counter productive:

  • The if( null == displayMap ){...} block successfully assigns the HashMap during the first call to the Enum constructor.
  • After all the enum values declarations are processed.
  • Init will call any initialises for declared variables.
  • If displayMap = null; is declared it replaces the populated HashMap, with 3 x values, with a new empty HashMap. grrr

Possibly related question:

这篇关于如何方便Netbeans Designer使用hashmap加载使用枚举反向查找的JPanel?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆