Monday, January 26, 2009

Loading and Displaying an Image in Java

Here's a common task--loading an image file and displaying it in a window.

I'll be using this program as a basis for further two dimensional graphics exercises, so give it a try and play around with it.

First, we need to get a picture to use. I use a picture of Duke, the Java mascot, from https://duke.dev.java.net/images/web/Duke_Blocks.gif

If you want to run the program as I present it, download the image and save it into the same directory that yor java program will be in. If you want to use your own image, replace the file name Duke_Blocks.gif with the name of your image file, and make sure the image is in the same directory as your java program.

The only somewhat tricky part is that we're using a Toolkit method to get the image. Take a look at the Java API reference to learn more about the Toolkit. (The Toolkit object is part of the java.awt package. So select "java.awt" in the top left frame of the API reference webpage to make finding Toolkit in the lower left frame easier.)

In this program, we scale and position the image in our window. In future programs, we'll convert the image to a Java2D object (which is really easy) so that we can do other things, like rotate it and use it as a sprite.

Here's the program:
/* ShowImage.java

  This program loads and displays an image from a file.

  mag-13May2008
  updated 20Feb2009 by mag to incorporate suggestions
  by mazing and iofthestorm on digg.
*/

// Import the basic graphics classes.
import java.awt.*;
import javax.swing.*;

public class ShowImage extends JPanel{
  Image image; // Declare a name for our Image object.

// Create a constructor method
  public ShowImage(){
   super();
   // Load an image file into our Image object.
   // This file has to be in the same
   // directory as ShowImage.class.
   image = Toolkit.getDefaultToolkit().getImage("Duke_Blocks.gif");
  }

// The following methods are instance methods.

/* Create a paintComponent() method to override the one in
JPanel.
This is where the drawing happens.
We don't have to call it in our program, it gets called
automatically whenever the panel needs to be redrawn,
like when it it made visible or moved or whatever.
*/
  public void paintComponent(Graphics g){

   // Draw our Image object.
   g.drawImage(image,50,10,200,200, this); // at location 50,10
     // 200 wide and high
  }

  public static void main(String arg[]){
   JFrame frame = new JFrame("ShowImage");
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   frame.setSize(600,400);

   ShowImage panel = new ShowImage();
   frame.setContentPane(panel);
   frame.setVisible(true);
  }
}
StumbleUpon

Tuesday, January 13, 2009

Listeners: Can Java Hear You?

In the program given in Simple Mouse Interaction in Java we used a Listener to connect our program to the mouse. We were able to use the Listener to find out when and where the mouse had been clicked within our program's window. We used this information to draw lines in the window, in a similar fashion to our earlier programs but controlled by the mouse, rather than from specific drawing instructions in the program that do the same thing every time you run the program.

By implementing the MouseListener interface, we were able to talk to the mouse very easily. However, a MouseListener is just one of the many types of Listener available in Java.

What Sort of Listener Are You?


If we tried to implement a full graphical interface in a program by using MouseListener, we'd have a lot of work to do. We'd have to draw all the buttons using drawing instructions in our program, then wait for mouse clicks. Once we got a click on something we'd have to figure out what had been clicked on by the location of the click in our window. Then we'd have to redraw the button (or slider, or whatever) to show that it had been clicked. Then we'd have to continue responding to the mouse by figuring out what the user is doing (clicking and releasing, clicking and dragging, or what) and make our program and the picture on the screen respond appropriately.

Whew! What a lot of work that would be! If we had to do that it'd almost be enough to drive you back to the command line. (Once upon a time you did have to do all that, believe it or not. Thank goodness those days are gone.)

Fortunately, Java has a number of different types of Listener suited for different tasks that take care of the complexity for you, and let your program do what you want it to do without you having to spell out every little detail. There are listeners for buttons, sliders and other controls such as trees, lists, focus changes, and so on. You can also write your own Listeners, so that you can create a new type of control and only ever have to deal with the inner complexities of how it works once.

What is a Listener?

A Listener is a connection between your program and something that creates an Event. An Event is a communication from a device on the computer or a program to something outside itself on the computer, like another program or device (through a program associated with that device, like its device driver.) In the case of our mouse program, the Listener is the connection between the mouse's button and our program. Whenever the left button is clicked, an Event is generated that contains what happened (a left-click) and the location in our window where it happened.

If the click happens outside our program's window, an Event is generated, but our program isn't included in the recipients of the message. If our program doesn't have a Listener, the mouse click Event gets passed to our program but is ignored.

If we have a Listener appropriate to an Event that's passed to our program, then something happens with it. So we have to create a Listener, tell our program to add it to its list of Listeners (which also tells the program what kind of events it's listening for.) Then our program will tell that Listener whenever one of those events happens, and pass along the details.

A MouseListener is a very generalized sort of Listener. An ActionListener, however, can be set up to listen for a specific event, like a click on a specific button. Take a look in the Java API at ActionListener. By associating an ActionListener with a specific button, you can hear only about when that button is clicked, and know that that's precisely what happened. That ActionListener won't hear about clicks elsewhere, you don't need to check the location of the click, and it won't tell you about anything else you don't want to hear about.

That saves you all the trouble that I talked about above. You can set up your ActionListener to just exeecute the part of your code you want it to run when someone clicks the button. Or slides the slider, or whatever. No fuss, no muss.

I'll be posting a sample program soon, until then have a look at the Sun Java Tutorials on using buttons and other controls from Swing (Java's best set of graphical user interface objects.)
StumbleUpon