Concepts / Image I/O in Java

Image I/O in Java

An icon in Java GUI is represented by an object of type Icon, and Icon is an interface rather than a class.

  • Programming

A Picture on a Button

Buttons, labels, and menus in a Java graphical interface often show a small picture next to their text. That picture is not simply dropped onto the component. Java expects the picture to be wrapped in a particular kind of object first, and then the graphical interface knows how to display that wrapped object. This article follows that wrapping step from start to finish, so you can see which piece of code is responsible for what.

What do you think happens?

Assume image is already an Image object. Which of these lines compiles without error?

  • Icon a = new Icon(image);

  • ImageIcon b = new Icon(image);

  • Icon c = new ImageIcon(image);

Reveal answer
Answer:

Only the third line, Icon c = new ImageIcon(image);, compiles.

Icon is an interface, and an interface cannot be created directly with new. The second line tries to store a general Icon into a variable of the more specific type ImageIcon, which is not allowed without a specific cast. The third line creates an ImageIcon, and an ImageIcon can be stored in a variable of type Icon because ImageIcon implements that interface. You will trace the reasons in the sections below.

Icon as a Description, Not a Recipe

Definition

An icon in a Java GUI is represented by an object of type Icon. Icon is an interface, not a class. An interface describes what a type promises to provide, and it does not itself say how that promise is kept.

The name Icon refers to a type that describes what an icon is in a Java GUI. It is the general description. Because it is a general description, the name Icon by itself does not tell you how a particular icon is built from a picture. A programmer who declares a variable as Icon is saying that the variable will hold something that behaves as an icon. The specific object behind it can be chosen separately.

This separation is why the general type appears on the left of many declarations. The variable promises only that it holds an icon-like object. The code that decides which concrete class to use can change without changing the declared type of the variable. This is a common reason to prefer writing the interface name in a declaration rather than the concrete class name.

Tracing an Image Into an Icon

Creating an icon from a picture happens in four steps. First, you have an Image object, which holds a picture. Second, you pass that image to the constructor of ImageIcon by writing new ImageIcon(image). Third, Java produces an ImageIcon object whose picture is the image you supplied. Finally, you can store that result in a variable of type Icon, because ImageIcon implements the interface.

java
Image objectholds the picturenew ImageIcon(image)constructor callImageIcon objectpicture is the suppliedimageIcon variabledeclared type Iconpassed inproducesstored as
What happens step by step when the Image is passed to the ImageIcon constructor, and what does the resulting object hold?
Worked example

Turning a picture into an icon for a button

You already have an Image object named logo. You want a variable that can be used anywhere the GUI expects an icon. Show how the logo becomes an icon.

  1. 1
    Start with the picture

    The Image object logo already holds the picture. Loading it is a separate job and is not part of this step.

  2. 2
    Call the constructor

    Write new ImageIcon(logo). This passes the picture to the ImageIcon constructor.

  3. 3
    Receive the ImageIcon

    Java produces an ImageIcon object whose picture is logo. Store it as ImageIcon wrapped = new ImageIcon(logo);.

  4. 4
    Widen the declared type

    Assign the result to Icon icon = wrapped; or directly Icon icon = new ImageIcon(logo);. The variable now promises only that it holds an icon.

Result

The variable icon refers to an ImageIcon object whose picture is logo. Its declared type is Icon, which is the general description.

Declared Type Versus Created Object

The class ImageIcon implements the Icon interface. That relationship has two sides. The interface Icon is the contract: it describes what an icon is. The class ImageIcon is the concrete implementation: it is one specific way of satisfying that contract, built from a picture. Because ImageIcon implements Icon, an ImageIcon object can be stored in a variable whose declared type is Icon.

Iconinterface: the contractImageIconclass: concreteimplementationimplements
How does ImageIcon sit under the Icon interface, and which part of the relationship is the contract and which part is the concrete implementation?

When a variable is declared as Icon but refers to an ImageIcon object, the object that actually exists in memory is the ImageIcon. The variable's declared type limits what you can rely on through that variable. You can use the operations that the Icon type promises. The variable does not change the object itself, and it does not reveal that the object was built from an Image unless you check its class. The specific class is chosen when the object is created, and it stays the same object behind the general name.

Mistakes When Declaring and Creating Icons

  • Common mistake

    Creating an Icon directly with new

    What it looks like
    Icon a = new Icon(image);
    Why it fails

    Icon is an interface, and an interface describes a type without being a class you can instantiate. The line does not compile because there is no concrete object to create.

    Do this instead
    Create a concrete class that implements Icon, such as ImageIcon, and then assign it: Icon a = new ImageIcon(image);
  • Common mistake

    Declaring the more specific type from a general type

    What it looks like
    ImageIcon b = new Icon(image);
    Why it fails

    This tries to create an Icon, which is not allowed because Icon is an interface. Even apart from that, the declared type ImageIcon is more specific than the Icon that would be created.

    Do this instead
    Use the concrete class on both sides when you need that exact type: ImageIcon b = new ImageIcon(image);
  • Common mistake

    Confusing the constructor call with loading the picture

    Why it fails

    The constructor new ImageIcon(image) only wraps an Image that already exists. Expecting it to read the picture from a file is a mismatch between the two separate jobs.

    Do this instead

    Make sure the Image object exists first, then pass it to the constructor. Loading the image is handled separately.

  • Common mistake

    Forgetting that the declared type limits which methods you can call through the variable

LineCompiles?Reason
Icon a = new Icon(image);NoIcon is an interface and cannot be created with new
ImageIcon b = new Icon(image);NoAn Icon cannot be created, and the types do not match
Icon c = new ImageIcon(image);YesImageIcon implements Icon, so an ImageIcon can be stored as an Icon

Three declaration and creation lines compared

Practice Tracing Icon Code

EASY

You have an Image object named photo. Write the one line that creates an ImageIcon from photo and stores it in a variable named badge whose declared type is Icon. Then explain in one sentence why the declared type Icon is allowed on the left.

Hints
  • Use the constructor call new ImageIcon(photo) on the right side.
  • Remember that ImageIcon implements the Icon interface, so an ImageIcon can be stored in a variable of type Icon.
  • Expected line: Icon badge = new ImageIcon(photo);

Key Takeaways

  • An icon in a Java GUI is represented by an object of type Icon, and Icon is an interface rather than a class.
  • ImageIcon is a class that implements Icon, so an ImageIcon object can be stored in a variable whose declared type is Icon.
  • The constructor call new ImageIcon(image) takes an existing Image object and produces an ImageIcon whose picture is that image.
  • Creating an icon is the wrapping step only; loading the Image from a source such as a resource file is a separate job.
  • An interface such as Icon cannot be created directly with new, so the object must be created from a concrete class.