Membuat Icon Dengan Efek Refleksi Kaca

Repost dari artikel saya di PC Mild 20/2010

Swing adalah salah satu package Java yang cukup menarik dan banyak sekali dipakai untuk pemrograman grafis. Tidak hanya mudah digunakan, tetapi juga mudah dimodifikasi. Bagian yang cukup menarik untuk dimodifikasi adalah tentang tampilannya.

Untuk menampilkan icon, biasanya cukup dengan menggunakan class jLabel, dengan sebuah gambar PNG ukuran tertentu. Dari sisi desain, sebenarnya pembuatan icon tersebut bisa dimodifikasi sehingga tampilan menjadi lebih menarik dengan efek pantulan kaca seperti ini.

Hasil pembuatan icon refleksi kaca

Modifikasi dilakukan dengan membuat turunan dari class jLabel. Konsep dasarnya adalah melakukan penggambaran ulang dari image yang digunakan sebagai icon, dengan menggunakan Java 2D API.

  1. Langkah pertama, membuat class bantuan untuk mencetak gambar pantulan. Class bantuan ini dibuat agar method untuk membuat gambar pantulan dapat dipakai di class lainnya, tidak hanya turunan jLabel yang akan dibuat. Constructor dibuat private untuk menghindari terciptanya instance dari class tersebut. Jangan lupa untuk meng-import class lain yang dibutuhkan dalam class ini.
    import java.awt.AlphaComposite;
    import java.awt.Color;
    import java.awt.GradientPaint;
    import java.awt.Graphics2D;
    import java.awt.Image;
    import java.awt.image.BufferedImage;
    
    public final class HQIconUtil {
      private HQIconUtil() {}
    }
    
  2. Membuat method untuk mengubah Image menjadi BufferedImage, sebab class yang digunakan sebagai icon pada komponen Swing adalah Image. Padahal, Image tidak dapat dimanipulasi secara langsung dengan menggunakan Java 2D API. Letakkan method ini di dalam class HQIconUtil.
      public static BufferedImage convertToBufferedImage(Image image) {
        // get image size
        int width = image.getWidth(null);
        int height = image.getHeight(null);
    
        // create new buffered image
        BufferedImage result = new BufferedImage(width, height,
            BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = result.createGraphics();
        g.drawImage(image, 0, 0, null);
        g.dispose();
    
        // return the result
        return result;
      }
    
  3. Berikutnya adalah membuat method untuk membuat efek pantulan kaca. Langkah ini adalah bagian terpenting dalam pembuatan icon pantulan kaca. Object gambar bertipe BufferedImage dimanipulasi sedemikian rupa menggunakan AlphaComposite sebagai mask untuk menampilkan gradasi. Hampir semua langkah dilakukan dalam object g yang merupakan instance Graphics2D dari BufferedImage yang akan dibuat.
      public static BufferedImage
          createReflectionBufferedImage(BufferedImage image) {
        // create result image
        BufferedImage result = new BufferedImage(image.getWidth(),
            image.getHeight() * 6 / 4, BufferedImage.TYPE_INT_ARGB);
    
        Graphics2D g = result.createGraphics();
    
        // paints original image
        g.drawImage(image, 0, 0, null);
    
        // paints mirrored image
        g.scale(1.0, -1.0);
        g.drawImage(image, 0, -image.getHeight() * 2, null);
        g.scale(1.0, -1.0);
    
        // move to mirror's origin
        g.translate(0, image.getHeight());
    
        // create gradien mask
        GradientPaint mask = new GradientPaint(0, 0, new Color(1f, 1f, 1f, 0.5f),
            0, image.getHeight() / 2, new Color(1f, 1f, 1f, 0f));
        g.setPaint(mask);
    
        // set alpha composite
        g.setComposite(AlphaComposite.DstIn);
    
        // paint the mask
        g.fillRect(0, 0, image.getWidth(), image.getHeight());
    
        g.dispose();
        return result;
      }
    
      public static BufferedImage
          createReflectionBufferedImage(Image image) {
        return createReflectionBufferedImage(convertToBufferedImage(image));
      }
    
  4. Setelah Class bantuan selesai dibuat, saatnya membuat class turunan dari jLabel. Tujuan akhir pembuatan class ini adalah sebagai komponen yang dapat digunakan berkali-kali, baik secara manual maupun dengan menggunakan IDE. Untuk itu, penurunan class harus disesuaikan dengan design pattern dari komponen Swing yang lain. Langkah awal, membuat class tersebut kemudian mendeklarasikan object dari class javax.swing.Icon yang akan digunakan sebagai icon pantulan kaca.
    import java.awt.image.BufferedImage;
    import javax.swing.Icon;
    import javax.swing.ImageIcon;
    import javax.swing.SwingConstants;
    
    public class HQLabel extends javax.swing.JLabel {
      private Icon iconReflect;
    
      // *****constructors area***** //
      /**
       * Default constructor.
       * Set label's text to the bottom center.
       */
      public HQLabel() {
        super();
        setHorizontalTextPosition(SwingConstants.CENTER);
        setVerticalTextPosition(SwingConstants.BOTTOM);
      }
    }
    
  5. Design pattern komponen Swing agar property bisa digunakan baik secara manual maupun akses grafikal melalui IDE seperti NetBeans, yaitu menyertakan method getter dan setter. Secara standart, nama method cukup dengan prefix “set” dan “get” sebelum nama object atau property yang akan diakses. Untuk menampilkan icon refleksi kaca secara otomatis, pada saat Icon di-set, maka harus dilakukan pemanggilan method createReflectionBufferedImage() pada class bantuan sebelumnya.
      public Icon getIconReflect() {
        return this.iconReflect;
      }
    
      /**
       * Set the icon reflection. Current icon will be
       * replaced by the icon reflection.
       * @param iconReflect
       */
      public void setIconReflect(Icon iconReflect)
          throws IllegalArgumentException {
        // check whether the argument is null
        if (iconReflect == null) {
          firePropertyChange("iconReflection", getIconReflect(), iconReflect);
          this.iconReflect = iconReflect;
          setIcon(iconReflect);
        } else {
          if (!(iconReflect instanceof ImageIcon)) {
            throw new IllegalArgumentException();
          }
          firePropertyChange("iconReflection", getIconReflect(), iconReflect);
          this.iconReflect = iconReflect;
          BufferedImage img = HQIconUtil.createReflectionBufferedImage(
                  ((ImageIcon) iconReflect).getImage());
          setIcon(new ImageIcon(img));
        }
      }
    
  6. Untuk melakukan percobaan, cukup membuat sebuah jFrame sederhana yang melakukan pemanggilan terhadap class HQLabel.
    import javax.swing.ImageIcon;
    
    /**
     *
     * @author Haqqi
     */
    public class Main extends javax.swing.JFrame {
      public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(new Runnable() {
          public void run() {
            new Main().setVisible(true);
          }
        });
      }
    
      public Main() {
        setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
        setTitle("http://fauzilhaqqi.net");
        setLayout(new java.awt.BorderLayout());
        icon = new HQLabel();
        icon.setIconReflect(new ImageIcon(this.getClass().getResource("logo.png")));
        add(icon);
        pack();
        setLocationRelativeTo(null);
      }
    
      HQLabel icon;
    }
    
  7. Seluruh langkah telah selesai. Label yang baru bisa dimanfaatkan bersama berbagai komponen Swing lainnya. Selain itu, class bantuan pembuat efek pantulan kaca sebelumnya juga dapat dipakai dalam class lain. Sebuah langkah yang tepat untuk pengembangan berikutnya juga kan? Selamat mencoba.

Download source code keseluruhan.Artikel ini telah dipublikasikan di media cetak tabloid PC Mild edisi 20 tahun 2010 lalu.

2 Comments

Leave a Comment.