Senin, 10 Desember 2018

EAS PBO B

1. Rancangan interface image editor.


2. Class diagram dari image editor yang akan dibuat terdiri atas 10 class seperti berikut.


  • ImageViewer : Membuat dan menampilkan GUI serta class utama dari aplikasi ini.
  • ImageFileManager : Mengelola file seperti save, load, dll.
  • ImagePanel : Mengatur panel yang akan dibentuk dari objek OFImage.
  • OFImage : Mendefinisikan sebuah gambar dalam format object first (OF).
  • Filter : Menerapkan filter ke gambar (OFImage).
  • DarkerFilter : Filter yang berfungsi untuk menggelapkan gambar.
  • LighterFilter : Filter yang berfungsi untuk menerangkan gambar.
  • Thresholdfilter : Filter dengan gambar hitam putih.
  • FishEyeFilter : Filter yang mencengkungkan gambar.
  • MirrorFilter : Filter yang mencerminkan gambar secara horizontal.
3. Implementasi program image editor.

Class ImageViewer

  import java.awt.*;    
  import java.awt.event.*;    
  import java.awt.image.*;    
  import javax.swing.*;    
  import javax.swing.border.*;    
  import java.io.File;    
  import java.util.List;    
  import java.util.ArrayList;    
  import java.util.Iterator;    
  /**   
  * Class utama aplikasi penampil gambar.  
  * membuat dan menampilkan GUI dan menginisialisasi komponen lainnya.  
  *   
  * @author    
  * @version   
  */   
  public class ImageViewer    
  {    
   // static fields:    
   private static final String VERSION = "Version 3.0";    
   private static JFileChooser fileChooser = new JFileChooser(System.getProperty("user.dir"));    
   // fields:    
   private JFrame frame;    
   private ImagePanel imagePanel;    
   private JLabel filenameLabel;    
   private JLabel statusLabel;    
   private JButton smallerButton;    
   private JButton largerButton;  
   private JButton cropButton;  
   private OFImage currentImage;    
   private List<Filter> filters;    
   /**    
   * Create an ImageViewer and display its GUI on screen.    
   */    
   public ImageViewer()    
   {    
   currentImage = null;    
   filters = createFilters();    
   makeFrame();    
   }    
   // ---- implementation of menu functions ----    
   /**    
   * Open function: open a file chooser to select a new image file,    
   * and then display the chosen image.    
   */    
   private void openFile()    
   {    
   int returnVal = fileChooser.showOpenDialog(frame);    
   if(returnVal != JFileChooser.APPROVE_OPTION) {    
    return; // cancelled    
   }    
   File selectedFile = fileChooser.getSelectedFile();    
   currentImage = ImageFileManager.loadImage(selectedFile);    
   if(currentImage == null) { // image file was not a valid image    
    JOptionPane.showMessageDialog(frame,    
     "The file was not in a recognized image file format.",    
     "Image Load Error",    
     JOptionPane.ERROR_MESSAGE);    
    return;    
   }    
   imagePanel.setImage(currentImage);    
   setButtonsEnabled(true);    
   showFilename(selectedFile.getPath());    
   showStatus("File loaded.");    
   frame.pack();    
   }    
   /**    
   * Close function: close the current image.    
   */    
   private void close()    
   {    
   currentImage = null;    
   imagePanel.clearImage();    
   showFilename(null);    
   setButtonsEnabled(false);    
   }    
   /**    
   * Save As function: save the current image to a file.    
   */    
   private void saveAs()    
   {    
   if(currentImage != null) {    
    int returnVal = fileChooser.showSaveDialog(frame);    
    if(returnVal != JFileChooser.APPROVE_OPTION) {    
    return; // cancelled    
    }    
    File selectedFile = fileChooser.getSelectedFile();    
    ImageFileManager.saveImage(currentImage, selectedFile);    
    showFilename(selectedFile.getPath());    
   }    
   }    
   /**    
   * Quit function: quit the application.    
   */    
   private void quit()    
   {    
   System.exit(0);    
   }    
   /**    
   * Apply a given filter to the current image.    
   *    
   * @param filter The filter object to be applied.    
   */    
   private void applyFilter(Filter filter)    
   {    
   if(currentImage != null) {    
    filter.apply(currentImage);    
    frame.repaint();    
    showStatus("Applied: " + filter.getName());    
   }    
   else {    
    showStatus("No image loaded.");    
   }    
   }    
   /**    
   * 'About' function: show the 'about' box.    
   */    
   private void showAbout()    
   {    
   JOptionPane.showMessageDialog(frame,    
     "ImageViewer\n" + VERSION,    
     "About ImageViewer",    
     JOptionPane.INFORMATION_MESSAGE);    
   }    
   /**    
   * Make the current picture larger.    
   */    
   private void makeLarger()    
   {    
   if(currentImage != null) {    
    // create new image with double size    
    int width = currentImage.getWidth();    
    int height = currentImage.getHeight();    
    OFImage newImage = new OFImage(width * 2, height * 2);    
    // copy pixel data into new image    
    for(int y = 0; y < height; y++) {    
    for(int x = 0; x < width; x++) {    
     Color col = currentImage.getPixel(x, y);    
     newImage.setPixel(x * 2, y * 2, col);    
     newImage.setPixel(x * 2 + 1, y * 2, col);    
     newImage.setPixel(x * 2, y * 2 + 1, col);    
     newImage.setPixel(x * 2+1, y * 2 + 1, col);    
    }    
    }    
    currentImage = newImage;    
    imagePanel.setImage(currentImage);    
    frame.pack();    
   }    
   }    
   /**    
   * Make the current picture smaller.    
   */    
   private void makeSmaller()    
   {    
   if(currentImage != null) {    
    // create new image with double size    
    int width = currentImage.getWidth() / 2;    
    int height = currentImage.getHeight() / 2;    
    OFImage newImage = new OFImage(width, height);    
    // copy pixel data into new image    
    for(int y = 0; y < height; y++) {    
    for(int x = 0; x < width; x++) {    
     newImage.setPixel(x, y, currentImage.getPixel(x * 2, y * 2));    
    }    
    }    
    currentImage = newImage;    
    imagePanel.setImage(currentImage);    
    frame.pack();    
   }    
   }  
   private void makeCrop()  
   {  
     if(currentImage != null){  
       int width = currentImage.getWidth();  
       int height = currentImage.getHeight();  
       int xAwal = Integer.parseInt(JOptionPane.showInputDialog("xAwal"));  
       int xAkhir = Integer.parseInt(JOptionPane.showInputDialog("xAkhir"));  
       int yAwal = Integer.parseInt(JOptionPane.showInputDialog("yAwal"));  
       int yAkhir = Integer.parseInt(JOptionPane.showInputDialog("yAkhir"));  
       OFImage newImage = new OFImage(xAkhir - xAwal, yAkhir - yAwal);  
       for(int y = 0; y < yAkhir - yAwal; y++){  
         for(int x = 0; x < xAkhir - xAwal; x++){  
           newImage.setPixel(x, y, currentImage.getPixel(x + xAwal, y + yAwal));  
         }  
       }  
       currentImage = newImage;  
       imagePanel.setImage(currentImage);  
       frame.pack();  
     }  
   }  
   // ---- support methods ----    
   /**    
   * Show the file name of the current image in the fils display label.    
   * 'null' may be used as a parameter if no file is currently loaded.    
   *    
   * @param filename The file name to be displayed, or null for 'no file'.    
   */    
   private void showFilename(String filename)    
   {    
   if(filename == null) {    
    filenameLabel.setText("No file displayed.");    
   }    
   else {    
    filenameLabel.setText("File: " + filename);    
   }    
   }    
   /**    
   * Show a message in the status bar at the bottom of the screen.    
   * @param text The message to be displayed.    
   */    
   private void showStatus(String text)    
   {    
   statusLabel.setText(text);    
   }    
   /**    
   * Enable or disable all toolbar buttons.    
   *    
   * @param status 'true' to enable the buttons, 'false' to disable.    
   */    
   private void setButtonsEnabled(boolean status)    
   {    
   smallerButton.setEnabled(status);    
   largerButton.setEnabled(status);  
   cropButton.setEnabled(status);  
   }    
   /**    
   * Create a list with all the known filters.    
   * @return The list of filters.    
   */    
   private List<Filter> createFilters()    
   {    
   List<Filter> filterList = new ArrayList<Filter>();    
   filterList.add(new DarkerFilter("Darker"));    
   filterList.add(new LighterFilter("Lighter"));    
   filterList.add(new ThresholdFilter("Threshold"));    
   filterList.add(new FishEyeFilter("Fish Eye"));  
   filterList.add(new MirrorFilter("Mirror"));  
   return filterList;    
   }    
   // ---- swing stuff to build the frame and all its components ----    
   /**    
   * Create the Swing frame and its content.    
   */    
   private void makeFrame()    
   {    
   frame = new JFrame("ImageViewer");    
   JPanel contentPane = (JPanel)frame.getContentPane();    
   contentPane.setBorder(new EmptyBorder(6, 6, 6, 6));    
   makeMenuBar(frame);    
   // Specify the layout manager with nice spacing    
   contentPane.setLayout(new BorderLayout(6, 6));    
   // Create the image pane in the center    
   imagePanel = new ImagePanel();    
   imagePanel.setBorder(new EtchedBorder());    
   contentPane.add(imagePanel, BorderLayout.CENTER);    
   // Create two labels at top and bottom for the file name and status message    
   filenameLabel = new JLabel();    
   contentPane.add(filenameLabel, BorderLayout.NORTH);    
   statusLabel = new JLabel(VERSION);    
   contentPane.add(statusLabel, BorderLayout.SOUTH);    
   // Create the toolbar with the buttons    
   JPanel toolbar = new JPanel();    
   toolbar.setLayout(new GridLayout(0, 1));    
   smallerButton = new JButton("Smaller");    
   smallerButton.addActionListener(new ActionListener() {    
      public void actionPerformed(ActionEvent e) { makeSmaller(); }    
      });    
   toolbar.add(smallerButton);    
   largerButton = new JButton("Larger");    
   largerButton.addActionListener(new ActionListener() {    
      public void actionPerformed(ActionEvent e) { makeLarger(); }    
      });    
   toolbar.add(largerButton);  
   cropButton = new JButton("Crop");  
   cropButton.addActionListener(new ActionListener(){  
      public void actionPerformed(ActionEvent e) { makeCrop();}  
      });  
   toolbar.add(cropButton);  
   // Add toolbar into panel with flow layout for spacing    
   JPanel flow = new JPanel();    
   flow.add(toolbar);    
   contentPane.add(flow, BorderLayout.WEST);    
   // building is done - arrange the components     
   showFilename(null);    
   setButtonsEnabled(false);    
   frame.pack();    
   // place the frame at the center of the screen and show    
   Dimension d = Toolkit.getDefaultToolkit().getScreenSize();    
   frame.setLocation(d.width/2 - frame.getWidth()/2, d.height/2 - frame.getHeight()/2);    
   frame.setVisible(true);    
   }    
   /**    
   * Create the main frame's menu bar.    
   *    
   * @param frame The frame that the menu bar should be added to.    
   */    
   private void makeMenuBar(JFrame frame)    
   {    
   final int SHORTCUT_MASK =    
    Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();    
   JMenuBar menubar = new JMenuBar();    
   frame.setJMenuBar(menubar);    
   JMenu menu;    
   JMenuItem item;    
   // create the File menu    
   menu = new JMenu("File");    
   menubar.add(menu);    
   item = new JMenuItem("Open...");    
    item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, SHORTCUT_MASK));    
    item.addActionListener(new ActionListener() {    
      public void actionPerformed(ActionEvent e) { openFile(); }    
      });    
   menu.add(item);    
   item = new JMenuItem("Close");    
    item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_W, SHORTCUT_MASK));    
    item.addActionListener(new ActionListener() {    
      public void actionPerformed(ActionEvent e) { close(); }    
      });    
   menu.add(item);    
   menu.addSeparator();    
   item = new JMenuItem("Save As...");    
    item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, SHORTCUT_MASK));    
    item.addActionListener(new ActionListener() {    
      public void actionPerformed(ActionEvent e) { saveAs(); }    
      });    
   menu.add(item);    
   menu.addSeparator();    
   item = new JMenuItem("Quit");    
    item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, SHORTCUT_MASK));    
    item.addActionListener(new ActionListener() {    
      public void actionPerformed(ActionEvent e) { quit(); }    
      });    
   menu.add(item);    
   // create the Filter menu    
   menu = new JMenu("Filter");    
   menubar.add(menu);    
   for(final Filter filter : filters) {    
    item = new JMenuItem(filter.getName());    
    item.addActionListener(new ActionListener() {    
      public void actionPerformed(ActionEvent e) {    
       applyFilter(filter);    
      }    
      });    
    menu.add(item);    
   }    
   // create the Help menu    
   menu = new JMenu("Help");    
   menubar.add(menu);    
   item = new JMenuItem("About ImageViewer...");    
    item.addActionListener(new ActionListener() {    
      public void actionPerformed(ActionEvent e) { showAbout(); }    
      });    
   menu.add(item);    
   }    
  }  

Class ImageFileManager

  import java.awt.image.*;    
  import javax.imageio.*;    
  import java.io.*;    
  /**   
  * Class ImageFileManager dengan method statis untuk membuka dan menyimpan gambar.  
  *   
  * @author   
  * @version   
  */   
  public class ImageFileManager    
  {    
   // A constant for the image format that this writer uses for writing.    
   // Available formats are "jpg" and "png".    
   private static final String IMAGE_FORMAT = "jpg";    
   /**    
   * Read an image file from disk and return it as an image. This method    
   * can read JPG and PNG file formats. In case of any problem (e.g the file    
   * does not exist, is in an undecodable format, or any other read error)    
   * this method returns null.    
   *    
   * @param imageFile The image file to be loaded.    
   * @return  The image object or null is it could not be read.    
   */    
   public static OFImage loadImage(File imageFile)    
   {    
   try {    
    BufferedImage image = ImageIO.read(imageFile);    
    if(image == null || (image.getWidth(null) < 0)) {    
    // we could not load the image - probably invalid file format    
    return null;    
    }    
    return new OFImage(image);    
   }    
   catch(IOException exc) {    
    return null;    
   }    
   }    
   /**    
   * Write an image file to disk. The file format is JPG. In case of any    
   * problem the method just silently returns.    
   *    
   * @param image The image to be saved.    
   * @param file The file to save to.    
   */    
   public static void saveImage(OFImage image, File file)    
   {    
   try {    
    ImageIO.write(image, IMAGE_FORMAT, file);    
   }    
   catch(IOException exc) {    
    return;    
   }    
   }    
  }  

Class ImagePanel

  import java.awt.*;    
  import javax.swing.*;    
  import java.awt.image.*;    
  /**   
  * Class ImagePanel sebuah swing component yang dapat menampilkan sebuah OFImage.  
  *   
  * @author   
  * @version   
  */   
  public class ImagePanel extends JComponent    
  {    
   // The current width and height of this panel    
   private int width, height;    
   // An internal image buffer that is used for painting. For    
   // actual display, this image buffer is then copied to screen.    
   private OFImage panelImage;    
   /**    
   * Create a new, empty ImagePanel.    
   */    
   public ImagePanel()    
   {    
   width = 360; // arbitrary size for empty panel    
   height = 240;    
   panelImage = null;    
   }    
   /**    
   * Set the image that this panel should show.    
   *    
   * @param image The image to be displayed.    
   */    
   public void setImage(OFImage image)    
   {    
   if(image != null) {    
    width = image.getWidth();    
    height = image.getHeight();    
    panelImage = image;    
    repaint();    
   }    
   }    
   /**    
   * Clear the image on this panel.    
   */    
   public void clearImage()    
   {    
   Graphics imageGraphics = panelImage.getGraphics();    
   imageGraphics.setColor(Color.LIGHT_GRAY);    
   imageGraphics.fillRect(0, 0, width, height);    
   repaint();    
   }    
   // The following methods are redefinitions of methods    
   // inherited from superclasses.    
   /**    
   * Tell the layout manager how big we would like to be.    
   * (This method gets called by layout managers for placing    
   * the components.)    
   *    
   * @return The preferred dimension for this component.    
   */    
   public Dimension getPreferredSize()    
   {    
   return new Dimension(width, height);    
   }    
   /**    
   * This component needs to be redisplayed. Copy the internal image    
   * to screen. (This method gets called by the Swing screen painter    
   * every time it want this component displayed.)    
   *    
   * @param g The graphics context that can be used to draw on this component.    
   */    
   public void paintComponent(Graphics g)    
   {    
   Dimension size = getSize();    
   g.clearRect(0, 0, size.width, size.height);    
   if(panelImage != null) {    
    g.drawImage(panelImage, 0, 0, null);    
   }    
   }    
  }  

Class OFImage

  import java.awt.*;    
  import java.awt.image.*;    
  import javax.swing.*;    
  /**   
  * class OFImage untuk mendefinisikan sebuah image dalam format object first.  
  *   
  * @author   
  * @version   
  */   
  public class OFImage extends BufferedImage    
  {    
   /**    
   * Create an OFImage copied from a BufferedImage.    
   * @param image The image to copy.    
   */    
   public OFImage(BufferedImage image)    
   {    
   super(image.getColorModel(), image.copyData(null),    
    image.isAlphaPremultiplied(), null);    
   }    
   /**    
   * Create an OFImage with specified size and unspecified content.    
   * @param width The width of the image.    
   * @param height The height of the image.    
   */    
   public OFImage(int width, int height)    
   {    
   super(width, height, TYPE_INT_RGB);    
   }    
   /**    
   * Set a given pixel of this image to a specified color. The    
   * color is represented as an (r,g,b) value.    
   * @param x The x position of the pixel.    
   * @param y The y position of the pixel.    
   * @param col The color of the pixel.    
   */    
   public void setPixel(int x, int y, Color col)    
   {    
   int pixel = col.getRGB();    
   setRGB(x, y, pixel);    
   }    
   /**    
   * Get the color value at a specified pixel position.    
   * @param x The x position of the pixel.    
   * @param y The y position of the pixel.    
   * @return The color of the pixel at the given position.    
   */    
   public Color getPixel(int x, int y)    
   {    
   int pixel = getRGB(x, y);    
   return new Color(pixel);    
   }    
  }  

Class Filter

  /**   
  * Class Filter untuk menambahkan filter pada gambar  
  *   
  * @author   
  * @version   
  */   
  public abstract class Filter    
  {    
   private String name;    
   /**    
   * Create a new filter with a given name.    
   * @param name The name of the filter.    
   */    
   public Filter(String name)    
   {    
   this.name = name;    
   }    
   /**    
   * Return the name of this filter.    
   *    
   * @return The name of this filter.    
   */    
   public String getName()    
   {    
   return name;    
   }    
   /**    
   * Apply this filter to an image.    
   *    
   * @param image The image to be changed by this filter.    
   */    
   public abstract void apply(OFImage image);    
  }  

Class DarkerFilter

  /**   
  *   
  *   
  * @author   
  * @version   
  */   
  public class DarkerFilter extends Filter    
  {    
   /**    
   * Constructor for objects of class DarkerFilter.    
   * @param name The name of the filter.    
   */    
   public DarkerFilter(String name)    
   {    
   super(name);    
   }    
   /**    
   * Apply this filter to an image.    
   *    
   * @param image The image to be changed by this filter.    
   */    
   public void apply(OFImage image)    
   {    
   int height = image.getHeight();    
   int width = image.getWidth();    
   for(int y = 0; y < height; y++) {    
    for(int x = 0; x < width; x++) {    
    image.setPixel(x, y, image.getPixel(x, y).darker());    
    }    
   }    
   }    
  }  

Class LighterFilter

  /**   
  *   
  *   
  * @author   
  * @version   
  */   
  public class LighterFilter extends Filter    
  {    
   /**    
    * Constructor for objects of class LighterFilter.    
   * @param name The name of the filter.    
    */    
   public LighterFilter(String name)    
   {    
   super(name);    
   }    
   /**    
   * Apply this filter to an image.    
   *    
   * @param image The image to be changed by this filter.    
   */    
   public void apply(OFImage image)    
   {    
   int height = image.getHeight();    
   int width = image.getWidth();    
   for(int y = 0; y < height; y++) {    
    for(int x = 0; x < width; x++) {    
    image.setPixel(x, y, image.getPixel(x, y).brighter());    
    }    
   }    
   }    
  }  

Class ThresholdFilter

  import java.awt.Color;   
  /**   
  * Write a description of class ThresfoldFilter here.   
  *   
  * @author   
  * @version   
  */   
  public class ThresholdFilter extends Filter    
  {    
   /**    
    * Constructor for objects of class ThresholdFilter.    
   * @param name The name of the filter.    
    */    
   public ThresholdFilter(String name)    
   {    
   super(name);    
   }    
   /**    
   * Apply this filter to an image.    
   *    
   * @param image The image to be changed by this filter.    
   */    
   public void apply(OFImage image)    
   {    
   int height = image.getHeight();    
   int width = image.getWidth();    
   for(int y = 0; y < height; y++) {    
    for(int x = 0; x < width; x++) {    
    Color pixel = image.getPixel(x, y);    
    int brightness = (pixel.getRed() + pixel.getBlue() + pixel.getGreen()) / 3;    
    if(brightness <= 85) {    
     image.setPixel(x, y, Color.BLACK);    
    }    
    else if(brightness <= 170) {    
     image.setPixel(x, y, Color.GRAY);    
    }    
    else {    
     image.setPixel(x, y, Color.WHITE);    
    }    
    }    
   }    
   }    
  }  

Class FishEyeFilter

  import java.awt.Color;    
  /**   
  *   
  *   
  * @author   
  * @version   
  */   
  public class FishEyeFilter extends Filter    
  {    
   // constants:    
   private final static int SCALE = 20; // this defines the strenght of the filter    
   private final static double TWO_PI = 2 * Math.PI;    
   /**    
   * Constructor for objects of class LensFilter.    
   * @param name The name of the filter.    
   */    
   public FishEyeFilter(String name)    
   {    
   super(name);    
   }    
   /**    
   * Apply this filter to an image.    
   *    
   * @param image The image to be changed by this filter.    
   */    
   public void apply(OFImage image)    
   {    
   int height = image.getHeight();    
   int width = image.getWidth();    
   OFImage original = new OFImage(image);    
   int[] xa = computeXArray(width);    
   int[] ya = computeYArray(height);    
   for(int y = 0; y < height; y++) {    
    for(int x = 0; x < width; x++) {    
    image.setPixel(x, y, original.getPixel(x + xa[x], y + ya[y]));    
    }    
   }    
   }    
   /**    
   * Compute and return an array of horizontal offsets for each pixel column.    
   * These can then be applied as the horizontal offset for each pixel.    
   */    
   private int[] computeXArray(int width)    
   {    
   int[] xArray = new int[width];    
   for(int i=0; i < width; i++) {    
    xArray[i] = (int)(Math.sin( ((double)i / width) * TWO_PI) * SCALE);    
   }    
   return xArray;    
   }    
   /**    
   * Compute and return an array of vertical offsets for each pixel row.    
   * These can then be applied as the vertical offset for each pixel.    
   */    
   private int[] computeYArray(int height)    
   {    
   int[] yArray = new int[height];    
   for(int i=0; i < height; i++) {    
    yArray[i] = (int)(Math.sin( ((double)i / height) * TWO_PI) * SCALE);    
   }    
   return yArray;    
   }    
  }  

Class MirrorFilter

 import java.awt.Color;  
 /**  
  * An image filter to mirror (flip) the image horizontally.  
  *   
  * @author  
  * @version  
  */  
 public class MirrorFilter extends Filter  
 {  
      /**  
       * Constructor for objects of class MirrorFilter.  
    * @param name The name of the filter.  
       */  
      public MirrorFilter(String name)  
   {  
     super(name);  
      }  
   /**  
    * Apply this filter to an image.  
    *   
    * @param image The image to be changed by this filter.  
    */  
   public void apply(OFImage image)  
   {  
     int height = image.getHeight();  
     int width = image.getWidth();  
     for(int y = 0; y < height; y++) {  
       for(int x = 0; x < width / 2; x++) {  
         Color left = image.getPixel(x, y);  
         image.setPixel(x, y, image.getPixel(width - 1 - x, y));  
         image.setPixel(width - 1 - x, y, left);  
       }  
     }  
   }  
 }  

Berikut kita akan mencoba untuk menggunakan aplikasi image editor ini.


Klik menu file kemudian open lalu pilih gambar yang akan diedit.



Menggunakan Fitur Crop, saat menggunakan fitur ini kita akan diminta untuk mengisi titik awal koordinat x, titik akhir koordinat x, titik awal koordinat y, titik akhir koordinat y dari gambar yang akan di crop.


Meggunakan fitur Smaller


Menggunakan fitur Larger


Menerapkan Filter Darker


Menerapkan Filter Lighter


Menerapkan Filter Threshold


Menerapkan Filter FishEye


Menerapkan Filter Mirror


Untuk menyimpan gambar klik menu File kemudian pilih Save As.


-- Terima Kasih --

Senin, 03 Desember 2018

Game Pong

Pada kali ini kita akan membuat game pong dengan bahasa Java menggunakan BlueJ.

Untuk membuat game Pong pertama kita membuat package bernama pong.


Pada package pong ini terdapat 4 class, berikut gambar mapping class-classnya.


Class Pong

 package pong;  
 import java.awt.BasicStroke;  
 import java.awt.Color;  
 import java.awt.Font;  
 import java.awt.Graphics2D;  
 import java.awt.RenderingHints;  
 import java.awt.event.ActionEvent;  
 import java.awt.event.ActionListener;  
 import java.awt.event.KeyEvent;  
 import java.awt.event.KeyListener;  
 import java.util.Random;  
 import javax.swing.JFrame;  
 import javax.swing.Timer;  
 public class Pong implements ActionListener, KeyListener  
 {  
      public static Pong pong;  
      public int width = 700, height = 700;  
      public Renderer renderer;  
      public Paddle player1;  
      public Paddle player2;  
      public Ball ball;  
      public boolean bot = false, selectingDifficulty;  
      public boolean w, s, up, down;  
      public int gameStatus = 0, scoreLimit = 7, playerWon; //0 = Menu, 1 = Paused, 2 = Playing, 3 = Over  
      public int botDifficulty, botMoves, botCooldown = 0;  
      public Random random;  
      public JFrame jframe;  
      public Pong()  
      {  
           Timer timer = new Timer(20, this);  
           random = new Random();  
           jframe = new JFrame("Pong");  
           renderer = new Renderer();  
           jframe.setSize(width + 15, height + 35);  
           jframe.setVisible(true);  
           jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
           jframe.add(renderer);  
           jframe.addKeyListener(this);  
           timer.start();  
      }  
      public void start()  
      {  
           gameStatus = 2;  
           player1 = new Paddle(this, 1);  
           player2 = new Paddle(this, 2);  
           ball = new Ball(this);  
      }  
      public void update()  
      {  
           if (player1.score >= scoreLimit)  
           {  
                playerWon = 1;  
                gameStatus = 3;  
           }  
           if (player2.score >= scoreLimit)  
           {  
                gameStatus = 3;  
                playerWon = 2;  
           }  
           if (w)  
           {  
                player1.move(true);  
           }  
           if (s)  
           {  
                player1.move(false);  
           }  
           if (!bot)  
           {  
                if (up)  
                {  
                     player2.move(true);  
                }  
                if (down)  
                {  
                     player2.move(false);  
                }  
           }  
           else  
           {  
                if (botCooldown > 0)  
                {  
                     botCooldown--;  
                     if (botCooldown == 0)  
                     {  
                          botMoves = 0;  
                     }  
                }  
                if (botMoves < 10)  
                {  
                     if (player2.y + player2.height / 2 < ball.y)  
                     {  
                          player2.move(false);  
                          botMoves++;  
                     }  
                     if (player2.y + player2.height / 2 > ball.y)  
                     {  
                          player2.move(true);  
                          botMoves++;  
                     }  
                     if (botDifficulty == 0)  
                     {  
                          botCooldown = 20;  
                     }  
                     if (botDifficulty == 1)  
                     {  
                          botCooldown = 15;  
                     }  
                     if (botDifficulty == 2)  
                     {  
                          botCooldown = 10;  
                     }  
                }  
           }  
           ball.update(player1, player2);  
      }  
      public void render(Graphics2D g)  
      {  
           g.setColor(Color.BLUE);  
           g.fillRect(0, 0, width, height);  
           g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);  
           if (gameStatus == 0)  
           {  
                g.setColor(Color.WHITE);  
                g.setFont(new Font("Arial", 1, 50));  
                g.drawString("PONG", width / 2 - 75, 50);  
                if (!selectingDifficulty)  
                {  
                     g.setFont(new Font("Arial", 1, 30));  
                     g.drawString("Press Space to Play", width / 2 - 150, height / 2 - 25);  
                     g.drawString("Press Shift to Play with Bot", width / 2 - 200, height / 2 + 25);  
                     g.drawString("<< Score Limit: " + scoreLimit + " >>", width / 2 - 150, height / 2 + 75);  
                }  
           }  
           if (selectingDifficulty)  
           {  
                String string = botDifficulty == 0 ? "Easy" : (botDifficulty == 1 ? "Medium" : "Hard");  
                g.setFont(new Font("Arial", 1, 30));  
                g.drawString("<< Bot Difficulty: " + string + " >>", width / 2 - 180, height / 2 - 25);  
                g.drawString("Press Space to Play", width / 2 - 150, height / 2 + 25);  
           }  
           if (gameStatus == 1)  
           {  
                g.setColor(Color.WHITE);  
                g.setFont(new Font("Arial", 1, 50));  
                g.drawString("PAUSED", width / 2 - 103, height / 2 - 25);  
           }  
           if (gameStatus == 1 || gameStatus == 2)  
           {  
                g.setColor(Color.WHITE);  
                g.setStroke(new BasicStroke(5f));  
                g.drawLine(width / 2, 0, width / 2, height);  
                g.setStroke(new BasicStroke(2f));  
                g.drawOval(width / 2 - 150, height / 2 - 150, 300, 300);  
                g.setFont(new Font("Arial", 1, 50));  
                g.drawString(String.valueOf(player1.score), width / 2 - 90, 50);  
                g.drawString(String.valueOf(player2.score), width / 2 + 65, 50);  
                player1.render(g);  
                player2.render(g);  
                ball.render(g);  
           }  
           if (gameStatus == 3)  
           {  
                g.setColor(Color.WHITE);  
                g.setFont(new Font("Arial", 1, 50));  
                g.drawString("PONG", width / 2 - 75, 50);  
                if (bot && playerWon == 2)  
                {  
                     g.drawString("The Bot Wins!", width / 2 - 170, 200);  
                }  
                else  
                {  
                     g.drawString("Player " + playerWon + " Wins!", width / 2 - 165, 200);  
                }  
                g.setFont(new Font("Arial", 1, 30));  
                g.drawString("Press Space to Play Again", width / 2 - 185, height / 2 - 25);  
                g.drawString("Press ESC for Menu", width / 2 - 140, height / 2 + 25);  
           }  
      }  
      @Override  
      public void actionPerformed(ActionEvent e)  
      {  
           if (gameStatus == 2)  
           {  
                update();  
           }  
           renderer.repaint();  
      }  
      public static void main(String[] args)  
      {  
           pong = new Pong();  
      }  
      @Override  
      public void keyPressed(KeyEvent e)  
      {  
           int id = e.getKeyCode();  
           if (id == KeyEvent.VK_W)  
           {  
                w = true;  
           }  
           else if (id == KeyEvent.VK_S)  
           {  
                s = true;  
           }  
           else if (id == KeyEvent.VK_UP)  
           {  
                up = true;  
           }  
           else if (id == KeyEvent.VK_DOWN)  
           {  
                down = true;  
           }  
           else if (id == KeyEvent.VK_RIGHT)  
           {  
                if (selectingDifficulty)  
                {  
                     if (botDifficulty < 2)  
                     {  
                          botDifficulty++;  
                     }  
                     else  
                     {  
                          botDifficulty = 0;  
                     }  
                }  
                else if (gameStatus == 0)  
                {  
                     scoreLimit++;  
                }  
           }  
           else if (id == KeyEvent.VK_LEFT)  
           {  
                if (selectingDifficulty)  
                {  
                     if (botDifficulty > 0)  
                     {  
                          botDifficulty--;  
                     }  
                     else  
                     {  
                          botDifficulty = 2;  
                     }  
                }  
                else if (gameStatus == 0 && scoreLimit > 1)  
                {  
                     scoreLimit--;  
                }  
           }  
           else if (id == KeyEvent.VK_ESCAPE && (gameStatus == 2 || gameStatus == 3))  
           {  
                gameStatus = 0;  
           }  
           else if (id == KeyEvent.VK_SHIFT && gameStatus == 0)  
           {  
                bot = true;  
                selectingDifficulty = true;  
           }  
           else if (id == KeyEvent.VK_SPACE)  
           {  
                if (gameStatus == 0 || gameStatus == 3)  
                {  
                     if (!selectingDifficulty)  
                     {  
                          bot = false;  
                     }  
                     else  
                     {  
                          selectingDifficulty = false;  
                     }  
                     start();  
                }  
                else if (gameStatus == 1)  
                {  
                     gameStatus = 2;  
                }  
                else if (gameStatus == 2)  
                {  
                     gameStatus = 1;  
                }  
           }  
      }  
      @Override  
      public void keyReleased(KeyEvent e)  
      {  
           int id = e.getKeyCode();  
           if (id == KeyEvent.VK_W)  
           {  
                w = false;  
           }  
           else if (id == KeyEvent.VK_S)  
           {  
                s = false;  
           }  
           else if (id == KeyEvent.VK_UP)  
           {  
                up = false;  
           }  
           else if (id == KeyEvent.VK_DOWN)  
           {  
                down = false;  
           }  
      }  
      @Override  
      public void keyTyped(KeyEvent e)  
      {  
      }  
 }  

Class Ball

 package pong;  
 import java.awt.Color;  
 import java.awt.Graphics;  
 import java.util.Random;  
 public class Ball  
 {  
      public int x, y, width = 25, height = 25;  
      public int motionX, motionY;  
      public Random random;  
      private Pong pong;  
      public int amountOfHits;  
      public Ball(Pong pong)  
      {  
           this.pong = pong;  
           this.random = new Random();  
           spawn();  
      }  
      public void update(Paddle paddle1, Paddle paddle2)  
      {  
           int speed = 5;  
           this.x += motionX * speed;  
           this.y += motionY * speed;  
           if (this.y + height - motionY > pong.height || this.y + motionY < 0)  
           {  
                if (this.motionY < 0)  
                {  
                     this.y = 0;  
                     this.motionY = random.nextInt(4);  
                     if (motionY == 0)  
                     {  
                          motionY = 1;  
                     }  
                }  
                else  
                {  
                     this.motionY = -random.nextInt(4);  
                     this.y = pong.height - height;  
                     if (motionY == 0)  
                     {  
                          motionY = -1;  
                     }  
                }  
           }  
           if (checkCollision(paddle1) == 1)  
           {  
                this.motionX = 1 + (amountOfHits / 5);  
                this.motionY = -2 + random.nextInt(4);  
                if (motionY == 0)  
                {  
                     motionY = 1;  
                }  
                amountOfHits++;  
           }  
           else if (checkCollision(paddle2) == 1)  
           {  
                this.motionX = -1 - (amountOfHits / 5);  
                this.motionY = -2 + random.nextInt(4);  
                if (motionY == 0)  
                {  
                     motionY = 1;  
                }  
                amountOfHits++;  
           }  
           if (checkCollision(paddle1) == 2)  
           {  
                paddle2.score++;  
                spawn();  
           }  
           else if (checkCollision(paddle2) == 2)  
           {  
                paddle1.score++;  
                spawn();  
           }  
      }  
      public void spawn()  
      {  
           this.amountOfHits = 0;  
           this.x = pong.width / 2 - this.width / 2;  
           this.y = pong.height / 2 - this.height / 2;  
           this.motionY = -2 + random.nextInt(4);  
           if (motionY == 0)  
           {  
                motionY = 1;  
           }  
           if (random.nextBoolean())  
           {  
                motionX = 1;  
           }  
           else  
           {  
                motionX = -1;  
           }  
      }  
      public int checkCollision(Paddle paddle)  
      {  
           if (this.x < paddle.x + paddle.width && this.x + width > paddle.x && this.y < paddle.y + paddle.height && this.y + height > paddle.y)  
           {  
                return 1; //bounce  
           }  
           else if ((paddle.x > x && paddle.paddleNumber == 1) || (paddle.x < x - width && paddle.paddleNumber == 2))  
           {  
                return 2; //score  
           }  
           return 0; //nothing  
      }  
      public void render(Graphics g)  
      {  
           g.setColor(Color.WHITE);  
           g.fillOval(x, y, width, height);  
      }  
 }  

Class Paddle

 package pong;  
 import java.awt.Color;  
 import java.awt.Graphics;  
 public class Paddle  
 {  
      public int paddleNumber;  
      public int x, y, width = 50, height = 250;  
      public int score;  
      public Paddle(Pong pong, int paddleNumber)  
      {  
           this.paddleNumber = paddleNumber;  
           if (paddleNumber == 1)  
           {  
                this.x = 0;  
           }  
           if (paddleNumber == 2)  
           {  
                this.x = pong.width - width;  
           }  
           this.y = pong.height / 2 - this.height / 2;  
      }  
      public void render(Graphics g)  
      {  
           g.setColor(Color.WHITE);  
           g.fillRect(x, y, width, height);  
      }  
      public void move(boolean up)  
      {  
           int speed = 15;  
           if (up)  
           {  
                if (y - speed > 0)  
                {  
                     y -= speed;  
                }  
                else  
                {  
                     y = 0;  
                }  
           }  
           else  
           {  
                if (y + height + speed < Pong.pong.height)  
                {  
                     y += speed;  
                }  
                else  
                {  
                     y = Pong.pong.height - height;  
                }  
           }  
      }  
 }  

Class Renderer

 package pong;  
 import java.awt.Graphics;  
 import java.awt.Graphics2D;  
 import javax.swing.JPanel;  
 public class Renderer extends JPanel  
 {  
      private static final long serialVersionUID = 1L;  
      @Override  
      protected void paintComponent(Graphics g)  
      {  
           super.paintComponent(g);  
           Pong.pong.render((Graphics2D) g);  
      }  
 }  

Berikut kita akan menjalankan game Pong, maka akan mucul tampilan seperti ini


Pada game ini kita dapat memainkan dengan 2 mode, yaitu bermain dengan 2 player dan bermain dengan Bot. Score Limit berfungsi untuk menentukan berapa jumlah score yang dibutuhkan untuk memenangkan permainan.


Jika bermain dengan mode Bot kita dapat memilih tingkat kesulitan bermain.


Jika bermain dengan mode 2 player. Player 1 menggunakan tombol keyboard S dan W untuk bergerak sedangkan Player 2 menggunakan tombol Up dan Down.

-- Terima Kasih --

Minggu, 02 Desember 2018

Image Viewer 2

Image Viewer 2 ini adalah pengembangan dari image viewer sebelumnya yang juga dibuat dengan bahasa Java  menggunakan BlueJ. Berikut gambar mapping class-classnya.


Class ImageViewer

  import java.awt.*;    
  import java.awt.event.*;    
  import java.awt.image.*;    
  import javax.swing.*;    
  import javax.swing.border.*;    
  import java.io.File;    
  import java.util.List;    
  import java.util.ArrayList;    
  import java.util.Iterator;    
  /**   
  * Class utama aplikasi penampil gambar.  
  * membuat dan menampilkan GUI dan menginisialisasi komponen lainnya.  
  *   
  * @author    
  * @version   
  */   
  public class ImageViewer    
  {    
   // static fields:    
   private static final String VERSION = "Version 3.0";    
   private static JFileChooser fileChooser = new JFileChooser(System.getProperty("user.dir"));    
   // fields:    
   private JFrame frame;    
   private ImagePanel imagePanel;    
   private JLabel filenameLabel;    
   private JLabel statusLabel;    
   private JButton smallerButton;    
   private JButton largerButton;    
   private OFImage currentImage;    
   private List<Filter> filters;    
   /**    
   * Create an ImageViewer and display its GUI on screen.    
   */    
   public ImageViewer()    
   {    
   currentImage = null;    
   filters = createFilters();    
   makeFrame();    
   }    
   // ---- implementation of menu functions ----    
   /**    
   * Open function: open a file chooser to select a new image file,    
   * and then display the chosen image.    
   */    
   private void openFile()    
   {    
   int returnVal = fileChooser.showOpenDialog(frame);    
   if(returnVal != JFileChooser.APPROVE_OPTION) {    
    return; // cancelled    
   }    
   File selectedFile = fileChooser.getSelectedFile();    
   currentImage = ImageFileManager.loadImage(selectedFile);    
   if(currentImage == null) { // image file was not a valid image    
    JOptionPane.showMessageDialog(frame,    
     "The file was not in a recognized image file format.",    
     "Image Load Error",    
     JOptionPane.ERROR_MESSAGE);    
    return;    
   }    
   imagePanel.setImage(currentImage);    
   setButtonsEnabled(true);    
   showFilename(selectedFile.getPath());    
   showStatus("File loaded.");    
   frame.pack();    
   }    
   /**    
   * Close function: close the current image.    
   */    
   private void close()    
   {    
   currentImage = null;    
   imagePanel.clearImage();    
   showFilename(null);    
   setButtonsEnabled(false);    
   }    
   /**    
   * Save As function: save the current image to a file.    
   */    
   private void saveAs()    
   {    
   if(currentImage != null) {    
    int returnVal = fileChooser.showSaveDialog(frame);    
    if(returnVal != JFileChooser.APPROVE_OPTION) {    
    return; // cancelled    
    }    
    File selectedFile = fileChooser.getSelectedFile();    
    ImageFileManager.saveImage(currentImage, selectedFile);    
    showFilename(selectedFile.getPath());    
   }    
   }    
   /**    
   * Quit function: quit the application.    
   */    
   private void quit()    
   {    
   System.exit(0);    
   }    
   /**    
   * Apply a given filter to the current image.    
   *    
   * @param filter The filter object to be applied.    
   */    
   private void applyFilter(Filter filter)    
   {    
   if(currentImage != null) {    
    filter.apply(currentImage);    
    frame.repaint();    
    showStatus("Applied: " + filter.getName());    
   }    
   else {    
    showStatus("No image loaded.");    
   }    
   }    
   /**    
   * 'About' function: show the 'about' box.    
   */    
   private void showAbout()    
   {    
   JOptionPane.showMessageDialog(frame,    
     "ImageViewer\n" + VERSION,    
     "About ImageViewer",    
     JOptionPane.INFORMATION_MESSAGE);    
   }    
   /**    
   * Make the current picture larger.    
   */    
   private void makeLarger()    
   {    
   if(currentImage != null) {    
    // create new image with double size    
    int width = currentImage.getWidth();    
    int height = currentImage.getHeight();    
    OFImage newImage = new OFImage(width * 2, height * 2);    
    // copy pixel data into new image    
    for(int y = 0; y < height; y++) {    
    for(int x = 0; x < width; x++) {    
     Color col = currentImage.getPixel(x, y);    
     newImage.setPixel(x * 2, y * 2, col);    
     newImage.setPixel(x * 2 + 1, y * 2, col);    
     newImage.setPixel(x * 2, y * 2 + 1, col);    
     newImage.setPixel(x * 2+1, y * 2 + 1, col);    
    }    
    }    
    currentImage = newImage;    
    imagePanel.setImage(currentImage);    
    frame.pack();    
   }    
   }    
   /**    
   * Make the current picture smaller.    
   */    
   private void makeSmaller()    
   {    
   if(currentImage != null) {    
    // create new image with double size    
    int width = currentImage.getWidth() / 2;    
    int height = currentImage.getHeight() / 2;    
    OFImage newImage = new OFImage(width, height);    
    // copy pixel data into new image    
    for(int y = 0; y < height; y++) {    
    for(int x = 0; x < width; x++) {    
     newImage.setPixel(x, y, currentImage.getPixel(x * 2, y * 2));    
    }    
    }    
    currentImage = newImage;    
    imagePanel.setImage(currentImage);    
    frame.pack();    
   }    
   }    
   // ---- support methods ----    
   /**    
   * Show the file name of the current image in the fils display label.    
   * 'null' may be used as a parameter if no file is currently loaded.    
   *    
   * @param filename The file name to be displayed, or null for 'no file'.    
   */    
   private void showFilename(String filename)    
   {    
   if(filename == null) {    
    filenameLabel.setText("No file displayed.");    
   }    
   else {    
    filenameLabel.setText("File: " + filename);    
   }    
   }    
   /**    
   * Show a message in the status bar at the bottom of the screen.    
   * @param text The message to be displayed.    
   */    
   private void showStatus(String text)    
   {    
   statusLabel.setText(text);    
   }    
   /**    
   * Enable or disable all toolbar buttons.    
   *    
   * @param status 'true' to enable the buttons, 'false' to disable.    
   */    
   private void setButtonsEnabled(boolean status)    
   {    
   smallerButton.setEnabled(status);    
   largerButton.setEnabled(status);    
   }    
   /**    
   * Create a list with all the known filters.    
   * @return The list of filters.    
   */    
   private List<Filter> createFilters()    
   {    
   List<Filter> filterList = new ArrayList<Filter>();    
   filterList.add(new DarkerFilter("Darker"));    
   filterList.add(new LighterFilter("Lighter"));    
   filterList.add(new ThresholdFilter("Threshold"));    
   filterList.add(new FishEyeFilter("Fish Eye"));    
   return filterList;    
   }    
   // ---- swing stuff to build the frame and all its components ----    
   /**    
   * Create the Swing frame and its content.    
   */    
   private void makeFrame()    
   {    
   frame = new JFrame("ImageViewer");    
   JPanel contentPane = (JPanel)frame.getContentPane();    
   contentPane.setBorder(new EmptyBorder(6, 6, 6, 6));    
   makeMenuBar(frame);    
   // Specify the layout manager with nice spacing    
   contentPane.setLayout(new BorderLayout(6, 6));    
   // Create the image pane in the center    
   imagePanel = new ImagePanel();    
   imagePanel.setBorder(new EtchedBorder());    
   contentPane.add(imagePanel, BorderLayout.CENTER);    
   // Create two labels at top and bottom for the file name and status message    
   filenameLabel = new JLabel();    
   contentPane.add(filenameLabel, BorderLayout.NORTH);    
   statusLabel = new JLabel(VERSION);    
   contentPane.add(statusLabel, BorderLayout.SOUTH);    
   // Create the toolbar with the buttons    
   JPanel toolbar = new JPanel();    
   toolbar.setLayout(new GridLayout(0, 1));    
   smallerButton = new JButton("Smaller");    
   smallerButton.addActionListener(new ActionListener() {    
      public void actionPerformed(ActionEvent e) { makeSmaller(); }    
      });    
   toolbar.add(smallerButton);    
   largerButton = new JButton("Larger");    
   largerButton.addActionListener(new ActionListener() {    
      public void actionPerformed(ActionEvent e) { makeLarger(); }    
      });    
   toolbar.add(largerButton);    
   // Add toolbar into panel with flow layout for spacing    
   JPanel flow = new JPanel();    
   flow.add(toolbar);    
   contentPane.add(flow, BorderLayout.WEST);    
   // building is done - arrange the components     
   showFilename(null);    
   setButtonsEnabled(false);    
   frame.pack();    
   // place the frame at the center of the screen and show    
   Dimension d = Toolkit.getDefaultToolkit().getScreenSize();    
   frame.setLocation(d.width/2 - frame.getWidth()/2, d.height/2 - frame.getHeight()/2);    
   frame.setVisible(true);    
   }    
   /**    
   * Create the main frame's menu bar.    
   *    
   * @param frame The frame that the menu bar should be added to.    
   */    
   private void makeMenuBar(JFrame frame)    
   {    
   final int SHORTCUT_MASK =    
    Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();    
   JMenuBar menubar = new JMenuBar();    
   frame.setJMenuBar(menubar);    
   JMenu menu;    
   JMenuItem item;    
   // create the File menu    
   menu = new JMenu("File");    
   menubar.add(menu);    
   item = new JMenuItem("Open...");    
    item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, SHORTCUT_MASK));    
    item.addActionListener(new ActionListener() {    
      public void actionPerformed(ActionEvent e) { openFile(); }    
      });    
   menu.add(item);    
   item = new JMenuItem("Close");    
    item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_W, SHORTCUT_MASK));    
    item.addActionListener(new ActionListener() {    
      public void actionPerformed(ActionEvent e) { close(); }    
      });    
   menu.add(item);    
   menu.addSeparator();    
   item = new JMenuItem("Save As...");    
    item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, SHORTCUT_MASK));    
    item.addActionListener(new ActionListener() {    
      public void actionPerformed(ActionEvent e) { saveAs(); }    
      });    
   menu.add(item);    
   menu.addSeparator();    
   item = new JMenuItem("Quit");    
    item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, SHORTCUT_MASK));    
    item.addActionListener(new ActionListener() {    
      public void actionPerformed(ActionEvent e) { quit(); }    
      });    
   menu.add(item);    
   // create the Filter menu    
   menu = new JMenu("Filter");    
   menubar.add(menu);    
   for(final Filter filter : filters) {    
    item = new JMenuItem(filter.getName());    
    item.addActionListener(new ActionListener() {    
      public void actionPerformed(ActionEvent e) {    
       applyFilter(filter);    
      }    
      });    
    menu.add(item);    
   }    
   // create the Help menu    
   menu = new JMenu("Help");    
   menubar.add(menu);    
   item = new JMenuItem("About ImageViewer...");    
    item.addActionListener(new ActionListener() {    
      public void actionPerformed(ActionEvent e) { showAbout(); }    
      });    
   menu.add(item);    
   }    
  }  

Class ImageFileManager

  import java.awt.image.*;    
  import javax.imageio.*;    
  import java.io.*;    
  /**   
  * Class ImageFileManager dengan method statis untuk membuka dan menyimpan gambar.  
  *   
  * @author   
  * @version   
  */   
  public class ImageFileManager    
  {    
   // A constant for the image format that this writer uses for writing.    
   // Available formats are "jpg" and "png".    
   private static final String IMAGE_FORMAT = "jpg";    
   /**    
   * Read an image file from disk and return it as an image. This method    
   * can read JPG and PNG file formats. In case of any problem (e.g the file    
   * does not exist, is in an undecodable format, or any other read error)    
   * this method returns null.    
   *    
   * @param imageFile The image file to be loaded.    
   * @return  The image object or null is it could not be read.    
   */    
   public static OFImage loadImage(File imageFile)    
   {    
   try {    
    BufferedImage image = ImageIO.read(imageFile);    
    if(image == null || (image.getWidth(null) < 0)) {    
    // we could not load the image - probably invalid file format    
    return null;    
    }    
    return new OFImage(image);    
   }    
   catch(IOException exc) {    
    return null;    
   }    
   }    
   /**    
   * Write an image file to disk. The file format is JPG. In case of any    
   * problem the method just silently returns.    
   *    
   * @param image The image to be saved.    
   * @param file The file to save to.    
   */    
   public static void saveImage(OFImage image, File file)    
   {    
   try {    
    ImageIO.write(image, IMAGE_FORMAT, file);    
   }    
   catch(IOException exc) {    
    return;    
   }    
   }    
  }  

Class ImagePanel

  import java.awt.*;    
  import javax.swing.*;    
  import java.awt.image.*;    
  /**   
  * Class ImagePanel sebuah swing component yang dapat menampilkan sebuah OFImage.  
  *   
  * @author   
  * @version   
  */   
  public class ImagePanel extends JComponent    
  {    
   // The current width and height of this panel    
   private int width, height;    
   // An internal image buffer that is used for painting. For    
   // actual display, this image buffer is then copied to screen.    
   private OFImage panelImage;    
   /**    
   * Create a new, empty ImagePanel.    
   */    
   public ImagePanel()    
   {    
   width = 360; // arbitrary size for empty panel    
   height = 240;    
   panelImage = null;    
   }    
   /**    
   * Set the image that this panel should show.    
   *    
   * @param image The image to be displayed.    
   */    
   public void setImage(OFImage image)    
   {    
   if(image != null) {    
    width = image.getWidth();    
    height = image.getHeight();    
    panelImage = image;    
    repaint();    
   }    
   }    
   /**    
   * Clear the image on this panel.    
   */    
   public void clearImage()    
   {    
   Graphics imageGraphics = panelImage.getGraphics();    
   imageGraphics.setColor(Color.LIGHT_GRAY);    
   imageGraphics.fillRect(0, 0, width, height);    
   repaint();    
   }    
   // The following methods are redefinitions of methods    
   // inherited from superclasses.    
   /**    
   * Tell the layout manager how big we would like to be.    
   * (This method gets called by layout managers for placing    
   * the components.)    
   *    
   * @return The preferred dimension for this component.    
   */    
   public Dimension getPreferredSize()    
   {    
   return new Dimension(width, height);    
   }    
   /**    
   * This component needs to be redisplayed. Copy the internal image    
   * to screen. (This method gets called by the Swing screen painter    
   * every time it want this component displayed.)    
   *    
   * @param g The graphics context that can be used to draw on this component.    
   */    
   public void paintComponent(Graphics g)    
   {    
   Dimension size = getSize();    
   g.clearRect(0, 0, size.width, size.height);    
   if(panelImage != null) {    
    g.drawImage(panelImage, 0, 0, null);    
   }    
   }    
  }  

Class OFImage

  import java.awt.*;    
  import java.awt.image.*;    
  import javax.swing.*;    
  /**   
  * class OFImage untuk mendefinisikan sebuah image dalam format object first.  
  *   
  * @author   
  * @version   
  */   
  public class OFImage extends BufferedImage    
  {    
   /**    
   * Create an OFImage copied from a BufferedImage.    
   * @param image The image to copy.    
   */    
   public OFImage(BufferedImage image)    
   {    
   super(image.getColorModel(), image.copyData(null),    
    image.isAlphaPremultiplied(), null);    
   }    
   /**    
   * Create an OFImage with specified size and unspecified content.    
   * @param width The width of the image.    
   * @param height The height of the image.    
   */    
   public OFImage(int width, int height)    
   {    
   super(width, height, TYPE_INT_RGB);    
   }    
   /**    
   * Set a given pixel of this image to a specified color. The    
   * color is represented as an (r,g,b) value.    
   * @param x The x position of the pixel.    
   * @param y The y position of the pixel.    
   * @param col The color of the pixel.    
   */    
   public void setPixel(int x, int y, Color col)    
   {    
   int pixel = col.getRGB();    
   setRGB(x, y, pixel);    
   }    
   /**    
   * Get the color value at a specified pixel position.    
   * @param x The x position of the pixel.    
   * @param y The y position of the pixel.    
   * @return The color of the pixel at the given position.    
   */    
   public Color getPixel(int x, int y)    
   {    
   int pixel = getRGB(x, y);    
   return new Color(pixel);    
   }    
  }  

Class Filter

  /**   
  * Class Filter untuk menambahkan filter pada gambar  
  *   
  * @author   
  * @version   
  */   
  public abstract class Filter    
  {    
   private String name;    
   /**    
   * Create a new filter with a given name.    
   * @param name The name of the filter.    
   */    
   public Filter(String name)    
   {    
   this.name = name;    
   }    
   /**    
   * Return the name of this filter.    
   *    
   * @return The name of this filter.    
   */    
   public String getName()    
   {    
   return name;    
   }    
   /**    
   * Apply this filter to an image.    
   *    
   * @param image The image to be changed by this filter.    
   */    
   public abstract void apply(OFImage image);    
  }  

Class DarkerFilter

  /**   
  *   
  *   
  * @author   
  * @version   
  */   
  public class DarkerFilter extends Filter    
  {    
   /**    
   * Constructor for objects of class DarkerFilter.    
   * @param name The name of the filter.    
   */    
   public DarkerFilter(String name)    
   {    
   super(name);    
   }    
   /**    
   * Apply this filter to an image.    
   *    
   * @param image The image to be changed by this filter.    
   */    
   public void apply(OFImage image)    
   {    
   int height = image.getHeight();    
   int width = image.getWidth();    
   for(int y = 0; y < height; y++) {    
    for(int x = 0; x < width; x++) {    
    image.setPixel(x, y, image.getPixel(x, y).darker());    
    }    
   }    
   }    
  }  

Class LighterFilter

  /**   
  *   
  *   
  * @author   
  * @version   
  */   
  public class LighterFilter extends Filter    
  {    
   /**    
    * Constructor for objects of class LighterFilter.    
   * @param name The name of the filter.    
    */    
   public LighterFilter(String name)    
   {    
   super(name);    
   }    
   /**    
   * Apply this filter to an image.    
   *    
   * @param image The image to be changed by this filter.    
   */    
   public void apply(OFImage image)    
   {    
   int height = image.getHeight();    
   int width = image.getWidth();    
   for(int y = 0; y < height; y++) {    
    for(int x = 0; x < width; x++) {    
    image.setPixel(x, y, image.getPixel(x, y).brighter());    
    }    
   }    
   }    
  }  

Class ThresholdFilter

  import java.awt.Color;   
  /**   
  * Write a description of class ThresfoldFilter here.   
  *   
  * @author   
  * @version   
  */   
  public class ThresholdFilter extends Filter    
  {    
   /**    
    * Constructor for objects of class ThresholdFilter.    
   * @param name The name of the filter.    
    */    
   public ThresholdFilter(String name)    
   {    
   super(name);    
   }    
   /**    
   * Apply this filter to an image.    
   *    
   * @param image The image to be changed by this filter.    
   */    
   public void apply(OFImage image)    
   {    
   int height = image.getHeight();    
   int width = image.getWidth();    
   for(int y = 0; y < height; y++) {    
    for(int x = 0; x < width; x++) {    
    Color pixel = image.getPixel(x, y);    
    int brightness = (pixel.getRed() + pixel.getBlue() + pixel.getGreen()) / 3;    
    if(brightness <= 85) {    
     image.setPixel(x, y, Color.BLACK);    
    }    
    else if(brightness <= 170) {    
     image.setPixel(x, y, Color.GRAY);    
    }    
    else {    
     image.setPixel(x, y, Color.WHITE);    
    }    
    }    
   }    
   }    
  }  

Class FishEyeFilter

  import java.awt.Color;    
  /**   
  *   
  *   
  * @author   
  * @version   
  */   
  public class FishEyeFilter extends Filter    
  {    
   // constants:    
   private final static int SCALE = 20; // this defines the strenght of the filter    
   private final static double TWO_PI = 2 * Math.PI;    
   /**    
   * Constructor for objects of class LensFilter.    
   * @param name The name of the filter.    
   */    
   public FishEyeFilter(String name)    
   {    
   super(name);    
   }    
   /**    
   * Apply this filter to an image.    
   *    
   * @param image The image to be changed by this filter.    
   */    
   public void apply(OFImage image)    
   {    
   int height = image.getHeight();    
   int width = image.getWidth();    
   OFImage original = new OFImage(image);    
   int[] xa = computeXArray(width);    
   int[] ya = computeYArray(height);    
   for(int y = 0; y < height; y++) {    
    for(int x = 0; x < width; x++) {    
    image.setPixel(x, y, original.getPixel(x + xa[x], y + ya[y]));    
    }    
   }    
   }    
   /**    
   * Compute and return an array of horizontal offsets for each pixel column.    
   * These can then be applied as the horizontal offset for each pixel.    
   */    
   private int[] computeXArray(int width)    
   {    
   int[] xArray = new int[width];    
   for(int i=0; i < width; i++) {    
    xArray[i] = (int)(Math.sin( ((double)i / width) * TWO_PI) * SCALE);    
   }    
   return xArray;    
   }    
   /**    
   * Compute and return an array of vertical offsets for each pixel row.    
   * These can then be applied as the vertical offset for each pixel.    
   */    
   private int[] computeYArray(int height)    
   {    
   int[] yArray = new int[height];    
   for(int i=0; i < height; i++) {    
    yArray[i] = (int)(Math.sin( ((double)i / height) * TWO_PI) * SCALE);    
   }    
   return yArray;    
   }    
  }  

Berikut ini kita akan menjalankan aplikasi Image Viewer 2


Kita akan mencoba beberapa fitur yang dimiliki oleh Image Viewer 2 ini.

Larger (Memperbesar ukuran gambar)


Smaller (Memperkecil ukuran gambar)


Menerapkan filter Darker pada gambar


Menerapkan filter Lighter pada gambar


Menerapkan filter Threshold pada gambar


Menerapkan filter Fish Eye pada gambar


-- Terima Kasih --

Senin, 26 November 2018

Image Viewer

Pada kali ini kami mendapat tugas untuk membuat sebuah image viewer menggunakan BlueJ. Aplikasi ini memiliki fitur filter. Berikut hasil dan source codenya.



Class OFImage

 import java.awt.*;   
 import java.awt.image.*;   
 import javax.swing.*;   
 /**   
  * class OFImage untuk mendefinisikan sebuah image dalam format object first.  
  *   
  * @author Ismail   
  * @version 26112018  
  */   
 public class OFImage extends BufferedImage   
 {  
    /**   
    * Create an OFImage copied from a BufferedImage.   
    * @param image The image to copy.   
    */   
    public OFImage(BufferedImage image)   
    {   
      super(image.getColorModel(), image.copyData(null),    
       image.isAlphaPremultiplied(), null);   
    }   
    /**   
    * Create an OFImage with specified size and unspecified content.   
    * @param width The width of the image.   
    * @param height The height of the image.   
    */   
    public OFImage(int width, int height)   
    {   
      super(width, height, TYPE_INT_RGB);   
    }     
    /**   
    * Set a given pixel of this image to a specified color. The   
    * color is represented as an (r,g,b) value.   
    * @param x The x position of the pixel.   
    * @param y The y position of the pixel.   
    * @param col The color of the pixel.   
    */   
    public void setPixel(int x, int y, Color col)   
    {   
      int pixel = col.getRGB();   
      setRGB(x, y, pixel);   
    }   
    /**   
    * Get the color value at a specified pixel position.   
    * @param x The x position of the pixel.   
    * @param y The y position of the pixel.   
    * @return The color of the pixel at the given position.   
    */   
    public Color getPixel(int x, int y)   
    {   
      int pixel = getRGB(x, y);   
      return new Color(pixel);   
    }   
    /**   
    * Make this image a bit darker.   
    */   
    public void darker()   
    {   
      int height = getHeight();   
      int width = getWidth();   
      for(int y = 0; y < height; y++) {   
        for(int x = 0; x < width; x++) {   
          setPixel(x, y, getPixel(x, y).darker());   
        }   
      }   
    }   
    /**   
     * Make this image a bit lighter.   
     */   
    public void lighter()   
    {   
      int height = getHeight();   
      int width = getWidth();   
      for(int y = 0; y < height; y++) {   
        for(int x = 0; x < width; x++) {   
          setPixel(x, y, getPixel(x, y).brighter());   
        }   
      }   
    }   
    /**   
    * Perform a three level threshold operation.   
    * That is: repaint the image with only three color values:   
    *   white, gray, and black.   
    */   
    public void threshold()   
    {   
      int height = getHeight();   
      int width = getWidth();   
      for(int y = 0; y < height; y++) {   
        for(int x = 0; x < width; x++) {   
          Color pixel = getPixel(x, y);   
          int brightness = (pixel.getRed() + pixel.getBlue() + pixel.getGreen()) / 3;   
          if(brightness <= 85) {   
            setPixel(x, y, Color.BLACK);   
          }   
          else if(brightness <= 170) {   
            setPixel(x, y, Color.GRAY);   
          }   
          else {   
            setPixel(x, y, Color.WHITE);   
          }   
        }   
      }   
    }   
 }   

Class ImagePanel

 import java.awt.*;   
 import javax.swing.*;   
 import java.awt.image.*;   
 /**   
  * Class ImagePanel sebuah swing component yang dapat menampilkan sebuah OFImage.    
  *    
  * @author Ismail   
  * @version 26112018  
  */   
 public class ImagePanel extends JComponent   
 {  
   // The current width and height of this panel   
   private int width, height;   
   // An internal image buffer that is used for painting. For   
   // actual display, this image buffer is then copied to screen.   
   private OFImage panelImage;   
   /**   
    * Create a new, empty ImagePanel.   
    */   
   public ImagePanel()   
   {  
     width = 360; // arbitrary size for empty panel   
     height = 240;   
     panelImage = null;   
   }   
   /**   
    * Set the image that this panel should show.   
    *    
    * @param image The image to be displayed.   
    */   
   public void setImage(OFImage image)   
   {   
     if(image != null) {   
       width = image.getWidth();   
       height = image.getHeight();   
       panelImage = image;   
       repaint();   
     }   
   }   
   /**   
    * Clear the image on this panel.   
    */   
   public void clearImage()   
   {   
     Graphics imageGraphics = panelImage.getGraphics();   
     imageGraphics.setColor(Color.LIGHT_GRAY);   
     imageGraphics.fillRect(0, 0, width, height);   
     repaint();   
   }   
   // The following methods are redefinitions of methods   
   // inherited from superclasses.   
   /**   
    * Tell the layout manager how big we would like to be.   
    * (This method gets called by layout managers for placing   
    * the components.)   
    *    
    * @return The preferred dimension for this component.   
    */   
   public Dimension getPreferredSize()   
   {  
     return new Dimension(width, height);   
   }   
   /**   
    * This component needs to be redisplayed. Copy the internal image    
    * to screen. (This method gets called by the Swing screen painter    
    * every time it want this component displayed.)   
    *    
    * @param g The graphics context that can be used to draw on this component.   
    */   
   public void paintComponent(Graphics g)   
   {   
     Dimension size = getSize();   
     g.clearRect(0, 0, size.width, size.height);   
     if(panelImage != null) {   
       g.drawImage(panelImage, 0, 0, null);   
     }   
   }   
 }   

Class ImageFileManager

 import java.awt.image.*;   
 import javax.imageio.*;   
 import java.io.*;   
 /**   
  * Class ImageFileManager dengan method statis untuk membuka dan menyimpan gambar.  
  *    
  * @author Ismail  
  * @version 26112018  
  */   
 public class ImageFileManager   
 {  
   // A constant for the image format that this writer uses for writing.   
   // Available formats are "jpg" and "png".   
   private static final String IMAGE_FORMAT = "jpg";   
   /**   
    * Read an image file from disk and return it as an image. This method   
    * can read JPG and PNG file formats. In case of any problem (e.g the file    
    * does not exist, is in an undecodable format, or any other read error)    
    * this method returns null.   
    *    
    * @param imageFile The image file to be loaded.   
    * @return   The image object or null is it could not be read.   
    */   
   public static OFImage loadImage(File imageFile)   
   {  
     try {   
       BufferedImage image = ImageIO.read(imageFile);   
       if(image == null || (image.getWidth(null) < 0)) {   
         // we could not load the image - probably invalid file format   
         return null;   
       }   
     return new OFImage(image);  
     }   
     catch(IOException exc) {   
       return null;   
     }   
   }   
   /**   
    * Write an image file to disk. The file format is JPG. In case of any    
    * problem the method just silently returns.   
    *    
    * @param image The image to be saved.   
    * @param file The file to save to.   
    */   
   public static void saveImage(OFImage image, File file)   
   {   
     try {   
       ImageIO.write(image, IMAGE_FORMAT, file);   
     }   
     catch(IOException exc) {   
       return;   
     }   
   }   
 }   

Class ImageViewer

 import java.awt.*;   
 import java.awt.event.*;   
 import java.awt.image.*;   
 import javax.swing.*;   
 import java.io.File;   
 /**   
  * Class utama aplikasi penampil gambar.  
  * membuat dan menampilkan GUI dan menginisialisasi komponen lainnya.  
  *  
  * @author Ismail  
  * @version 26112018  
  */   
  public class ImageViewer   
  {  
    // static fields:   
    private static final String VERSION = "Version 1.0";   
    private static JFileChooser fileChooser = new JFileChooser(System.getProperty("user.dir"));   
    // fields:   
    private JFrame frame;   
    private ImagePanel imagePanel;   
    private JLabel filenameLabel;   
    private JLabel statusLabel;   
    private OFImage currentImage;   
    /**   
    * Create an ImageViewer show it on screen.   
    */   
    public ImageViewer()   
    {  
      currentImage = null;   
      makeFrame();   
    }   
    // ---- implementation of menu functions ----   
    /**   
    * Open function: open a file chooser to select a new image file.   
    */   
    private void openFile()   
    {  
      int returnVal = fileChooser.showOpenDialog(frame);   
      if(returnVal != JFileChooser.APPROVE_OPTION) {   
        return; // cancelled   
      }   
      File selectedFile = fileChooser.getSelectedFile();   
      currentImage = ImageFileManager.loadImage(selectedFile);   
      if(currentImage == null) { // image file was not a valid image   
        JOptionPane.showMessageDialog(frame,   
        "The file was not in a recognized image file format.",   
        "Image Load Error",   
        JOptionPane.ERROR_MESSAGE);   
        return;   
      }   
      imagePanel.setImage(currentImage);   
      showFilename(selectedFile.getPath());   
      showStatus("File loaded.");   
      frame.pack();   
     }   
     /**   
      * Close function: close the current image.   
      */   
    private void close()   
    {  
      currentImage = null;   
      imagePanel.clearImage();   
      showFilename(null);   
    }   
    /**   
    * Quit function: quit the application.   
    */   
    private void quit()   
    {  
      System.exit(0);  
    }   
    /**   
    * 'Darker' function: make the picture darker.   
    */   
    private void makeDarker()   
    {  
      if(currentImage != null) {   
        currentImage.darker();   
        frame.repaint();   
        showStatus("Applied: darker");  
      }   
      else {  
        showStatus("No image loaded.");   
      }   
     }   
    /**   
    * 'Lighter' function: make the picture lighter   
    */   
    private void makeLighter()   
    {  
      if(currentImage != null) {   
        currentImage.lighter();   
        frame.repaint();   
        showStatus("Applied: lighter");   
      }   
      else {  
        showStatus("No image loaded.");   
      }   
     }   
    /**   
    * 'threshold' function: apply the threshold filter   
    */   
    private void threshold()   
    {  
      if(currentImage != null) {   
        currentImage.threshold();   
        frame.repaint();   
        showStatus("Applied: threshold");   
      }   
      else {   
        showStatus("No image loaded.");   
      }   
    }   
    /**   
    * 'Lighter' function: make the picture lighter   
    */   
    private void showAbout()   
    {   
      JOptionPane.showMessageDialog(frame,    
       "ImageViewer\n" + VERSION,   
       "About ImageViewer",    
       JOptionPane.INFORMATION_MESSAGE);   
    }   
    // ---- support methods ----   
    /**   
    * Display a file name on the appropriate label.   
    * @param filename The file name to be displayed.   
    */   
    private void showFilename(String filename)   
    {   
      if(filename == null) {   
        filenameLabel.setText("No file displayed.");   
      }   
      else {   
        filenameLabel.setText("File: " + filename);   
      }   
    }   
    /**   
    * Display a status message in the frame's status bar.   
    * @param text The status message to be displayed.   
    */   
    private void showStatus(String text)   
    {   
      statusLabel.setText(text);   
    }   
    // ---- swing stuff to build the frame and all its components ----   
    /**   
    * Create the Swing frame and its content.   
    */   
    private void makeFrame()   
    {   
      frame = new JFrame("ImageViewer");   
      makeMenuBar(frame);   
      Container contentPane = frame.getContentPane();   
      // Specify the layout manager with nice spacing   
      contentPane.setLayout(new BorderLayout(6, 6));   
      filenameLabel = new JLabel();   
      contentPane.add(filenameLabel, BorderLayout.NORTH);   
      imagePanel = new ImagePanel();   
      contentPane.add(imagePanel, BorderLayout.CENTER);   
      statusLabel = new JLabel(VERSION);   
      contentPane.add(statusLabel, BorderLayout.SOUTH);   
      // building is done - arrange the components and show     
      showFilename(null);   
      frame.pack();   
      Dimension d = Toolkit.getDefaultToolkit().getScreenSize();   
      frame.setLocation(d.width/2 - frame.getWidth()/2, d.height/2 - frame.getHeight()/2);   
      frame.setVisible(true);   
    }     
    /**   
    * Create the main frame's menu bar.   
    * @param frame The frame that the menu bar should be added to.   
    */   
    private void makeMenuBar(JFrame frame)   
    {   
      final int SHORTCUT_MASK =   
       Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();   
      JMenuBar menubar = new JMenuBar();   
      frame.setJMenuBar(menubar);   
      JMenu menu;   
      JMenuItem item;   
      // create the File menu   
      menu = new JMenu("File");   
      menubar.add(menu);   
      item = new JMenuItem("Open");   
       item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, SHORTCUT_MASK));   
       item.addActionListener(new ActionListener() {  
         public void actionPerformed(ActionEvent e) { openFile(); }   
       });   
      menu.add(item);   
      item = new JMenuItem("Close");   
       item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_W, SHORTCUT_MASK));   
       item.addActionListener(new ActionListener() {   
         public void actionPerformed(ActionEvent e) { close(); }   
       });   
      menu.add(item);   
      menu.addSeparator();   
      item = new JMenuItem("Quit");   
       item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, SHORTCUT_MASK));   
       item.addActionListener(new ActionListener() {   
         public void actionPerformed(ActionEvent e) { quit(); }   
       });   
      menu.add(item);   
      // create the Filter menu   
      menu = new JMenu("Filter");   
      menubar.add(menu);   
      item = new JMenuItem("Darker");   
       item.addActionListener(new ActionListener() {   
         public void actionPerformed(ActionEvent e) { makeDarker(); }   
       });   
      menu.add(item);   
      item = new JMenuItem("Lighter");   
       item.addActionListener(new ActionListener() {   
         public void actionPerformed(ActionEvent e) { makeLighter(); }   
       });   
      menu.add(item);   
      item = new JMenuItem("Threshold");   
       item.addActionListener(new ActionListener() {   
         public void actionPerformed(ActionEvent e) { threshold(); }   
       });   
      menu.add(item);   
      // create the Help menu   
      menu = new JMenu("Help");   
      menubar.add(menu);   
      item = new JMenuItem("About ImageViewer...");   
       item.addActionListener(new ActionListener() {   
         public void actionPerformed(ActionEvent e) { showAbout(); }   
       });   
      menu.add(item);   
   }   
 }   


Berikut ini kita akan menjalankan Aplikasi ImageViewer




Untuk membuka gambar klik File lalu pilih Open dan pilih gambar yang ingin ditampilkan


Kita juga dapat menambahkan Filter pada gambar yang kita tampilkan seperti dibawah ini



-- Terima Kasih --

EAS PBO B

1. Rancangan interface image editor. 2. Class diagram dari image editor yang akan dibuat terdiri atas 10 class seperti berikut. ...