Object Oriented Programming | Week 13: GUI Programming
PBO-A 2025
Pada pertemuan minggu ke-13, kami berlatih untuk membuat GUI menggunakan java. Graphical User Interface (GUI) adalah sebuah antarmuka yang memungkinkan pengguna untuk berinteraksi dengan program dengan menggunakan elemen-elemen grafis seperti ikon, tombol, dan lainnya.
Latihan 1: Login Form
Berikut contoh program login form dan penjelasannya.
- fieldUsername: text field component untuk memasukkan username.
- fieldPassword: password field component untuk memasukkan password.
- btnLogin: button component sebagai tombol untuk login.
- btnCancel: button component sebagai tombol untuk menghapus input (username dan password).
- checkPassword: component checkbox untuk menampilkan/menyembunyikan password.
- userCreds: Map yang menyimpan password dengan key username.
/**
* Write a description of class LoginFrame here.
*
* @author Muhammad Zaky Zein
* @version 2025.11.18
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Map;
import java.util.HashMap;
public class Login extends JFrame
{
private JTextField fieldUsername;
private JPasswordField fieldPassword;
private JButton btnLogin;
private JButton btnCancel;
private JCheckBox checkPassword;
private Map<String, String> userCreds = new HashMap<>();
public Login() {
createUserCreds();
createComponents();
componentsLayout();
attachListeners();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setLocationRelativeTo(null);
setResizable(false);
}
private void createUserCreds() {
userCreds.put("Bryophytes", "pass123");
}
private void createComponents() {
fieldUsername = new JTextField(20);
fieldPassword = new JPasswordField(20);
btnCancel = new JButton("Cancel");
btnLogin = new JButton("Login");
checkPassword = new JCheckBox("Show password");
}
private void componentsLayout() {
JPanel content = new JPanel(new BorderLayout(10, 10));
content.setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12));
JPanel fields = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.insets = new Insets(6, 6, 6, 6);
c.anchor = GridBagConstraints.WEST;
c.gridx = 0; c.gridy = 0;
fields.add(new JLabel("Username:"), c);
c.gridx = 1;
fields.add(fieldUsername, c);
c.gridx = 0; c.gridy = 1;
fields.add(new JLabel("Password:"), c);
c.gridx = 1;
fields.add(fieldPassword, c);
c.gridx = 1; c.gridy = 2;
fields.add(checkPassword, c);
JPanel buttons = new JPanel(new FlowLayout(FlowLayout.RIGHT));
buttons.add(btnLogin);
buttons.add(btnCancel);
content.add(fields, BorderLayout.CENTER);
content.add(buttons, BorderLayout.SOUTH);
setContentPane(content);
}
private void attachListeners() {
checkPassword.addActionListener(e -> {
fieldPassword.setEchoChar(checkPassword.isSelected() ? (char)0 : '\u2022');
});
btnCancel.addActionListener(e -> {
fieldUsername.setText("");
fieldPassword.setText("");
fieldUsername.requestFocus();
});
btnLogin.addActionListener(e -> attemptLogin());
Action enterAction = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
attemptLogin();
}
};
fieldUsername.addActionListener(enterAction);
fieldPassword.addActionListener(enterAction);
}
private void attemptLogin() {
String user = fieldUsername.getText().trim();
String pass = new String(fieldPassword.getPassword());
if (user.isEmpty() || pass.isEmpty()) {
JOptionPane.showMessageDialog(this, "Username or password can't be empty.", "Login error", JOptionPane.WARNING_MESSAGE);
return;
}
if (authenticate(user, pass)) {
JOptionPane.showMessageDialog(this, "Hi, " + user + "!", "Login success", JOptionPane.INFORMATION_MESSAGE);
openMainWindow(user);
} else {
JOptionPane.showMessageDialog(this, "Wrong username or password.", "Login fail", JOptionPane.ERROR_MESSAGE);
fieldPassword.setText("");
fieldPassword.requestFocus();
}
}
private boolean authenticate(String username, String password) {
if (!userCreds.containsKey(username)) return false;
String expected = userCreds.get(username);
return expected.equals(password);
}
private void openMainWindow(String username) {
JFrame main = new JFrame("Main - Welcome " + username);
main.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
main.setSize(400, 200);
main.setLocationRelativeTo(this);
JLabel lbl = new JLabel("Login as " + username, SwingConstants.CENTER);
main.add(lbl);
main.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
new Login().setVisible(true);
});
}
}1. Memasukkan username dan password yang salah.
3. Opsi menampilkan password dan menyembunyikannya.
Latihan 2: Image Viewer
Berikut program Image Viewer dengan menggunakan java.
ImageViewer.java - Class utama yang menerapkan GUI sehingga user dapat berinteraksi dengan program untuk membuka suatu foto:
/**
* Write a description of class ImageViewer here.
*
* @author Muhammad Zaky Zein
* @version 2025.11.18
*/
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;
initializeFrame();
}
private void openFile() {
int result = fileChooser.showOpenDialog(frame);
if (result != JFileChooser.APPROVE_OPTION) {
return;
}
File selectedFile = fileChooser.getSelectedFile();
currentImage = ImageFileManager.loadImage(selectedFile);
if (currentImage == null) {
JOptionPane.showMessageDialog(frame, "The file format is not supported.", "Image Load Error", JOptionPane.ERROR_MESSAGE);
return;
}
imagePanel.setImage(currentImage);
updateFilename(selectedFile.getPath());
updateStatus("File loaded successfully.");
frame.pack();
}
private void closeImage() {
currentImage = null;
imagePanel.clearImage();
updateFilename(null);
}
private void quitApplication() {
System.exit(0);
}
private void applyDarkerFilter() {
if (currentImage != null) {
currentImage.darker();
frame.repaint();
updateStatus("Image darkened.");
} else {
updateStatus("No image loaded.");
}
}
private void applyLighterFilter() {
if (currentImage != null) {
currentImage.lighter();
frame.repaint();
updateStatus("Image lightened.");
} else {
updateStatus("No image loaded.");
}
}
private void applyThresholdFilter() {
if (currentImage != null) {
currentImage.threshold();
frame.repaint();
updateStatus("Image thresholded.");
} else {
updateStatus("No image loaded.");
}
}
private void showAboutDialog() {
JOptionPane.showMessageDialog(frame,
"Image Viewer\n" + VERSION,
"About Image Viewer",
JOptionPane.INFORMATION_MESSAGE
);
}
private void updateFilename(String filename) {
if (filename == null) {
filenameLabel.setText("No file displayed.");
} else {
filenameLabel.setText("File: " + filename);
}
}
private void updateStatus(String message) {
statusLabel.setText(message);
}
private void initializeFrame() {
frame = new JFrame("Image Viewer");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setupMenuBar(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(VERSION);
contentPane.add(statusLabel, BorderLayout.SOUTH);
updateFilename(null);
frame.pack();
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
frame.setLocation(screenSize.width / 2 - frame.getWidth() / 2, screenSize.height / 2 - frame.getHeight() / 2);
frame.setVisible(true);
}
private void setupMenuBar(JFrame frame) {
final int SHORTCUT_MASK = Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx();
JMenuBar menuBar = new JMenuBar();
frame.setJMenuBar(menuBar);
JMenu fileMenu = new JMenu("File");
menuBar.add(fileMenu);
addMenuItem(fileMenu, "Open", KeyEvent.VK_O, SHORTCUT_MASK, e -> openFile());
addMenuItem(fileMenu, "Close", KeyEvent.VK_W, SHORTCUT_MASK, e -> closeImage());
addMenuItem(fileMenu, "Quit", KeyEvent.VK_Q, SHORTCUT_MASK, e -> quitApplication());
JMenu filterMenu = new JMenu("Filter");
menuBar.add(filterMenu);
addMenuItem(filterMenu, "Darker", 0, 0, e -> applyDarkerFilter());
addMenuItem(filterMenu, "Lighter", 0, 0, e -> applyLighterFilter());
addMenuItem(filterMenu, "Threshold", 0, 0, e -> applyThresholdFilter());
JMenu helpMenu = new JMenu("Help");
menuBar.add(helpMenu);
addMenuItem(helpMenu, "About", 0, 0, e -> showAboutDialog());
}
private void addMenuItem(JMenu menu, String title, int keyEvent, int mask, ActionListener action) {
JMenuItem item = new JMenuItem(title);
if (keyEvent > 0) {
item.setAccelerator(KeyStroke.getKeyStroke(keyEvent, mask));
}
item.addActionListener(action);
menu.add(item);
}
public static void main(String[] args) {
new ImageViewer();
}
}ImagePanel.java - Class yang berfungsi untuk menampilkan foto:
/**
* Write a description of class ImagePanel here.
*
* @author Muhammad Zaky Zein
* @version 2025.11.18
*/
import java.awt.*;
import javax.swing.*;
public class ImagePanel extends JComponent {
private OFImage panelImage;
public ImagePanel() {
panelImage = null;
}
public void setImage(OFImage image) {
if (image != null) {
panelImage = image;
repaint();
}
}
public void clearImage() {
if (panelImage != null) {
Graphics imageGraphics = panelImage.getGraphics();
imageGraphics.setColor(Color.LIGHT_GRAY);
imageGraphics.fillRect(0, 0, getWidth(), getHeight());
repaint();
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(800, 600);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (panelImage != null) {
int panelWidth = getWidth();
int panelHeight = getHeight();
int imageWidth = panelImage.getWidth();
int imageHeight = panelImage.getHeight();
double imageAspectRatio = (double) imageWidth / imageHeight;
double panelAspectRatio = (double) panelWidth / panelHeight;
int drawWidth, drawHeight;
int xOffset = 0, yOffset = 0;
if (panelAspectRatio > imageAspectRatio) {
drawHeight = panelHeight;
drawWidth = (int) (drawHeight * imageAspectRatio);
xOffset = (panelWidth - drawWidth) / 2;
} else {
drawWidth = panelWidth;
drawHeight = (int) (drawWidth / imageAspectRatio);
yOffset = (panelHeight - drawHeight) / 2;
}
g.drawImage(panelImage, xOffset, yOffset, drawWidth, drawHeight, null);
} else {
g.setColor(Color.LIGHT_GRAY);
g.fillRect(0, 0, getWidth(), getHeight());
}
}
}ImageFileManager.java - Class yang berfungsi agar user dapat menelusuri file foto yang akan dibuka:
/**
* Write a description of class ImageFileManager here.
*
* @author Muhamamad Zaky Zein
* @version 2025.11.18
*/
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class ImageFileManager {
private static final String IMAGE_FORMAT = "jpg";
public static OFImage loadImage(File imageFile) {
try {
BufferedImage bufferedImage = ImageIO.read(imageFile);
if (bufferedImage == null || bufferedImage.getWidth() <= 0) {
return null;
}
return new OFImage(bufferedImage);
} catch (Exception e) {
return null;
}
}
public static void saveImage(OFImage image, File file) {
try {
ImageIO.write(image, IMAGE_FORMAT, file);
} catch (IOException e) {
}
}
}OFImage.java - Class untuk memungkinkan pengguna mengedit tingkat kecerahan dari foto:
/**
* Write a description of class OFImage here.
*
* @author Muhammad Zaky Zein
* @version 2025.11.18
*/
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 color) {
int rgbValue = color.getRGB();
setRGB(x, y, rgbValue);
}
public Color getPixel(int x, int y) {
int rgbValue = getRGB(x, y);
return new Color(rgbValue);
}
public void darker() {
int width = getWidth();
int height = getHeight();
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 width = getWidth();
int height = getHeight();
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 width = getWidth();
int height = getHeight();
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
Color pixelColor = getPixel(x, y);
int brightness = pixelColor.getRed() + pixelColor.getGreen() + pixelColor.getBlue();
if (brightness <= 85) {
setPixel(x, y, Color.BLACK);
} else if (brightness <= 170) {
setPixel(x, y, Color.GRAY);
} else {
setPixel(x, y, Color.WHITE);
}
}
}
}
}Class Diagram:
Output:

Comments
Post a Comment