Wednesday, August 10, 2011

NetBeans JFrame Properties: iconImage

In NetBeans 7.0.1 and 6.9.1, the routine to a custom JFrame icon is not straight forward.

There are two ways to set a JFrame icon in NetBeans. Under "JFrame Properties" there are two properties listed called "iconImage" and "iconImages".

By default, the iconImage property is set to <none> and the iconImages property is set to <default>. If you click on the ellipsis (...), you will see a dialog box that indicates that: "Custom editing of this property is not supported."

What to do next?

There are three different ways to do this. The first and easiest way is to add code to the constructor after initComponents() of the JFrame. The code below shows this added to the constructor. (If you are concerned about leaking the this reference in the constructor, you can call the method after the EDT returns from the constructor.)


public MyFrame() {
    initComponents();
    this.setIconImage(new ImageIcon(getClass()
                    .getResource("/<resource_path>" + "/image.png")).getImage());
}


The second way is basically the same, but you enter the code for setIconImage() in the JFrame's Properties form. This will put the code in the NetBean's generated code block. To do this, click the ellipsis button next to iconImage in the Properties form and choose Custom Code. Then type in the same argument as shown in the setIconImage() method in the constructor code above. See the image below.




The third way is to override the method the frame uses to get the resource. The Java API specifications indicates the Frame.getIconImage() is obsolete and the Windows.getIconImages() method should be used. This restricts us to using the iconImages property. Which is fine with me, why have 2 different ways to do the same way? To use Windows.getIconImages() (inherited by JFrame), we must set it in the iconImages property. First, we must override Windows.getIconImages() and write a method for retrieving and returning a List object from it. See code below.

// MyFrame.java

import java.awt.Image;
import java.util.ArrayList;
import java.util.List;

public class MyFrame extends javax.swing.JFrame {
  
  . . .
 
  @Override
  public List<Image> getIconImages() {
    ArrayList<Image> imageList = new ArrayList();
    imageList.add(getClass().getResource("/<resource_path>" +
         "/image.png")).getImage());
    return imageList;
  }
  
  . . .
  
  /** This method is called from within the constructor to
  * initialize the form.
  * WARNING: Do NOT modify this code. The content of this method is
  * always regenerated by the Form Editor.
  */
  @SuppressWarnings("unchecked")
  // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
  private void initComponents() {
  
  . . .

  setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
  setTitle("Title");
  setIconImages(getIconImages());
  setResizable(false);

  . . .

}// <editor-fold>

Now we click the ellipsis for imageIcons and choose "Set Form's iconImages property using: Value from existing component". Then select "Method Call:" and click the ellipses button. Then choose Form and the getIconImages() method. See images below.



Now your icon will show up on the upper left corner of the JFrame.

Actually, if we leave the iconImages property left at <default> it will still work because the default behavior is to use getIconImages() to load the default Java icon. This is overridden to load the custom image, but getIconImages() will not show in the NetBeans generated code this way.

Warning: If you choose to use the obsolete property iconImage, the JFrame property iconImages must be set to <default> or NetBeans sets Frame.setIconImage(null) no matter what setting you use for the iconImage property. Leave iconImages set to <default>. If you inadvertently change it to <none> then click the ellipsis button and then click the "Reset to Default" button.

1 comment: