Senin, 10 Desember 2018

EAS PBO
Membuat Image Editor

Nama = Chaniyah Zulfa Mukhlishah
NRP   = 05111740000115
Kelas = PBO-B

Soal =
  1. Gambarkan rancangan interfacenya.
  2. Gambarkan dan jelaskan Class Diagram penyusun dari image viewer yang akan dibuat.
  3. Implementasikan ke dalam program dan buat linknya.
Jawab =
  • Rancangan Interface
  • Class Diagram

      Explanation =
    1. ImageViewer: Sebagai Main Class. Image Viewer menampilkan GUI dan mengenalkan semua komponen lainnya. Seperti crop,text,rotate editor juga dimuat pada ImageViewer. Untuk menge-run pun kita membuat objek dari Class ini.
    2. ImageFileManager: Class untuk memuat dan menyimpan gambar dengan format gambar .jpg atau .png.
    3. ImagePanel: Komponen yang menampilkan OFImage. ImagePanel adalah subkelas JComponent dengan tambahan fungsi pengaturan OFImage yang akan ditampilkan pada permukaan komponen ini.
    4. OFImage: Mendefine gambar dalam format Objects First.
    5. Filter : Superclass abstrak untuk menampung semua filter gambar yang terdiri dari Darker,Treshold,Lighter,dan FishEye. Filter diterapkan ke OFImages.
    6. DarkerFilter: Filter untuk membuat gambar terlihat lebih gelap.
    7. TresholdFilter: Filter tingkat berbasis abu-abu.
    8. LighterFilter: Filter gambar untuk membuat gambar terlihat lebih terang.
    9. FishEyeFilter: Filter gambar untuk membuat efek mirip dengan lensa kamera mata ikan.
  • Program 
- 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;  
 /**   
  * Chaniyah Zulfa Mukhlishah   
  * 10-Des-18  
  */  
 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();  
     }  
   }  
   private void makeCrop()  
   {  
     if (currentImage != null)  
     {  
       int width = currentImage.getWidth();  
       int height = currentImage.getWidth();  
       int xAwal = Integer.parseInt(JOptionPane.showInputDialog("xAwal"));  
       int yAwal = Integer.parseInt(JOptionPane.showInputDialog("yAwal"));  
       int xAkhir = Integer.parseInt(JOptionPane.showInputDialog("xAkhir"));  
       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();  
     }  
   }  
   private void makeText()  
   {  
     JTextField xField = new JTextField(5);  
     JTextField yField = new JTextField(5);  
     JTextField zField = new JTextField(5);  
     JPanel myPanel = new JPanel();  
     myPanel.add(new JLabel("R"));  
     myPanel.add(xField);  
     myPanel.add(Box.createVerticalStrut(15)); // a spacer  
     myPanel.add(new JLabel("G"));  
     myPanel.add(yField);  
     myPanel.add(Box.createVerticalStrut(15)); // a spacer  
     myPanel.add(new JLabel("B"));  
     myPanel.add(zField);  
     if(currentImage != null) {  
       int width = currentImage.getWidth();  
       int height = currentImage.getHeight();  
       int xPosition = Integer.parseInt(JOptionPane.showInputDialog("Posisi X"));  
       int yPosition = Integer.parseInt(JOptionPane.showInputDialog("Posisi Y"));  
       float fontSize = Float.parseFloat(JOptionPane.showInputDialog("Ukuran font"));  
       String addText = JOptionPane.showInputDialog("Tuliskan sesuatu...");  
       int result = JOptionPane.showConfirmDialog(null, myPanel, "Warna font", JOptionPane.OK_CANCEL_OPTION);  
       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++) {  
           Color col = currentImage.getPixel(x, y);  
           newImage.setPixel(x, y, col);  
         }  
       }  
       int r = Integer.parseInt(xField.getText());  
       int gr = Integer.parseInt(yField.getText());  
       int b = Integer.parseInt(zField.getText());  
       Color c = new Color(r,gr,b);  
       Graphics g = newImage.getGraphics();  
       g.setFont(g.getFont().deriveFont(fontSize));  
       g.setColor(c);  
       g.drawString(addText, xPosition, yPosition);  
       g.dispose();  
       currentImage = newImage;  
       imagePanel.setImage(currentImage);  
     }  
   }  
   private void Rotate180() {  
     if(currentImage != null) {  
       // create new image with double size  
       int width = currentImage.getWidth();  
       int height = currentImage.getHeight();  
       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++) {  
           Color col = currentImage.getPixel(width-x-1, height-y-1);  
           newImage.setPixel(x, y, col);  
         }  
       }  
       currentImage = newImage;  
       imagePanel.setImage(currentImage);  
       frame.pack();  
     }  
   }  
   private void Rotate90left() {  
     if(currentImage != null) {  
       // create new image with double size  
       int width = currentImage.getWidth();  
       int height = currentImage.getHeight();  
       OFImage newImage = new OFImage(height, width);  
       //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(y, width-x-1, col);  
         }  
       }  
       currentImage = newImage;  
       imagePanel.setImage(currentImage);  
       frame.pack();  
     }  
   }  
   private void Rotate90right() {  
     if(currentImage != null) {  
       // create new image with double size  
       int width = currentImage.getWidth();  
       int height = currentImage.getHeight();  
       OFImage newImage = new OFImage(height, width);  
       //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(height-y-1, x, col);  
         }  
       }  
       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);  
      }  
     menu = new JMenu("Crop");  
     menubar.add(menu);  
     item = new JMenuItem("Crop Image");  
       item.addActionListener(new ActionListener()   
       {  
         public void actionPerformed(ActionEvent e) { makeCrop(); }  
       });  
     menu.add(item);  
     menu = new JMenu("Text");  
     menubar.add(menu);  
     item = new JMenuItem("Add Text");  
       item.addActionListener(new ActionListener()   
       {  
       public void actionPerformed(ActionEvent e) { makeText(); }  
     });  
     menu.add(item);  
     menu = new JMenu("Rotate");  
     menubar.add(menu);  
     item = new JMenuItem("Rotate 180");  
       item.addActionListener(new ActionListener() {  
                 public void actionPerformed(ActionEvent e) { Rotate180(); }  
               });  
     menu.add(item);  
     item = new JMenuItem("Rotate 90 Left");  
       item.addActionListener(new ActionListener() {  
                 public void actionPerformed(ActionEvent e) { Rotate90left(); }  
               });  
     menu.add(item);  
     item = new JMenuItem("Rotate 90 Right");  
       item.addActionListener(new ActionListener() {  
                 public void actionPerformed(ActionEvent e) { Rotate90right(); }  
               });  
     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.*;   
  /**   
  * Chaniyah Zulfa Mukhlishah   
  * 10-Des-18  
  */   
  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 ImagePlanel


 import java.awt.*;   
  import javax.swing.*;   
  import java.awt.image.*;   
  /**   
  * Chaniyah Zulfa Mukhlishah   
  * 10-Des-18  
  */    
  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.*;   
  /**   
  * Chaniyah Zulfa Mukhlishah   
  * 10-Des-18  
  */    
  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


  /**   
  * Chaniyah Zulfa Mukhlishah   
  * 10-Des-18  
  */    
  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 LighterFilter


 /**   
  * Chaniyah Zulfa Mukhlishah   
  * 10-Des-18  
  */   
  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 FishEyeFilter


  import java.awt.Color;   
  /**   
  * Chaniyah Zulfa Mukhlishah   
  * 10-Des-18  
  */   
  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 ThresholdFilter


 import java.awt.Color;   
  /**   
  * Chaniyah Zulfa Mukhlishah   
  * 10-Des-18  
  */    
  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 DarkFilter



 /**   
  * Chaniyah Zulfa Mukhlishah   
  * 10-Des-18  
  */   
  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());   
     }   
    }   
   }   
  }   

Thanks All, semoga bermanfaat :))

Minggu, 02 Desember 2018

GAME PONG
Nama = Chaniyah Zulfa Mukhlishah
NRP   = 05111740000115

Tugas kali ini adalah membuat game pong dari blueJ, yang membutuhkan 4 Class, yaitu =
1.  Ball
2. Paddle
3. Renderer
4. Pong

Source Code untuk tiap class adalah sebagai berikut :
1.) Class Ball

 /**  
  * @author Chaniyah Zulfa Mukhlishah  
  * @version 03-Dec-18  
  */  
 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;    
    }   
    public void render(Graphics g)   
    {   
       g.setColor(Color.WHITE);   
       g.fillOval(x, y, width, height);   
    }   
  }   

2.) Class Paddle

 /**  
  * @author Chaniyah Zulfa Mukhlishah  
  * @version 03-Dec-18  
  */  
 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;   
     }   
    }   
   }   
  }   

3.) Class Renderer

 /**  
  * @author Chaniyah Zulfa Mukhlishah  
  * @version 03-Dec-18  
  */  
 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);   
   }   
  }   

4.) Class Pong

 /**  
  * @author Chaniyah Zulfa Mukhlishah  
  * @version 03-Dec-18  
  */  
  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 = 1;   
            }   
            if (botDifficulty == 1)   
            {   
              botCooldown = 15;   
            }   
            if (botDifficulty == 2)   
            {   
              botCooldown = 10;   
            }   
         }   
       }   
       ball.update(player1, player2);   
    }   
    public void render(Graphics2D g)   
    {   
       g.setColor(Color.BLACK);   
       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)   
    {   
    }   
  }   

Running =


Pertama, run pada Class pong
----------------------------------------------------------------------------------------


Untuk bermain dengan bot, klik "Shift" pada keyboard
------------------------------------------------------------------------------------------


Pilihlah level dari Easy, Medium, atau Hard sesuai selera
------------------------------------------------------------------------------------------------


Untuk menggeser penangkap bola klik S(kebawah) dan W(keatas)
---------------------------------------------------------------------------------------------------


Hasil keluar jika salah satu poin = 7
--------------------------------------------------------------------------------------------- 

Thanks all :) Semoga bermanfaat !!

Minggu, 25 November 2018

IMAGE VIEWER
Nama : Chaniyah Zulfa Mukhlishah
NRP   : 05111740000115

Tugas kali ini saya membuat Image Viewer dengan menggunakan GUI. GUI sendiri adalah Graphical User Interface. Pada tugas ini, dibutuhkan delapan class, yaitu : ImageViewer, ImagePanel, ImageFileManager, OFImage, LighterFilter, DarkerFilter, TresholdFilter, dan Filter.


Source Code setiap class =

1.) ImageViewer

  import java.awt.*;   
  import java.awt.event.*;   
  import java.awt.image.*;   
  import javax.swing.*;   
  import java.io.File;   
  /**   
  * ImageViewer is the main class of the image viewer application. It builds and   
  * displays the application GUI and initialises all other components.   
  *    
  * To start the application, create an object of this class.   
  *    
  * @author Chaniyah Zulfa MUkhlishah   
  * @version 26-Nov-18   
  */   
  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);   
   }   
  }   

2.) ImagePanel

  import java.awt.*;   
  import javax.swing.*;   
  import java.awt.image.*;   
  /**   
  * An ImagePanel is a Swing component that can display an OFImage.   
  * It is constructed as a subclass of JComponent with the added functionality   
  * of setting an OFImage that will be displayed on the surface of this   
  * component.   
  *    
  * @author Chaniyah Zulfa MUkhlishah   
  * @version 26-Nov-18   
  */   
  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);   
    }   
   }   
  }   

3.)ImageFileManager

 import java.awt.image.*;   
  import javax.imageio.*;   
  import java.io.*;   
  /**   
  * ImageFileManager is a small utility class with static methods to load   
  * and save images.   
  *    
  * The files on disk can be in JPG or PNG image format. For files written   
  * by this class, the format is determined by the constant IMAGE_FORMAT.   
  *    
  * @author Chaniyah Zulfa MUkhlishah   
  * @version 26-Nov-18   
  */   
  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;   
    }   
   }   
  }   

4.) OFImage

  import java.awt.*;   
  import java.awt.image.*;   
  import javax.swing.*;   
  /**   
  * OFImage is a class that defines an image in OF (Objects First) format.   
  *    
  * @author Chaniyah Zulfa MUkhlishah   
  * @version 26-Nov-18   
  */   
  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);   
   }   
  }   

5.) Lighter Filter


  import java.awt.*;   
  import javax.swing.*;   
  import java.awt.image.*;   
  /**   
  * Class Filter for choosing the lighter filter  
  * @author Chaniyah Zulfa MUkhlishah   
  * @version 26-Nov-18   
  */   
 public class LighterFilter extends Filter  
 {  
   /**   
   * Make this image a bit lighter.  
   */  
   public LighterFilter(String name)  
   {  
     super(name);  
   }  
   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());   
     }   
    }   
   }  
 }  

6.) Darker Filter


  import java.awt.*;   
  import javax.swing.*;   
  import java.awt.image.*;   
  /**   
  * Class DarkerFilter for choosing the dark filter  
  * @author Chaniyah Zulfa MUkhlishah   
  * @version 26-Nov-18   
  */   
 public class DarkerFilter extends Filter  
 {  
   public DarkerFilter(String name)  
   {  
     super(name);  
   }  
   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());  
     }  
     }  
   }  
 }  

7.) Treshold Filter


  import java.awt.*;   
  import javax.swing.*;   
  import java.awt.image.*;   
  /**   
  * Class DarkerFilter for choosing the treshold filter  
  * @author Chaniyah Zulfa MUkhlishah   
  * @version 26-Nov-18   
  */   
 public class TresholdFilter extends Filter  
 {  
   public TresholdFilter(String name)  
   {  
     super(name);  
   }  
   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);   
      }   
     }   
    }  
   }  
 }  

8.) Filter

  import java.awt.*;   
  import javax.swing.*;   
  import java.awt.image.*;   
  /**   
  * Class Filter for choosing the best filter which you wanted  
  * @author Chaniyah Zulfa MUkhlishah   
  * @version 26-Nov-18   
  */   
 public abstract class Filter  
 {  
   private String name;  
   /**  
   * Create a new filter with a given name.  
   */  
   public Filter(String name)  
   {  
     this.name = name;  
   }  
   /**  
   * Return the name of this filter.  
   *  
   * @return The name of this filter.  
   */  
   public String getName()  
   {  
     return name;  
   }  
   public abstract void apply(OFImage image);  
 }  

Untuk menghasilkan Image Viewer (menampilkan gambar), pertama tama kita membuat new ImageViewer
-------------------------------------------------------------------------------------------------------------------------
Lalu, kita run sehingga hasil awal belum menampilkan apapun
------------------------------------------------------------------------------------------------------------------------
Untuk menghasilkan gambar, buka gambar pada komputer yang telah kita simpan sebelumnya, dengan cara File-> Open-> (Pilih File), Setelah gambar terpilih. Maka gambar akan ditampilkan
-------------------------------------------------------------------------------------------------------------------------
Kita juga bisa menambahkan beberapa Filter yang tersedia disana dengan cara Filter-> (Pilih Filter)
                                                               -(Filter Threshold)-
--------------------------------------------------------------------------------------------------------------------------

         Semoga bermanfaat, Thanks All :)

Minggu, 18 November 2018

TUGAS SIMULASI FOX AND RABBIT

Nama : Chaniyah Zulfa Mukhlishah
NRP   : 05111740000115
Kelas  : PBO-B

Tugas kali ini adalah membuat simulator fox and rabbit yang menerapkan Polymorphism. Terdapat 9 class didalamnya, yaitu=
1. Simulator
2. SimulatorView
3. Fox
4. Rabbit
5. Location
6. Randomizer
7. Field
8. Field Stats
9. Counter

Source Code setiap class nya berikut ini =

1. Simulator


 import java.util.Random;   
  import java.util.List;   
  import java.util.ArrayList;   
  import java.util.Iterator;   
  import java.awt.Color;   
  /**  
  * Polymorphism  
  * @author Chaniyah Zulfa Mukhlishah  
  * @version 19-Nov-18  
  */   
  public class Simulator   
  {   
   // Constants representing configuration information for the simulation.   
   // The default width for the grid.   
   private static final int DEFAULT_WIDTH = 50;   
   // The default depth of the grid.   
   private static final int DEFAULT_DEPTH = 50;   
   // The probability that a fox will be created in any given grid position.   
   private static final double FOX_CREATION_PROBABILITY = 0.02;   
   // The probability that a rabbit will be created in any given grid position.   
   private static final double RABBIT_CREATION_PROBABILITY = 0.08;    
   // Lists of animals in the field. Separate lists are kept for ease of iteration.   
   private List<Rabbit> rabbits;   
   private List<Fox> foxes;   
   // The current state of the field.   
   private Field field;   
   // The current step of the simulation.   
   private int step;   
   // A graphical view of the simulation.   
   private SimulatorView view;   
   /**   
   * Construct a simulation field with default size.   
   */   
   public Simulator()   
   {   
    this(DEFAULT_DEPTH, DEFAULT_WIDTH);   
   }   
   /**   
   * Create a simulation field with the given size.   
   * @param depth Depth of the field. Must be greater than zero.   
   * @param width Width of the field. Must be greater than zero.   
   */   
   public Simulator(int depth, int width)   
   {   
    if(width <= 0 || depth <= 0) {   
     System.out.println("The dimensions must be greater than zero.");   
     System.out.println("Using default values.");   
     depth = DEFAULT_DEPTH;   
     width = DEFAULT_WIDTH;   
    }   
    rabbits = new ArrayList<Rabbit>();   
    foxes = new ArrayList<Fox>();   
    field = new Field(depth, width);   
    // Create a view of the state of each location in the field.   
    view = new SimulatorView(depth, width);   
    view.setColor(Rabbit.class, Color.orange);   
    view.setColor(Fox.class, Color.blue);   
    // Setup a valid starting point.   
    reset();   
   }   
   /**   
   * Run the simulation from its current state for a reasonably long period,   
   * e.g. 500 steps.   
   */   
   public void runLongSimulation()   
   {   
    simulate(500);   
   }   
   /**   
   * Run the simulation from its current state for the given number of steps.   
   * Stop before the given number of steps if it ceases to be viable.   
   * @param numSteps The number of steps to run for.   
   */   
   public void simulate(int numSteps)   
   {   
    for(int step = 1; step <= numSteps && view.isViable(field); step++) {   
     simulateOneStep();   
    }   
   }   
   /**   
   * Run the simulation from its current state for a single step.   
   * Iterate over the whole field updating the state of each   
   * fox and rabbit.   
   */   
   public void simulateOneStep()   
   {   
    step++;   
    // Provide space for newborn rabbits.   
    List<Rabbit> newRabbits = new ArrayList<Rabbit>();     
    // Let all rabbits act.   
    for(Iterator<Rabbit> it = rabbits.iterator(); it.hasNext(); ) {   
     Rabbit rabbit = it.next();   
     rabbit.run(newRabbits);   
     if(! rabbit.isAlive()) {   
      it.remove();   
     }   
    }   
    // Provide space for newborn foxes.   
    List<Fox> newFoxes = new ArrayList<Fox>();     
    // Let all foxes act.   
    for(Iterator<Fox> it = foxes.iterator(); it.hasNext(); ) {   
     Fox fox = it.next();   
     fox.hunt(newFoxes);   
     if(! fox.isAlive()) {   
      it.remove();   
     }   
    }   
    // Add the newly born foxes and rabbits to the main lists.   
    rabbits.addAll(newRabbits);   
    foxes.addAll(newFoxes);   
    view.showStatus(step, field);   
   }   
   /**   
   * Reset the simulation to a starting position.   
   */   
   public void reset()   
   {   
    step = 0;   
    rabbits.clear();   
    foxes.clear();   
    populate();   
    // Show the starting state in the view.   
    view.showStatus(step, field);   
   }   
   /**   
   * Randomly populate the field with foxes and rabbits.   
   */   
   private void populate()   
   {   
    Random rand = Randomizer.getRandom();   
    field.clear();   
    for(int row = 0; row < field.getDepth(); row++) {   
     for(int col = 0; col < field.getWidth(); col++) {   
      if(rand.nextDouble() <= FOX_CREATION_PROBABILITY) {   
       Location location = new Location(row, col);   
       Fox fox = new Fox(true, field, location);   
       foxes.add(fox);   
      }   
      else if(rand.nextDouble() <= RABBIT_CREATION_PROBABILITY) {   
       Location location = new Location(row, col);   
       Rabbit rabbit = new Rabbit(true, field, location);   
       rabbits.add(rabbit);   
      }   
      // else leave the location empty.   
     }   
    }   
   }   
  }  

2. SimulatorView


 import java.awt.*;   
  import java.awt.event.*;   
  import javax.swing.*;   
  import java.util.LinkedHashMap;   
  import java.util.Map;   
  /**  
  * Polymorphism  
  * @author Chaniyah Zulfa Mukhlishah  
  * @version 19-Nov-18  
  */   
  public class SimulatorView extends JFrame   
  {   
   // Colors used for empty locations.   
   private static final Color EMPTY_COLOR = Color.white;   
   // Color used for objects that have no defined color.   
   private static final Color UNKNOWN_COLOR = Color.gray;   
   private final String STEP_PREFIX = "Step: ";   
   private final String POPULATION_PREFIX = "Population: ";   
   private JLabel stepLabel, population;   
   private FieldView fieldView;   
   // A map for storing colors for participants in the simulation   
   private Map<Class, Color> colors;   
   // A statistics object computing and storing simulation information   
   private FieldStats stats;   
   /**   
   * Create a view of the given width and height.   
   * @param height The simulation's height.   
   * @param width The simulation's width.   
   */   
   public SimulatorView(int height, int width)   
   {   
    stats = new FieldStats();   
    colors = new LinkedHashMap<Class, Color>();   
    setTitle("Fox and Rabbit Simulation");   
    stepLabel = new JLabel(STEP_PREFIX, JLabel.CENTER);   
    population = new JLabel(POPULATION_PREFIX, JLabel.CENTER);   
    setLocation(100, 50);   
    fieldView = new FieldView(height, width);   
    Container contents = getContentPane();   
    contents.add(stepLabel, BorderLayout.NORTH);   
    contents.add(fieldView, BorderLayout.CENTER);   
    contents.add(population, BorderLayout.SOUTH);   
    pack();   
    setVisible(true);   
   }   
   /**   
   * Define a color to be used for a given class of animal.   
   * @param animalClass The animal's Class object.   
   * @param color The color to be used for the given class.   
   */   
   public void setColor(Class animalClass, Color color)   
   {   
    colors.put(animalClass, color);   
   }   
   /**   
   * @return The color to be used for a given class of animal.   
   */   
   private Color getColor(Class animalClass)   
   {   
    Color col = colors.get(animalClass);   
    if(col == null) {   
     // no color defined for this class   
     return UNKNOWN_COLOR;   
    }   
    else {   
     return col;   
    }   
   }   
   /**   
   * Show the current status of the field.   
   * @param step Which iteration step it is.   
   * @param field The field whose status is to be displayed.   
   */   
   public void showStatus(int step, Field field)   
   {   
    if(!isVisible()) {   
     setVisible(true);   
    }   
    stepLabel.setText(STEP_PREFIX + step);   
    stats.reset();   
    fieldView.preparePaint();   
    for(int row = 0; row < field.getDepth(); row++) {   
     for(int col = 0; col < field.getWidth(); col++) {   
      Object animal = field.getObjectAt(row, col);   
      if(animal != null) {   
       stats.incrementCount(animal.getClass());   
       fieldView.drawMark(col, row, getColor(animal.getClass()));   
      }   
      else {   
       fieldView.drawMark(col, row, EMPTY_COLOR);   
      }   
     }   
    }   
    stats.countFinished();   
    population.setText(POPULATION_PREFIX + stats.getPopulationDetails(field));   
    fieldView.repaint();   
   }   
   /**   
   * Determine whether the simulation should continue to run.   
   * @return true If there is more than one species alive.   
   */   
   public boolean isViable(Field field)   
   {   
    return stats.isViable(field);   
   }   
   /**   
   * Provide a graphical view of a rectangular field. This is    
   * a nested class (a class defined inside a class) which   
   * defines a custom component for the user interface. This   
   * component displays the field.   
   * This is rather advanced GUI stuff - you can ignore this    
   * for your project if you like.   
   */   
   private class FieldView extends JPanel   
   {   
    private final int GRID_VIEW_SCALING_FACTOR = 6;   
    private int gridWidth, gridHeight;   
    private int xScale, yScale;   
    Dimension size;   
    private Graphics g;   
    private Image fieldImage;   
    /**   
    * Create a new FieldView component.   
    */   
    public FieldView(int height, int width)   
    {   
     gridHeight = height;   
     gridWidth = width;   
     size = new Dimension(0, 0);   
    }   
    /**   
    * Tell the GUI manager how big we would like to be.   
    */   
    public Dimension getPreferredSize()   
    {   
     return new Dimension(gridWidth * GRID_VIEW_SCALING_FACTOR,   
          gridHeight * GRID_VIEW_SCALING_FACTOR);   
    }   
    /**   
    * Prepare for a new round of painting. Since the component   
    * may be resized, compute the scaling factor again.   
    */   
    public void preparePaint()   
    {   
     if(! size.equals(getSize())) { // if the size has changed...   
      size = getSize();   
      fieldImage = fieldView.createImage(size.width, size.height);   
      g = fieldImage.getGraphics();   
      xScale = size.width / gridWidth;   
      if(xScale < 1) {   
       xScale = GRID_VIEW_SCALING_FACTOR;   
      }   
      yScale = size.height / gridHeight;   
      if(yScale < 1) {   
       yScale = GRID_VIEW_SCALING_FACTOR;   
      }   
     }   
    }   
    /**   
    * Paint on grid location on this field in a given color.   
    */   
    public void drawMark(int x, int y, Color color)   
    {   
     g.setColor(color);   
     g.fillRect(x * xScale, y * yScale, xScale-1, yScale-1);   
    }   
    /**   
    * The field view component needs to be redisplayed. Copy the   
    * internal image to screen.   
    */   
    public void paintComponent(Graphics g)   
    {   
     if(fieldImage != null) {   
      Dimension currentSize = getSize();   
      if(size.equals(currentSize)) {   
       g.drawImage(fieldImage, 0, 0, null);   
      }   
      else {   
       // Rescale the previous image.   
       g.drawImage(fieldImage, 0, 0, currentSize.width, currentSize.height, null);   
      }   
     }   
    }   
   }   
  }   

3. Fox


  import java.util.List;   
  import java.util.Iterator;   
  import java.util.Random;   
  /**  
  * Polymorphism  
  * @author Chaniyah Zulfa Mukhlishah  
  * @version 19-Nov-18  
  */   
  public class Fox   
  {   
   // Characteristics shared by all foxes (static fields).   
   // The age at which a fox can start to breed.   
   private static final int BREEDING_AGE = 10;   
   // The age to which a fox can live.   
   private static final int MAX_AGE = 150;   
   // The likelihood of a fox breeding.   
   private static final double BREEDING_PROBABILITY = 0.35;   
   // The maximum number of births.   
   private static final int MAX_LITTER_SIZE = 5;   
   // The food value of a single rabbit. In effect, this is the   
   // number of steps a fox can go before it has to eat again.   
   private static final int RABBIT_FOOD_VALUE = 7;   
   // A shared random number generator to control breeding.   
   private static final Random rand = Randomizer.getRandom();   
   // Individual characteristics (instance fields).   
   // The fox's age.   
   private int age;   
   // Whether the fox is alive or not.   
   private boolean alive;   
   // The fox's position.   
   private Location location;   
   // The field occupied.   
   private Field field;   
   // The fox's food level, which is increased by eating rabbits.   
   private int foodLevel;   
   /**   
   * Create a fox. A fox can be created as a new born (age zero   
   * and not hungry) or with a random age and food level.   
   *    
   * @param randomAge If true, the fox will have random age and hunger level.   
   * @param field The field currently occupied.   
   * @param location The location within the field.   
   */   
   public Fox(boolean randomAge, Field field, Location location)   
   {   
    age = 0;   
    alive = true;   
    this.field = field;   
    setLocation(location);   
    if(randomAge) {   
     age = rand.nextInt(MAX_AGE);   
     foodLevel = rand.nextInt(RABBIT_FOOD_VALUE);   
    }   
    else {   
     // leave age at 0   
     foodLevel = RABBIT_FOOD_VALUE;   
    }   
   }   
   /**   
   * This is what the fox does most of the time: it hunts for   
   * rabbits. In the process, it might breed, die of hunger,   
   * or die of old age.   
   * @param field The field currently occupied.   
   * @param newFoxes A list to add newly born foxes to.   
   */   
   public void hunt(List<Fox> newFoxes)   
   {   
    incrementAge();   
    incrementHunger();   
    if(alive) {   
     giveBirth(newFoxes);      
     // Move towards a source of food if found.   
     Location newLocation = findFood(location);   
     if(newLocation == null) {    
      // No food found - try to move to a free location.   
      newLocation = field.freeAdjacentLocation(location);   
     }   
     // See if it was possible to move.   
     if(newLocation != null) {   
      setLocation(newLocation);   
     }   
     else {   
      // Overcrowding.   
      setDead();   
     }   
    }   
   }   
   /**   
   * Check whether the fox is alive or not.   
   * @return True if the fox is still alive.   
   */   
   public boolean isAlive()   
   {   
    return alive;   
   }   
   /**   
   * Return the fox's location.   
   * @return The fox's location.   
   */   
   public Location getLocation()   
   {   
    return location;   
   }   
   /**   
   * Place the fox at the new location in the given field.   
   * @param newLocation The fox's new location.   
   */   
   private void setLocation(Location newLocation)   
   {   
    if(location != null) {   
     field.clear(location);   
    }   
    location = newLocation;   
    field.place(this, newLocation);   
   }   
   /**   
   * Increase the age. This could result in the fox's death.   
   */   
   private void incrementAge()   
   {   
    age++;   
    if(age > MAX_AGE) {   
     setDead();   
    }   
   }   
   /**   
   * Make this fox more hungry. This could result in the fox's death.   
   */   
   private void incrementHunger()   
   {   
    foodLevel--;   
    if(foodLevel <= 0) {   
     setDead();   
    }   
   }   
   /**   
   * Tell the fox to look for rabbits adjacent to its current location.   
   * Only the first live rabbit is eaten.   
   * @param location Where in the field it is located.   
   * @return Where food was found, or null if it wasn't.   
   */   
   private Location findFood(Location location)   
   {   
    List<Location> adjacent = field.adjacentLocations(location);   
    Iterator<Location> it = adjacent.iterator();   
    while(it.hasNext()) {   
     Location where = it.next();   
     Object animal = field.getObjectAt(where);   
     if(animal instanceof Rabbit) {   
      Rabbit rabbit = (Rabbit) animal;   
      if(rabbit.isAlive()) {    
       rabbit.setDead();   
       foodLevel = RABBIT_FOOD_VALUE;   
       // Remove the dead rabbit from the field.   
       return where;   
      }   
     }   
    }   
    return null;   
   }   
   /**   
   * Check whether or not this fox is to give birth at this step.   
   * New births will be made into free adjacent locations.   
   * @param newFoxes A list to add newly born foxes to.   
   */   
   private void giveBirth(List<Fox> newFoxes)   
   {   
    // New foxes are born into adjacent locations.   
    // Get a list of adjacent free locations.   
    List<Location> free = field.getFreeAdjacentLocations(location);   
    int births = breed();   
    for(int b = 0; b < births && free.size() > 0; b++) {   
     Location loc = free.remove(0);   
     Fox young = new Fox(false, field, loc);   
     newFoxes.add(young);   
    }   
   }   
   /**   
   * Generate a number representing the number of births,   
   * if it can breed.   
   * @return The number of births (may be zero).   
   */   
   private int breed()   
   {   
    int births = 0;   
    if(canBreed() && rand.nextDouble() <= BREEDING_PROBABILITY) {   
     births = rand.nextInt(MAX_LITTER_SIZE) + 1;   
    }   
    return births;   
   }   
   /**   
   * A fox can breed if it has reached the breeding age.   
   */   
   private boolean canBreed()   
   {   
    return age >= BREEDING_AGE;   
   }   
   /**   
   * Indicate that the fox is no longer alive.   
   * It is removed from the field.   
   */   
   private void setDead()   
   {   
    alive = false;   
    if(location != null) {   
     field.clear(location);   
     location = null;   
     field = null;   
    }   
   }   
  }   

4. Rabbit


 import java.util.List;   
  import java.util.Random;   
  /**  
  * Polymorphism  
  * @author Chaniyah Zulfa Mukhlishah  
  * @version 19-Nov-18  
  */   
  public class Rabbit   
  {    
   private static final int BREEDING_AGE = 5;   
   private static final int MAX_AGE = 40;    
   private static final double BREEDING_PROBABILITY = 0.15;   
   private static final int MAX_LITTER_SIZE = 4;    
   private static final Random rand = Randomizer.getRandom();   
   private int age;    
   private boolean alive;    
   private Location location;   
   private Field field;   
   /**   
   * Create a new rabbit. A rabbit may be created with age   
   * zero (a new born) or with a random age.   
   *    
   * @param randomAge If true, the rabbit will have a random age.   
   * @param field The field currently occupied.   
   * @param location The location within the field.   
   */   
   public Rabbit(boolean randomAge, Field field, Location location)   
   {   
    age = 0;   
    alive = true;   
    this.field = field;   
    setLocation(location);   
    if(randomAge) {   
     age = rand.nextInt(MAX_AGE);   
    }   
   }   
   /**   
   * This is what the rabbit does most of the time - it runs    
   * around. Sometimes it will breed or die of old age.   
   * @param newRabbits A list to add newly born rabbits to.   
   */   
   public void run(List<Rabbit> newRabbits)   
   {   
    incrementAge();   
    if(alive) {   
     giveBirth(newRabbits);      
     // Try to move into a free location.   
     Location newLocation = field.freeAdjacentLocation(location);   
     if(newLocation != null) {   
      setLocation(newLocation);   
     }   
     else {   
      // Overcrowding.   
      setDead();   
     }   
    }   
   }   
   /**   
   * Check whether the rabbit is alive or not.   
   * @return true if the rabbit is still alive.   
   */   
   public boolean isAlive()   
   {   
    return alive;   
   }   
   /**   
   * Indicate that the rabbit is no longer alive.   
   * It is removed from the field.   
   */   
   public void setDead()   
   {   
    alive = false;   
    if(location != null) {   
     field.clear(location);   
     location = null;   
     field = null;   
    }   
   }   
   /**   
   * Return the rabbit's location.   
   * @return The rabbit's location.   
   */   
   public Location getLocation()   
   {   
    return location;   
   }   
   /**   
   * Place the rabbit at the new location in the given field.   
   * @param newLocation The rabbit's new location.   
   */   
   private void setLocation(Location newLocation)   
   {   
    if(location != null) {   
     field.clear(location);   
    }   
    location = newLocation;   
    field.place(this, newLocation);   
   }   
   /**   
   * Increase the age.   
   * This could result in the rabbit's death.   
   */   
   private void incrementAge()   
   {   
    age++;   
    if(age > MAX_AGE) {   
     setDead();   
    }   
   }   
   /**   
   * Check whether or not this rabbit is to give birth at this step.   
   * New births will be made into free adjacent locations.   
   * @param newRabbits A list to add newly born rabbits to.   
   */   
   private void giveBirth(List<Rabbit> newRabbits)   
   {   
    // New rabbits are born into adjacent locations.   
    // Get a list of adjacent free locations.   
    List<Location> free = field.getFreeAdjacentLocations(location);   
    int births = breed();   
    for(int b = 0; b < births && free.size() > 0; b++) {   
     Location loc = free.remove(0);   
     Rabbit young = new Rabbit(false, field, loc);   
     newRabbits.add(young);   
    }   
   }   
   /**   
   * Generate a number representing the number of births,   
   * if it can breed.   
   * @return The number of births (may be zero).   
   */   
   private int breed()   
   {   
    int births = 0;   
    if(canBreed() && rand.nextDouble() <= BREEDING_PROBABILITY) {   
     births = rand.nextInt(MAX_LITTER_SIZE) + 1;   
    }   
    return births;   
   }   
   /**   
   * A rabbit can breed if it has reached the breeding age.   
   * @return true if the rabbit can breed, false otherwise.   
   */   
   private boolean canBreed()   
   {   
    return age >= BREEDING_AGE;   
   }   
  }   

5. Location


  /**  
  * Polymorphism  
  * @author Chaniyah Zulfa Mukhlishah  
  * @version 19-Nov-18  
  */   
  public class Location   
  {   
   // Row and column positions.   
   private int row;   
   private int col;   
   /**   
   * Represent a row and column.   
   * @param row The row.   
   * @param col The column.   
   */   
   public Location(int row, int col)   
   {   
    this.row = row;   
    this.col = col;   
   }   
   /**   
   * Implement content equality.   
   */   
   public boolean equals(Object obj)   
   {   
    if(obj instanceof Location) {   
     Location other = (Location) obj;   
     return row == other.getRow() && col == other.getCol();   
    }   
    else {   
     return false;   
    }   
   }   
   /**   
   * Return a string of the form row,column   
   * @return A string representation of the location.   
   */   
   public String toString()   
   {   
    return row + "," + col;   
   }   
   /**   
   * Use the top 16 bits for the row value and the bottom for   
   * the column. Except for very big grids, this should give a   
   * unique hash code for each (row, col) pair.   
   * @return A hashcode for the location.   
   */   
   public int hashCode()   
   {   
    return (row << 16) + col;   
   }   
   /**   
   * @return The row.   
   */   
   public int getRow()   
   {   
    return row;   
   }   
   /**   
   * @return The column.   
   */   
   public int getCol()   
   {   
    return col;   
   }   
  }   

6. Randomizer


 import java.util.Random;   
  /**  
  * Polymorphism  
  * @author Chaniyah Zulfa Mukhlishah  
  * @version 19-Nov-18  
  */   
  public class Randomizer   
  {   
   // The default seed for control of randomization.   
   private static final int SEED = 1111;   
   // A shared Random object, if required.   
   private static final Random rand = new Random(SEED);   
   // Determine whether a shared random generator is to be provided.   
   private static final boolean useShared = true;   
   /**   
   * Constructor for objects of class Randomizer   
   */   
   public Randomizer()   
   {   
   }   
   /**   
   * Provide a random generator.   
   * @return A random object.   
   */   
   public static Random getRandom()   
   {   
    if(useShared) {   
     return rand;   
    }   
    else {   
     return new Random();   
    }   
   }   
   /**   
   * Reset the randomization.   
   * This will have no effect if randomization is not through   
   * a shared Random generator.   
   */   
   public static void reset()   
   {   
    if(useShared) {   
     rand.setSeed(SEED);   
    }   
   }   
  }   

7. Field


 import java.util.Collections;   
  import java.util.Iterator;   
  import java.util.LinkedList;   
  import java.util.List;   
  import java.util.Random;   
  /**  
  * Polymorphism  
  * @author Chaniyah Zulfa Mukhlishah  
  * @version 19-Nov-18  
  */   
  public class Field   
  {   
   // A random number generator for providing random locations.   
   private static final Random rand = Randomizer.getRandom();   
   // The depth and width of the field.   
   private int depth, width;   
   // Storage for the animals.   
   private Object[][] field;   
   /**   
   * Represent a field of the given dimensions.   
   * @param depth The depth of the field.   
   * @param width The width of the field.   
   */   
   public Field(int depth, int width)   
   {   
    this.depth = depth;   
    this.width = width;   
    field = new Object[depth][width];   
   }   
   /**   
   * Empty the field.   
   */   
   public void clear()   
   {   
    for(int row = 0; row < depth; row++) {   
     for(int col = 0; col < width; col++) {   
      field[row][col] = null;   
     }   
    }   
   }   
   /**   
   * Clear the given location.   
   * @param location The location to clear.   
   */   
   public void clear(Location location)   
   {   
    field[location.getRow()][location.getCol()] = null;   
   }   
   /**   
   * Place an animal at the given location.   
   * If there is already an animal at the location it will   
   * be lost.   
   * @param animal The animal to be placed.   
   * @param row Row coordinate of the location.   
   * @param col Column coordinate of the location.   
   */   
   public void place(Object animal, int row, int col)   
   {   
    place(animal, new Location(row, col));   
   }   
   /**   
   * Place an animal at the given location.   
   * If there is already an animal at the location it will   
   * be lost.   
   * @param animal The animal to be placed.   
   * @param location Where to place the animal.   
   */   
   public void place(Object animal, Location location)   
   {   
    field[location.getRow()][location.getCol()] = animal;   
   }   
   /**   
   * Return the animal at the given location, if any.   
   * @param location Where in the field.   
   * @return The animal at the given location, or null if there is none.   
   */   
   public Object getObjectAt(Location location)   
   {   
    return getObjectAt(location.getRow(), location.getCol());   
   }   
   /**   
   * Return the animal at the given location, if any.   
   * @param row The desired row.   
   * @param col The desired column.   
   * @return The animal at the given location, or null if there is none.   
   */   
   public Object getObjectAt(int row, int col)   
   {   
    return field[row][col];   
   }   
   /**   
   * Generate a random location that is adjacent to the   
   * given location, or is the same location.   
   * The returned location will be within the valid bounds   
   * of the field.   
   * @param location The location from which to generate an adjacency.   
   * @return A valid location within the grid area.   
   */   
   public Location randomAdjacentLocation(Location location)   
   {   
    List<Location> adjacent = adjacentLocations(location);   
    return adjacent.get(0);   
   }   
   /**   
   * Get a shuffled list of the free adjacent locations.   
   * @param location Get locations adjacent to this.   
   * @return A list of free adjacent locations.   
   */   
   public List<Location> getFreeAdjacentLocations(Location location)   
   {   
    List<Location> free = new LinkedList<Location>();   
    List<Location> adjacent = adjacentLocations(location);   
    for(Location next : adjacent) {   
     if(getObjectAt(next) == null) {   
      free.add(next);   
     }   
    }   
    return free;   
   }   
   /**   
   * Try to find a free location that is adjacent to the   
   * given location. If there is none, return null.   
   * The returned location will be within the valid bounds   
   * of the field.   
   * @param location The location from which to generate an adjacency.   
   * @return A valid location within the grid area.   
   */   
   public Location freeAdjacentLocation(Location location)   
   {   
    // The available free ones.   
    List<Location> free = getFreeAdjacentLocations(location);   
    if(free.size() > 0) {   
     return free.get(0);   
    }   
    else {   
     return null;   
    }   
   }   
   /**   
   * Return a shuffled list of locations adjacent to the given one.   
   * The list will not include the location itself.   
   * All locations will lie within the grid.   
   * @param location The location from which to generate adjacencies.   
   * @return A list of locations adjacent to that given.   
   */   
   public List<Location> adjacentLocations(Location location)   
   {   
    assert location != null : "Null location passed to adjacentLocations";   
    // The list of locations to be returned.   
    List<Location> locations = new LinkedList<Location>();   
    if(location != null) {   
     int row = location.getRow();   
     int col = location.getCol();   
     for(int roffset = -1; roffset <= 1; roffset++) {   
      int nextRow = row + roffset;   
      if(nextRow >= 0 && nextRow < depth) {   
       for(int coffset = -1; coffset <= 1; coffset++) {   
        int nextCol = col + coffset;   
        // Exclude invalid locations and the original location.   
        if(nextCol >= 0 && nextCol < width && (roffset != 0 || coffset != 0)) {   
         locations.add(new Location(nextRow, nextCol));   
        }   
       }   
      }   
     }   
     // Shuffle the list. Several other methods rely on the list   
     // being in a random order.   
     Collections.shuffle(locations, rand);   
    }   
    return locations;   
   }   
   /**   
   * Return the depth of the field.   
   * @return The depth of the field.   
   */   
   public int getDepth()   
   {   
    return depth;   
   }   
   /**   
   * Return the width of the field.   
   * @return The width of the field.   
   */   
   public int getWidth()   
   {   
    return width;   
   }   
  }   

8. FieldStats


  import java.awt.Color;   
  import java.util.HashMap;   
  /**  
  * Polymorphism  
  * @author Chaniyah Zulfa Mukhlishah  
  * @version 19-Nov-18  
  */   
  public class FieldStats   
  {   
   // Counters for each type of entity (fox, rabbit, etc.) in the simulation.   
   private HashMap<Class, Counter> counters;   
   // Whether the counters are currently up to date.   
   private boolean countsValid;   
   /**   
   * Construct a FieldStats object.   
   */   
   public FieldStats()   
   {   
    // Set up a collection for counters for each type of animal that   
    // we might find   
    counters = new HashMap<Class, Counter>();   
    countsValid = true;   
   }   
   /**   
   * Get details of what is in the field.   
   * @return A string describing what is in the field.   
   */   
   public String getPopulationDetails(Field field)   
   {   
    StringBuffer buffer = new StringBuffer();   
    if(!countsValid) {   
     generateCounts(field);   
    }   
    for(Class key : counters.keySet()) {   
     Counter info = counters.get(key);   
     buffer.append(info.getName());   
     buffer.append(": ");   
     buffer.append(info.getCount());   
     buffer.append(' ');   
    }   
    return buffer.toString();   
   }   
   /**   
   * Invalidate the current set of statistics; reset all    
   * counts to zero.   
   */   
   public void reset()   
   {   
    countsValid = false;   
    for(Class key : counters.keySet()) {   
     Counter count = counters.get(key);   
     count.reset();   
    }   
   }   
   /**   
   * Increment the count for one class of animal.   
   * @param animalClass The class of animal to increment.   
   */   
   public void incrementCount(Class animalClass)   
   {   
    Counter count = counters.get(animalClass);   
    if(count == null) {   
     // We do not have a counter for this species yet.   
     // Create one.   
     count = new Counter(animalClass.getName());   
     counters.put(animalClass, count);   
    }   
    count.increment();   
   }   
   /**   
   * Indicate that an animal count has been completed.   
   */   
   public void countFinished()   
   {   
    countsValid = true;   
   }   
   /**   
   * Determine whether the simulation is still viable.   
   * I.e., should it continue to run.   
   * @return true If there is more than one species alive.   
   */   
   public boolean isViable(Field field)   
   {   
    // How many counts are non-zero.   
    int nonZero = 0;   
    if(!countsValid) {   
     generateCounts(field);   
    }   
    for(Class key : counters.keySet()) {   
     Counter info = counters.get(key);   
     if(info.getCount() > 0) {   
      nonZero++;   
     }   
    }   
    return nonZero > 1;   
   }   
   /**   
   * Generate counts of the number of foxes and rabbits.   
   * These are not kept up to date as foxes and rabbits   
   * are placed in the field, but only when a request   
   * is made for the information.   
   * @param field The field to generate the stats for.   
   */   
   private void generateCounts(Field field)   
   {   
    reset();   
    for(int row = 0; row < field.getDepth(); row++) {   
     for(int col = 0; col < field.getWidth(); col++) {   
      Object animal = field.getObjectAt(row, col);   
      if(animal != null) {   
       incrementCount(animal.getClass());   
      }   
     }   
    }   
    countsValid = true;   
   }   
  }   

9. Counter


  import java.awt.Color;   
  /**  
  * Polymorphism  
  * @author Chaniyah Zulfa Mukhlishah  
  * @version 19-Nov-18  
  */   
  public class Counter   
  {   
   // A name for this type of simulation participant   
   private String name;   
   // How many of this type exist in the simulation.   
   private int count;   
   /**   
   * Provide a name for one of the simulation types.   
   * @param name A name, e.g. "Fox".   
   */   
   public Counter(String name)   
   {   
    this.name = name;   
    count = 0;   
   }   
   /**   
   * @return The short description of this type.   
   */   
   public String getName()   
   {   
    return name;   
   }   
   /**   
   * @return The current count for this type.   
   */   
   public int getCount()   
   {   
    return count;   
   }   
   /**   
   * Increment the current count by one.   
   */   
   public void increment()   
   {   
    count++;   
   }   
   /**   
   * Reset the current count to zero.   
   */   
   public void reset()   
   {   
    count = 0;   
   }   
  }   

Lalu, tes hasilnya dengan membuat simulator dahulu dengan depth dan width yang kita inginkan, maka, step 0 akan muncul



Lalu, kita bisa menambah step menggunakan metode simulate pada simulator

Lalu, hasilnya adalah step 0+30 = step 30



Thanks All, Semoga bermanfaat :)