Image Viewer using Java! That was one of the lab assignments we were assigned. And I tell you, it was great fun! Going through the Java documentation of various classes, appreciating the way they were developed, and trying to use them, I mean creating instances for those classes and calling methods using those instances, it took nearly 10 days to finish the job with perfection...
Graphics Programming using Java works out very well and for these simple applications its just awesome. Once you start working with this pardigm, you understand the OO concepts better. And the way the graphics components are designed in Java, My God! Hats off to those class developers.
So this is how I developed the application:
Firstly the public class ImageViewer with the static main method defined in it is written. The main method is so simple that it just creates an object for class ImageFrame, passing the command line arguments to its constructor. As you guess, the next step is to write the class ImageFrame that extends JFrame class. Its just a one-method class (the constructor alone). We set the title, size and the icon image for it. Thus the frame is ready to act as a container of JComponents. Instead of adding all the JComponents to the ImageFrame, we add a JPanel to it first, and then add the necessary JComponents on top of the JPanel.
So we create another class ImagePanel that extends JPanel class, and add it to the ImageFrame. So now the ImagePanel can hold all the other JComponents, but how do we arrange them on the panel, so that they all look neat? Yes! We gotta use an appropriate Layout Manager. We set border layout to it. To the north we shall add the text boxes for displaying the file and the zoom percent (a little later), and in the south a JToolBar that shall contain all the buttons for the ImageViewer. It is not made floatable so that its location in the window is static.
In the center of the ImagePanel comes another JPanel that acts as the container of the Image that has to be displayed. Since drawing an image in a panel is little tedious, we add a JLabel to it with no text. To display the image, we just gotta set the icon for JLabel.
We pass the command line arguments from the ImageViewer class to ImageFrame class, which in turn goes to the ImagePanel class. We check if the command line input has a file that can be opened and if so, the icon is set for the JLabel (as mentioned in the previous para). For the sake of formality, we add the tooltips to all the buttons on the panel. Now that the buttons have only the image icon and not any action command, we try to set the action commands for all the buttons, so that it easy to capture the action events generated in the action listener.
So, the next step is to add action listeners to all the buttons on the tool bar. So we develop a class ToolListener that implements ActionListener interface. We pass a reference object of the JPanel we were using (ImagePanel) so that all its class members are accessible through the reference. Lets now move our focus to the Listener class. In the constructor we assign the reference object of the ImagePanel class. We define what action is to be done on those button clicks in the actionPerformed method. We also design a class ImageFile, that will have objects describing the image in use in the application, that is the File object in use, the image object in use and the zoom percent of the image. Let us mark them static so that it is accessible from all the classes (globally).
We also design a filter class ImageFilter that extends javax.swing.filechooser.FileFilter and implements java.io.FileFilter. Its just to override the methods accept and getDescription. Let us also define few static methods that operate on these objects, so that they can simply be called from differenct classes.
Let us now see how all the functional requirements are implemented in the action listener:
1. Load image from the file system:
Simply use the JFileChooser object of the swing package. Set the file filter using the object of class ImageFilter (will be explained shortly). Display the open dialog and get the selected file object. Call the static loadImage method of the ImageFile class (Now the job is over).
2. Save image to the file system:
Again we use the JFileChooser class, but dislplay the save dialog instead of open. As you expect, the file object is used to save the image. We use the file stream classes for the copy operation (FileInputStream and FileOutputStream).
3. Delete the image being viewed from the file system:
This is the most easiest task. (Destructive jobs seem to be easier!) Using the static image file object and call the delete method of the File class.
4. Refresh the display:
Since the display is on a panel, we call the repaint method using its object. As simple as that!
5. Zoom :
We call the static rescale method of the ImageFile class passing the rescale factor. Now what do we do in the rescale method is the question. Pay little attention here. Create a new BufferedImage object with the new height and width using the rescale factor. Create a graphics object using the image and alter the image using the drawImage method of the Graphics class. To make it more clear, here is the sentence for it:
g.drawImage(image, 0, 0,(int)(width*resizeFactor) ,(int)(height*resizeFactor),0,0,width,height, null);
Since this requirement has got something to do with time, we comfortably use threads. So to create a thread, let us define another class Slideshow that extends Thread class, and simply override the run method. In the run method, we examine the directory where the display image is, and simply list all the image files from the directory (Use the ImageFilter again for this). Use an enhanced loop to get an image and sleep for 5 seconds (5000 milli seconds in fact!). We load the image as long as a boolean variable stopThread reads true. We set it false using requestStop method of this class in order to pause.
7. Load first, next, previous and last images:
These are done by those static methods that examine the directory and use a ArrayList of File objects to load the next or previous or index 0 or last index image.
8. Change Background color:
We use the JColorChooser class that returns the color object. Using the referencePanel object and the setBackground method, we implement this.
9. Close:
We take extra care to first make the panel invisible and then exit (System.exit(status);).
P.S. This is my first technical blog :)
- ∫.∫rikrishnan
Good one ! :-)
ReplyDeleteThat was a good tutorial !! :)
ReplyDelete