Friday, February 18, 2011

Java : Framing Treasured Moments

Yesterday's "Hello world!" program just wrote text to a DOS box. Today's program is going to open up a window and display an image in it. Not quite "Call of Duty: Modern Warfare 3", but remember - baby steps.

We'll start with this heart-warming image of two lovable cartoon characters.

Make a new sub-directory of your Java working directory and call it "Images". Save the image in there as "hitler_bambi_0.jpg". (If you're offended by cartoon deer, you can use any image you like, but be sure to change the image and directory names in your program later.)

Now for our program:
// ShowImageApp.java

// import definitions for the pre-defined classes & methods we'll be using
import java.awt.*;
import java.awt.image.*;
import javax.swing.*;
import javax.imageio.*;
import java.io.*;

public class ShowImageApp extends JPanel
{
 // define constants to determine the width & height of our window
 private static final int PWIDTH =  417;
 private static final int PHEIGHT=  400;
 
 // declare a variable to hold our image;
 private BufferedImage image;
 
 // ShowImageApp() is a constructor method for initializing new ShowImageApp objects
 public ShowImageApp()
 {
  setPreferredSize(new Dimension(PWIDTH,PHEIGHT));
  image = loadImage("Images/hitler_bambi_0.jpg");
 }

 // Load the image from <filename>, returning it as a BufferedImage
  public BufferedImage loadImage(String filename) 
 {
  try {
   BufferedImage im =  ImageIO.read(getClass().getResource(filename));
   return im; 
  } catch(IOException e) {
   System.out.println("Load Image error for "+filename+":\n"+e);
   return null;
  }
 }
 
 // tells the window manager how to paint the window
 public void paintComponent(Graphics g)
 {
  g.drawImage(image,0,0,this);  
 }
  
 public static void main(String args[])
 {
  // construct a new object, showPanel, of class ShowImageApp
  ShowImageApp showPanel = new ShowImageApp();

  // construct a new window-frame object, showFrame
  JFrame showFrame = new JFrame("Frame title goes here");

  // link the panel to the frame
  showFrame.getContentPane().add(showPanel,BorderLayout.CENTER);

  // tell Java to shut down when we close the window
  showFrame.setDefaultCloseOperation (WindowConstants.EXIT_ON_CLOSE);

  // don't allow the window to be resized
  showFrame.setResizable(false);

  // display the window
  showFrame.pack();
  showFrame.setVisible(true); 
 } // main
} // ShowImageApp class
Whoah! That's a big jump in complexity from the "Hello World" program. Let's strip out some of the noise and show some simplified pseudo-code.
import definitions;

public class ShowImageApp extends JPanel
{
 define constants & declare variables;
 
 ShowImageApp() is a constructor method for the ShowImageApp class

 loadImage(filename) loads an image into a BufferedImage
  
 paintComponent(Graphics g) tells the JVM how to paint the window
  
 public static void main(String args[])
 {
  construct a new ShowImageApp object called showPanel;

  construct a new window frame called showFrame;
  tell JVM that showPanel is the content of showFrame;
  tell JVM to shut down when we close the window;
  make the window size fixed;  
  display the window;
 }
}

So, yesterday's program defined the "HelloWorldApp" class: today's defines "ShowImageApp".
Yesterday's "main" method just printed a line of text: today's constructs a new object "showPanel"; makes a window for it "showFrame"; links the two; does some housekeeping; and displays the window.

The most confusing part of this program for me as a beginner is the overloading (re-definition) of the word "ShowImageApp". In a better designed language, the constructor method for the "ShowImageApp" class might have been called "makeShowImageApp". This would make it a little clearer that the constructor is just an initialization method for a new class object. The declaration of "showPanel" would then read:
ShowImageApp showPanel = new makeShowImageApp();
Sadly, we're stuck with Java's execrable syntax.

The most complicated part of our program is perhaps the method "loadImage". You'll see code like
try{some action}catch{some exception}
quite a lot in Java - usually when performing input/output (I/O) of some kind. It just tells the JVM to try to do something, and if something goes wrong, to handle the exception gracefully.

To run the program, copy and save the first program listing (not the pseudo-code) to a file called "ShowImageApp.java" in your working directory. (Remember, the filename must match the class name.)

Compile with

javac ShowImageApp.java

and run with

java ShowImageApp

Your most likely source of problems is that the program looks for the image in the wrong place and with the wrong name. Java is case sensitive! But, Windows often "fixes" file commands for you so cases "kind of" match. Make sure your images sub-directory is called "Images" not "images" or "ImAgEs".

Once you get the program working, you can swap the image for something from your fap folder. remember to change the definitions of PWIDTH and PHEIGHT to match the size (in pixels) of your new image.

Have fun.

15 comments:

  1. i love java!!! i actually just developed this Poetry for Android from java. java is so tedious though compared to c++, and php.

    ReplyDelete
  2. That deer... Loves... Hitler? Lawl.

    I'm no good with Java, or C++ or any of that stuff, I can barely scrape by in HTML.

    I fail as a nerd.

    ReplyDelete
  3. "If you're offended by cartoon deer"....bwaahaahaa! You make me laugh.

    ReplyDelete
  4. hitler looks so innocent in that pic

    ReplyDelete
  5. I dunno, Suciô, that sounds like quite a bit of work. maybe if i wasn't drinkin

    ReplyDelete
  6. wow that's a lot of code to just open up a window with an image.

    ReplyDelete
  7. yeah im just hosed right now. that looks fun and exciting :)

    ReplyDelete
  8. nice tutorial and awesome picture :D

    ReplyDelete
  9. You know that picture is so cute. Regardless of the Fuhrer or not.

    ReplyDelete
  10. Oh woe is me..take me back to the start she says.. Let me review the first post and try to catch up. I really want to learn this but am so not a techno geek..
    Of I go in search of the start :-)

    Have a great weekend!!

    ReplyDelete
  11. awwwww, baby Hitler's mustache looks like a little nose.

    ReplyDelete