Pertemuan 14 OOP - Graphical User Interface

Nama : Kadek Fajar Pramartha Yasodana

NRP : 5025231185

Kelas : PBO A


Graphical User Interface

1. Membuat frame windows user login dan password .

Source Code : GitHub

Untuk membuat frame, kita akan menggunakan library GUI pada java.awt dan javax.swing untuk memudahkan kita membuat.

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Main {
private JTextField txtUsername;
private JPasswordField txtPassword;
private static String Username = "Fajar";
private static String Password = "its";
private static String msg;

public static void main(String[] args) {
Main gui = new Main();
gui.go();
}

public void go() {
JFrame frame = new JFrame("Login Form");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

JPanel panel = new JPanel();
panel.setLayout(new GridLayout(3, 2, 10, 10));

JLabel lblUsername = new JLabel("Username:");
JLabel lblPassword = new JLabel("Password:");

txtUsername = new JTextField(20);
txtPassword = new JPasswordField(20);

JButton btnLogin = new JButton("Login");
btnLogin.addActionListener(new LoginListener());

JButton btnCancel = new JButton("Cancel");
btnCancel.addActionListener(new CancelListener());

panel.add(lblUsername);
panel.add(txtUsername);
panel.add(lblPassword);
panel.add(txtPassword);
panel.add(btnLogin);
panel.add(btnCancel);

frame.getContentPane().add(panel, BorderLayout.CENTER);
frame.setSize(600, 200);
frame.setVisible(true);
}

public class LoginListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
if (Username.equals(txtUsername.getText())) {
if (Password.equals(new String(txtPassword.getPassword()))) {
msg = "Login Granted!";
} else {
msg = "Login Denied";
}
} else {
msg = "Login Denied";
}
JOptionPane.showMessageDialog(null, msg);
}
}
public class CancelListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
txtUsername.setText("");
txtPassword.setText("");
txtUsername.requestFocus();
}
}
}

Method main

Metode ini berfungsi sebagai titik awal program, di mana sebuah instance dari kelas Main dibuat, lalu metode go() dipanggil untuk memulai GUI. Dengan cara ini, program memastikan bahwa seluruh antarmuka pengguna dibuat dan ditampilkan ketika aplikasi dijalankan.

Method go

Metode ini bertanggung jawab untuk membangun antarmuka pengguna (GUI) program. Dimulai dengan membuat objek JFrame untuk jendela utama dengan judul "Login Form" dan mengatur aksi penutupan. Panel utama (JPanel) dibuat dan menggunakan tata letak grid (GridLayout) dengan tiga baris dan dua kolom untuk menyusun komponen. Komponen seperti JLabel (untuk label username dan password), JTextField (untuk input username), JPasswordField (untuk input password), serta tombol JButton (Login dan Cancel) ditambahkan ke panel. Listener ditetapkan untuk setiap tombol, di mana tombol Login dihubungkan ke LoginListener untuk memeriksa kredensial, dan tombol Cancel dihubungkan ke CancelListener untuk membersihkan input. Panel kemudian ditambahkan ke frame, ukuran jendela diatur, dan GUI ditampilkan.

Class LoginListener

Kelas ini menangani klik pada tombol Login. Metode actionPerformed di dalamnya membandingkan input pengguna di field username dan password dengan kredensial yang disimpan. Jika cocok, pesan "Login Granted!" akan ditampilkan menggunakan dialog JOptionPane, sedangkan jika salah, pesan "Login Denied" muncul. Metode ini memastikan logika otentikasi diterapkan ketika tombol Login ditekan.

Class CancelListener

Kelas ini menangani klik pada tombol Cancel. Metode actionPerformed mengatur agar field input untuk username dan password dikosongkan, lalu fokus kursor dipindahkan kembali ke field username. Ini memberikan cara cepat bagi pengguna untuk menghapus input mereka tanpa perlu menutup aplikasi.


Hasil




2. Implementasikan aplikasi image viewer.
Untuk mengimplementasikan image viewer kira kira sama, kita menggunakan library java.awt dan javax.swing.
Source Code : GitHub

ImageFileManager.java

import java.awt.image.*;
import javax.imageio.*;
import java.io.*;

public class ImageFileManager {
private static final String IMAGE_FORMAT = "jpg";

public static OFImage loadImage(File imageFile) {
try {
BufferedImage image = ImageIO.read(imageFile);
if(image == null || (image.getWidth() < 0)) {
return null;
}

return new OFImage(image);
} catch (IOException exc) {
return null;
}
}

public static void saveImage(OFImage image, File file) {
try {
ImageIO.write(image, IMAGE_FORMAT, file);
} catch(IOException exc) {
return;
}
}
}

Kelas ImageFileManager menangani operasi file gambar, seperti membaca dan menyimpan gambar. Metode loadImage digunakan untuk membaca file gambar dari disk dan mengembalikan objek OFImage. Jika file tidak valid atau tidak dikenali, metode ini akan mengembalikan null. Metode saveImage digunakan untuk menyimpan objek OFImage ke file dengan format yang ditentukan (jpg dalam program ini). Kedua metode ini menangani kemungkinan kesalahan seperti IOException.

ImagePanel.java

import java.awt.*;
import javax.swing.JComponent;

public class ImagePanel extends JComponent{
private int width, height;
private OFImage panelImage;

public ImagePanel() {
width = 360;
height = 240;
panelImage = null;
}

public void setImage(OFImage image) {
if(image != null) {
width = image.getWidth();
height = image.getHeight();
panelImage = image;
repaint();
}
}

public void clearImage() {
if (panelImage != null) {
Graphics imageGraphics = panelImage.getGraphics();
imageGraphics.setColor(Color.LIGHT_GRAY);
imageGraphics.fillRect(0, 0, width, height);
}
repaint();
}


public Dimension getPreferredSize() {
return new Dimension(width, height);
}

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);
}
}
}

Kelas ImagePanel bertanggung jawab untuk menampilkan gambar pada antarmuka. Kelas ini menyimpan atribut seperti lebar dan tinggi panel, serta objek gambar (OFImage) yang akan ditampilkan. Metode setImage digunakan untuk menetapkan gambar ke panel, clearImage untuk menghapus gambar yang ada dengan warna default, dan paintComponent untuk menggambar ulang gambar pada panel setiap kali terjadi pembaruan. Ukuran panel juga dapat dikonfigurasi menggunakan metode getPreferredSize.

ImageViewer.java

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

import java.io.File;

public class ImageViewer {

private static final String VERSION = "Version 1.0";
private static JFileChooser fileChooser =
new JFileChooser(System.getProperty("user.dir"));

private JFrame frame;
private ImagePanel imagePanel;
private JLabel filenameLabel;
private JLabel statusLabel;
private OFImage currentImage;

public ImageViewer() {
currentImage = null;
makeFrame();
}


private void openFile() {
int returnVal = fileChooser.showOpenDialog(frame);

if(returnVal != JFileChooser.APPROVE_OPTION) {
return ;
}

File selectedFile = fileChooser.getSelectedFile();
currentImage = ImageFileManager.loadImage(selectedFile);

if(currentImage == null) {
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();
}

private void close() {
currentImage = null;
imagePanel.clearImage();
showFilename(null);
}

private void quit() {
System.exit(0);
}

private void makeDarker() {
if (currentImage != null) {
currentImage.darker();
frame.repaint();
showStatus("Applied: darker");
} else {
showStatus("No image loaded");
}
}

private void makeLighter() {
if (currentImage != null) {
currentImage.lighter();
frame.repaint();
showStatus("Applied: lighter");
} else {
showStatus("No image loaded");
}
}

private void threshold() {
if(currentImage != null) {
currentImage.threshold();
frame.repaint();
showStatus("Applied: threshold");
} else {
showStatus("No image loaded");
}
}

private void showAbout() {
JOptionPane.showMessageDialog(
frame,
"ImageViewer\n",
VERSION,
JOptionPane.INFORMATION_MESSAGE
);
}

private void showFilename(String filename){
if(filename == null) {
filenameLabel.setText("No file displayed.");
} else {
filenameLabel.setText("File: " + filename);
}
}

private void showStatus(String text) {
statusLabel.setText(text);
}

private void makeFrame() {
frame = new JFrame("ImageViewer");
makeMenuBar(frame);

Container contentPane = frame.getContentPane();

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();
contentPane.add(statusLabel, BorderLayout.SOUTH);

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);
}

private void makeMenuBar(JFrame frame) {
final int SHORTCUT_MASK =
Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx();

JMenuBar menubar = new JMenuBar();
frame.setJMenuBar(menubar);

JMenu menu;
JMenuItem item;

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);

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);

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);


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);
}
}

Kelas ImageViewer adalah inti dari aplikasi. Kelas ini mengelola antarmuka pengguna, termasuk panel untuk menampilkan gambar (ImagePanel), menu, serta label status dan nama file. Kelas ini juga bertanggung jawab untuk membaca dan menampilkan file gambar menggunakan ImageFileManager, serta menyediakan fitur manipulasi gambar seperti membuat lebih gelap atau terang (darker dan lighter) dan threshold. Selain itu, ImageViewer memiliki metode seperti openFile untuk memuat gambar, close untuk membersihkan gambar dari panel, dan makeMenuBar untuk menyiapkan menu navigasi.

Main.java

import javax.swing.*;

// Press Shift twice to open the Search Everywhere dialog and type `show whitespaces`,
// then press Enter. You can now see whitespace characters in your code.
public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new ImageViewer());
}
}

Kelas Main adalah titik awal program yang hanya berisi metode main. Metode ini menggunakan SwingUtilities.invokeLater untuk memastikan bahwa antarmuka grafis dibuat dan diatur dalam thread event-dispatching. Dalam metode ini, sebuah instance dari kelas ImageViewer dibuat, yang menginisialisasi seluruh antarmuka pengguna untuk aplikasi pengelolaan gambar.

OFImage.java

import java.awt.*;
import java.awt.image.*;

public class OFImage extends BufferedImage {
public OFImage(BufferedImage image) {
super(
image.getColorModel(),
image.copyData(null),
image.isAlphaPremultiplied(),
null
);
}

public OFImage(int width, int height) {
super(width, height, TYPE_INT_RGB);
}

public void setPixel(int x, int y, Color col) {
if (x >= 0 && x < getWidth() && y >= 0 && y < getHeight()) {
int pixel = col.getRGB();
setRGB(x, y, pixel);
}
}

public Color getPixel(int x, int y) {
int pixel = getRGB(x, y);
return new Color(pixel);
}

public void darker() {
int height = getHeight();
int width = getWidth();

for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
setPixel(x, y, getPixel(x, y).darker());
}
}
}

public void lighter() {
int height = getHeight();
int width = getWidth();

for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
setPixel(x, y, getPixel(x, y).brighter());
}
}
}

public void threshold() {
int height = getHeight();
int width = getWidth();

for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
Color pixel = getPixel(x, y);

int brightness =
(pixel.getRed() +
pixel.getGreen() +
pixel.getBlue()) / 3;

if (brightness <= 85) {
setPixel(x, y, Color.BLACK);
} else if (brightness <= 170) {
setPixel(x, y, Color.GRAY);
} else {
setPixel(x, y, Color.WHITE);
}

}
}
}
}

Kelas OFImage adalah subclass dari BufferedImage yang menyediakan fitur tambahan untuk memanipulasi gambar. Fitur ini meliputi metode setPixel dan getPixel untuk membaca atau menulis warna pixel tertentu, serta metode darker, lighter, dan threshold untuk memodifikasi kecerahan atau warna keseluruhan gambar. Metode manipulasi ini menggunakan iterasi pada setiap pixel dalam gambar, menjadikannya fleksibel untuk berbagai efek visual. Kelas ini juga memiliki dua konstruktor, satu untuk membuat objek dari BufferedImage lain dan satu lagi untuk membuat gambar kosong dengan ukuran tertentu.

Hasil










Comments

Popular posts from this blog

Pertemuan 6 KPPL - Implementasi Web ChatBot Tech Support System, Web & Prototipe & Metodologi

Pertemuan 13 OOP - Abstraksi & Simulasi Fox & Rabit

Pertemuan 7 KPPL - Studi Kasus Pembuatan Aplikasi dengan Agile