Interfaces and Implementation in Java
An icon in Java GUI is represented by an object of type Icon, and Icon is an interface rather than a class.
Pictures in a Graphical Interface
Buttons, labels, and menus in a Java graphical interface often display small pictures alongside their text. Those pictures are not simply dropped onto a component. Java expects the picture to be wrapped in a particular kind of object first, and the GUI then knows how to display that 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?
Before reading on, decide: if a button should show a small picture, do you think you hand the picture straight to the button, or does Java need an intermediate object first?
Reveal answer
Wrap the picture in an intermediate object first
Java expects the picture to be wrapped in a particular kind of object, and the GUI then knows how to display that wrapped object.
Two Roles: Icon and ImageIcon
The name Icon refers to a type that describes what an icon is in a Java GUI. The name ImageIcon refers to a class that provides an actual icon built from a picture. Keeping these two roles separate is the key to reading icon code. The type Icon is the general description; ImageIcon is one concrete way of satisfying that description.
An interface such as Icon describes what an object must be able to do, while a class such as ImageIcon provides the actual object that does it. The class is said to implement the interface.
Read the diagram from the bottom up: ImageIcon is the concrete class, and the arrow labeled implements points to the interface it satisfies. Icon itself is the description, not a thing you build a picture from directly.
Why Declare the Variable as Icon
Because ImageIcon implements the Icon interface, an ImageIcon object can be stored in a variable whose declared type is Icon. This is the usual reason a programmer writes the more general type on the left of a declaration. The variable promises only that it holds something that behaves as an icon, and the specific class behind it can be chosen separately.
- Icon on the left is the declared type: the promise the variable makes
- ImageIcon after new is the class of the object actually created
- image is an Image object that already holds the picture
Tracing an Image into an ImageIcon
Work through the process step by step. 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.
Turning a picture into an icon
You already have an Image object named image that holds a picture. Create an icon from it and store the result in a variable whose declared type is Icon.
- 1Start with the Image
The picture already exists as an Image object named image. Creating the icon does not require drawing anything yet.
- 2Call the ImageIcon constructor
Write new
ImageIcon(image). The constructor receives the Image and wraps it, so the new object's picture is the image you supplied. - 3Store the result in an Icon variable
Assign the new object to a variable declared as Icon. This works because ImageIcon implements the Icon interface.
The variable icon refers to an ImageIcon object whose picture is image, and it can be used anywhere an Icon is expected.
- The line creating image is left as a placeholder: the Image may be read from a resource file, which later examples in the chapter cover
- The constructor only wraps the image; it does not load it
Where the Icon Reference Sits
After the statement Icon icon = new ImageIcon(image) runs, the variable icon holds a reference to the ImageIcon object. The variable is the name you use in code; the ImageIcon object is the thing that carries the picture. The variable's declared type limits which operations you may call through it, while the object itself remains an ImageIcon.
Notice what the diagram does not show: the exact location of the object in memory. For this article, what matters is the relationship. The variable reaches the object through a reference, and the object is the ImageIcon that holds the picture.
Mistakes with Icon Declarations
Most errors with icons come from mixing up the interface and the class. The following mistakes are the ones to watch for when reading or writing this code.
Common mistake Creating an object directly from the interface name
What it looks likeIcon icon = new Icon(image);Why it failsIcon is an interface, a description of what an icon is. It does not provide a constructor that builds a picture, so you cannot create an object from it with new.
Do this insteadCreate the object from a class that implements Icon, such as ImageIcon: Icon icon = new ImageIcon(image);Common mistake Thinking the declared type and the created class must match
What it looks likeBelieving that Icon icon = new ImageIcon(image) is wrong because the names differ.
Why it failsThe variable's declared type only promises behavior. ImageIcon implements Icon, so an ImageIcon object is allowed in an Icon variable.
Do this insteadRead the left side as the promise and the right side as the actual class. Both can be correct at once.
Common mistake Assuming the constructor loads the picture from a file
What it looks likeExpecting new ImageIcon(image) to find and open a file by itself.
Why it failsThe constructor only wraps an Image that already exists. The Image may be read from a resource file, but that is a separate job.
Do this insteadMake the Image first, then pass it to new ImageIcon(image).
| Line | Works? | Reason |
|---|---|---|
| Icon icon = new ImageIcon(image); | Yes | ImageIcon is a class that implements Icon, so its object fits an Icon variable |
| Icon icon = new Icon(image); | No | Icon is an interface and cannot be used to create an object with new |
| ImageIcon icon = new ImageIcon(image); | Yes | The declared type matches the created class exactly |
Comparing valid and invalid icon declarations
Reading Icon Code Yourself
A line in a program reads: Icon badge = new ImageIcon(logo); where logo is an Image object. Explain, in your own words, which type the variable badge promises, which class creates the object, and what the constructor call receives and returns.
Hints
- Identify the declared type on the left of the assignment first
- Find the word after new: that names the class of the object actually created
- The argument logo is the Image; the result is the ImageIcon whose picture is logo
Suppose a different class named ArrowIcon also implements Icon. Explain why code that declares a variable as Icon and only calls operations promised by Icon could accept either an ImageIcon or an ArrowIcon without changing.
Hints
- Think about what the declared type promises the code will rely on
- The specific class behind the variable can be chosen separately
Key Takeaways
- An icon in Java GUI is represented by the type Icon, which is an interface describing what an icon is rather than a class you build directly.
- ImageIcon is a class that implements Icon and creates an actual icon from an Image object through the constructor call new
ImageIcon(image). - Because ImageIcon implements Icon, an ImageIcon object can be stored in a variable declared as Icon, and the specific class can be chosen separately from the declared type.
- Loading an image and wrapping an image are separate jobs; the constructor handles only the wrapping, and creating an object directly from the interface name is an error.