Selasa, 02 Desember 2025

Pertemuan 16 - Membuat Aplikasi CRUD Java

 Nama        : Safa Mashita

 NRP          : 5025241022

Membuat Aplikasi CRUD Java - Manajemen Buku Perpustakaan

Pada pertemuan ini, saya mempelajari bagaimana membangun aplikasi sederhana berbasis Object-Oriented Programming (OOP) di Java untuk mengelola data buku perpustakaan. Aplikasi ini dibuat menggunakan BlueJ, dan memiliki fitur CRUD (Create, Read, Update, Delete) dengan database untuk mengelola data buku yang tersimpan dalam sistem.

Program ini terdiri dari beberapa kelas utama:
  • Book : Kelas representasi buku

  • Main : Kelas utama untuk menjalankan program dan melakukan operasi CRUD

  • ArrayList digunakan sebagai penyimpanan data buku


A. Database Menggunakan MySQL Workbench 8.0

Pada pertemuan ini selain membuat aplikasi CRUD berbasis Java, juga dibuat sebuah struktur database sederhana menggunakan MySQL untuk menggambarkan bagaimana data buku dapat disimpan secara permanen pada DBMS.


CREATE DATABASE perpustakaan; USE perpustakaan; CREATE TABLE buku ( id_buku INT NOT NULL AUTO_INCREMENT, judul VARCHAR(100) NOT NULL, penulis VARCHAR(100) NOT NULL, tahun INT NOT NULL, PRIMARY KEY (id_buku) ); INSERT INTO buku (id_buku, judul, penulis, tahun) VALUES
(001, 'Laut Bercerita', 'Leila S. Chudori', 2017),
(002, 'Kata', 'Nadhifa Allya Tsana', 2018);


Penjelasan :
  • CREATE DATABASE perpustakaan;
    Membuat database kosong untuk menyimpan tabel-tabel.

  • USE perpustakaan;
    Memilih database yang akan digunakan.

  • CREATE TABLE buku (...);
    Membuat tabel utama untuk menyimpan data buku yang memiliki kolom:

    • id_buku → primary key, auto increment.

    • judul → judul buku.

    • penulis → nama pengarang.

    • tahun → tahun terbit buku.

  • INSERT INTO buku ... VALUES (...);
    Mengisi tabel dengan data contoh.

B. Visualisasi Desain Program dan Hubungan Antar Kelas




Program ini memiliki struktur sederhana dengan dua kelas utama:

1. Kelas Book

Digunakan sebagai blueprint objek buku yang berisi properti seperti:

  • ID buku

  • Judul

  • Penulis

  • Tahun terbit

Kelas ini juga memiliki method untuk menampilkan informasi buku.

2. Kelas Main 

Berfungsi sebagai pusat program dan mengatur menu CRUD:

  • Menambah buku

  • Melihat seluruh buku

  • Mengedit buku

  • Menghapus buku

Relasi antar kelas:

  • Main menggunakan Book

  • Data buku disimpan dalam ArrayList<Book>

Struktur sederhana ini menekankan pemahaman dasar class dan object.


C. Alur Program
  1. Program menampilkan menu utama kepada pengguna.

  2. Pengguna memilih operasi CRUD.

  3. Program menjalankan operasi sesuai pilihan:

    • Tambah Buku: membuat objek Book baru

    • Lihat Buku: menampilkan seluruh data buku

    • Edit Buku: mencari buku berdasarkan ID dan memperbarui datanya

    • Hapus Buku: menghapus buku dari daftar

  4. Program terus berjalan sampai pengguna memilih keluar.


D. Kode Program dan Penjelasan

1. Class Book
public class Book { private int id; private String title; private String author; private int year; public Book(int id, String title, String author, int year) { this.id = id; this.title = title; this.author = author; this.year = year; } public int getId() { return id; } public String getTitle() { return title; } public String getAuthor() { return author; } public int getYear() { return year; } public void setTitle(String title) { this.title = title; } public void setAuthor(String author) { this.author = author; } public void setYear(int year) { this.year = year; } public void printBook() { System.out.println("ID: " + id); System.out.println("Judul: " + title); System.out.println("Penulis: " + author); System.out.println("Tahun: " + year); System.out.println("-------------------------"); } }

Kegunaan:

Mewakili satu objek buku dalam sistem.

Atribut:

  • id : nomor identitas buku

  • title : judul buku

  • author : penulis buku

  • year : tahun terbit

Method:

  • Getter & Setter untuk manipulasi data

  • printBook() : menampilkan detail buku

2. Class DatabaseManager

Menambahkan mysql-connector-j-8.xx.jar ke BlueJ → Preferences → Libraries → Add

import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.Statement; import java.sql.ResultSet; public class DatabaseManager { private static final String URL = "jdbc:mysql://localhost:3306/perpustakaann"; private static final String USER = "root"; private static final String PASS = ""; private Connection conn; public DatabaseManager() { try { conn = DriverManager.getConnection(URL, USER, PASS); System.out.println("Koneksi ke database berhasil!\n"); } catch (Exception e) { System.out.println("Gagal konek: " + e.getMessage()); } } public void insertBook(Book b) { String sql = "INSERT INTO buku (id_buku, judul, penulis, tahun) VALUES (?, ?, ?, ?)"; try { PreparedStatement pst = conn.prepareStatement(sql); pst.setInt(1, b.getId()); pst.setString(2, b.getTitle()); pst.setString(3, b.getAuthor()); pst.setInt(4, b.getYear()); pst.executeUpdate(); System.out.println("Buku berhasil disimpan ke database!\n"); } catch (Exception e) { System.out.println("Gagal tambah buku: " + e.getMessage()); } } public void showBooks() { String sql = "SELECT * FROM buku"; try { Statement st = conn.createStatement(); ResultSet rs = st.executeQuery(sql); System.out.println("\n=== DAFTAR BUKU DI DATABASE ==="); while (rs.next()) { System.out.println("ID: " + rs.getInt("id_buku")); System.out.println("Judul: " + rs.getString("judul")); System.out.println("Penulis: " + rs.getString("penulis")); System.out.println("Tahun: " + rs.getInt("tahun")); System.out.println("------------------------------"); } } catch (Exception e) { System.out.println("Gagal menampilkan: " + e.getMessage()); } } public void updateBook(Book b) { String sql = "UPDATE buku SET judul=?, penulis=?, tahun=? WHERE id_buku=?"; try { PreparedStatement pst = conn.prepareStatement(sql); pst.setString(1, b.getTitle()); pst.setString(2, b.getAuthor()); pst.setInt(3, b.getYear()); pst.setInt(4, b.getId()); int updated = pst.executeUpdate(); if (updated > 0) System.out.println("Buku berhasil diperbarui!\n"); else System.out.println("Buku tidak ditemukan.\n"); } catch (Exception e) { System.out.println("Gagal update: " + e.getMessage()); } } public void deleteBook(int id) { String sql = "DELETE FROM buku WHERE id_buku=?"; try { PreparedStatement pst = conn.prepareStatement(sql); pst.setInt(1, id); int deleted = pst.executeUpdate(); if (deleted > 0) System.out.println("Buku berhasil dihapus!\n"); else System.out.println("Buku tidak ditemukan.\n"); } catch (Exception e) { System.out.println("Gagal hapus: " + e.getMessage()); } } }

Kegunaan:

Mengatur koneksi ke MySQL dan menjalankan CRUD langsung ke database.

Atribut:

  • insertBook() : tambah buku

  • showBooks() : tampilkan semua buku

  • updateBook() : edit buku berdasarkan ID

  • deleteBook() : hapus buku berdasarkan ID

Method:

  • conn : objek koneksi MySQL

  • URL, USER, PASS : konfigurasi database

3. Class Main

import java.util.ArrayList; import java.util.Scanner; public class Main { private static ArrayList<Book> listBuku = new ArrayList<>(); private static Scanner input = new Scanner(System.in); public static void main(String[] args) { int pilihan; do { System.out.println("=== MENU PERPUSTAKAAN ==="); System.out.println("1. Tambah Buku"); System.out.println("2. Lihat Buku"); System.out.println("3. Edit Buku"); System.out.println("4. Hapus Buku"); System.out.println("5. Keluar"); System.out.print("Pilih menu: "); pilihan = input.nextInt(); input.nextLine(); switch (pilihan) { case 1: tambahBuku(); break; case 2: lihatBuku(); break; case 3: editBuku(); break; case 4: hapusBuku(); break; case 5: System.out.println("Program selesai."); break; default: System.out.println("Pilihan salah!"); } } while (pilihan != 5); } private static void tambahBuku() { System.out.print("Masukkan ID: "); int id = input.nextInt(); input.nextLine(); System.out.print("Masukkan Judul: "); String judul = input.nextLine(); System.out.print("Masukkan Penulis: "); String penulis = input.nextLine(); System.out.print("Masukkan Tahun: "); int tahun = input.nextInt(); listBuku.add(new Book(id, judul, penulis, tahun)); System.out.println("Buku berhasil ditambahkan!\n"); } private static void lihatBuku() { if (listBuku.isEmpty()) { System.out.println("Tidak ada data buku.\n"); return; } System.out.println("\n=== DAFTAR BUKU ==="); for (Book b : listBuku) { b.printBook(); } } private static void editBuku() { System.out.print("Masukkan ID buku yang ingin diedit: "); int id = input.nextInt(); input.nextLine(); for (Book b : listBuku) { if (b.getId() == id) { System.out.print("Judul baru: "); b.setTitle(input.nextLine()); System.out.print("Penulis baru: "); b.setAuthor(input.nextLine()); System.out.print("Tahun baru: "); b.setYear(input.nextInt()); System.out.println("Buku berhasil diperbarui!\n"); return; } } System.out.println("Buku tidak ditemukan.\n"); } private static void hapusBuku() { System.out.print("Masukkan ID buku yang ingin dihapus: "); int id = input.nextInt(); for (Book b : listBuku) { if (b.getId() == id) { listBuku.remove(b); System.out.println("Buku berhasil dihapus!\n"); return; } } System.out.println("Buku tidak ditemukan.\n"); } }

Kegunaan:
Menjalankan program utama dan menyediakan menu CRUD.

Fitur Utama:

  • tambahBuku() : membuat objek Book baru

  • lihatBuku() : menampilkan seluruh buku

  • editBuku() : memperbarui data buku berdasarkan ID

  • hapusBuku() : menghapus buku dari ArrayList

Atribut:

  • ArrayList<Book> listBuku : penyimpanan data

  • Scanner input : menerima input pengguna


E. Output Program

1. Create (Tambah Buku)

2. Read (Lihat Buku)


3. Update (Edit Buku)


4. Delete (Hapus Buku)

5. Keluar

F. Kesimpulan

Pada kelas ini, saya belajar bagaimana membuat aplikasi sederhana untuk manajemen buku menggunakan konsep dasar OOP di Java.

  1. Cara membuat class dan objek dalam Java.

  2. Cara menyimpan data menggunakan ArrayList.

  3. Implementasi fitur CRUD dalam satu program.

  4. Pentingnya pemisahan kelas agar program lebih terstruktur dan mudah dirawat.

Kamis, 27 November 2025

Pertemuan 15 - Pemrograman Game

 Nama    : Safa Mashita

 NRP      : 5025241022


 Pertemuan 15 - Pemrograman Game

Pada pertemuan ini, saya mempelajari cara membuat permainan klasik Pong menggunakan bahasa pemrograman Java dengan library Java Swing dan OOP (Object-Oriented Programming). Pong merupakan game sederhana yang meniru permainan tenis meja, terdiri dari dua paddle, satu bola, dan sistem skor.

A. Struktur Kelas dan Hubungan Antar Kelas


Program ini terdiri dari beberapa kelas utama:

  1. Pong

    • Class utama, mengelola game state, input, dan update logic.

  2. Ball

    • Mengatur pergerakan bola, deteksi tumbukan, dan sistem skor.

  3. Paddle

    • Objek pemain (player 1 dan player 2/bot).

  4. Renderer

    • Class untuk menggambar objek ke layar menggunakan paintComponent.

Hubungan antar kelas:

  • Pong membuat objek Ball, Paddle, dan Renderer.

  • Renderer memanggil method render() pada class Pong.

  • Ball berinteraksi langsung dengan objek Paddle untuk memeriksa tabrakan.

  • Seluruh kelas saling bekerja sesuai prinsip OOP untuk membentuk game lengkap.


B. Alur Program
  1. Program dimulai dari main() pada class Pong.

  2. Window game dibuat menggunakan JFrame.

  3. Timer berjalan setiap 20ms untuk meng-update game (game loop).

  4. Ketika pemain menekan Space, permainan dimulai.

  5. Setiap frame:

    • Bola bergerak sesuai kecepatan (motionX, motionY).

    • Paddle bergerak mengikuti input keyboard (W/S atau Up/Down).

    • Jika menggunakan mode bot, paddle kanan digerakkan otomatis.

  6. Bola memantul ketika menyentuh batas atas/bawah atau paddle.

  7. Jika bola melewati paddle, pemain lawan mendapat skor.

  8. Game berakhir ketika skor mencapai limit.


C. Penjelasan Kode

1. Class Ball

package pong;

import java.awt.Color;
import java.awt.Graphics;
import java.util.Random;

public class Ball
{

public int x, y, width = 25, height = 25;

public int motionX, motionY;

public Random random;

private Pong pong;

public int amountOfHits;

public Ball(Pong pong)
{
this.pong = pong;

this.random = new Random();

spawn();
}

public void update(Paddle paddle1, Paddle paddle2)
{
int speed = 5;

this.x += motionX * speed;
this.y += motionY * speed;

if (this.y + height - motionY > pong.height || this.y + motionY < 0)
{
if (this.motionY < 0)
{
this.y = 0;
this.motionY = random.nextInt(4);

if (motionY == 0)
{
motionY = 1;
}
}
else
{
this.motionY = -random.nextInt(4);
this.y = pong.height - height;

if (motionY == 0)
{
motionY = -1;
}
}
}

if (checkCollision(paddle1) == 1)
{
this.motionX = 1 + (amountOfHits / 5);
this.motionY = -2 + random.nextInt(4);

if (motionY == 0)
{
motionY = 1;
}

amountOfHits++;
}
else if (checkCollision(paddle2) == 1)
{
this.motionX = -1 - (amountOfHits / 5);
this.motionY = -2 + random.nextInt(4);

if (motionY == 0)
{
motionY = 1;
}

amountOfHits++;
}

if (checkCollision(paddle1) == 2)
{
paddle2.score++;
spawn();
}
else if (checkCollision(paddle2) == 2)
{
paddle1.score++;
spawn();
}
}

public void spawn()
{
this.amountOfHits = 0;
this.x = pong.width / 2 - this.width / 2;
this.y = pong.height / 2 - this.height / 2;

this.motionY = -2 + random.nextInt(4);

if (motionY == 0)
{
motionY = 1;
}

if (random.nextBoolean())
{
motionX = 1;
}
else
{
motionX = -1;
}
}

public int checkCollision(Paddle paddle)
{
if (this.x < paddle.x + paddle.width && this.x + width > paddle.x && this.y < paddle.y + paddle.height && this.y + height > paddle.y)
{
return 1; //bounce
}
else if ((paddle.x > x && paddle.paddleNumber == 1) || (paddle.x < x - width && paddle.paddleNumber == 2))
{
return 2; //score
}

return 0; //nothing
}

public void render(Graphics g)
{
g.setColor(Color.WHITE);
g.fillOval(x, y, width, height);
}

}

Kegunaan :

Mengatur bola dalam permainan: posisi, pergerakan, pantulan, tabrakan, dan kondisi ketika mencetak skor.

Atribut:

  • x, y : posisi bola di layar.

  • width, height : ukuran bola.

  • motionX, motionY : arah gerakan bola secara horizontal dan vertikal.

  • random : untuk menghasilkan arah acak ketika memantul atau spawn.

  • pong : mengakses ukuran layar dan objek utama.

  • amountOfHits : menghitung jumlah pantulan agar bola makin cepat.

Method:

  • Ball(Pong pong) : constructor, menyimpan referensi ke kelas Pong dan memanggil spawn().

  • update(paddle1, paddle2) : menggerakkan bola, mengecek tabrakan, mengecek skor, memberi pantulan.

  • spawn() : mereset posisi bola ke tengah dan memberi arah acak.

  • checkCollision(paddle) : mendeteksi tabrakan atau bola lewat paddle.

  • render(Graphics g) : menggambar bola sebagai lingkaran putih.


2. Class Paddle

package pong;

import java.awt.Color;
import java.awt.Graphics;

public class Paddle
{

public int paddleNumber;

public int x, y, width = 50, height = 250;

public int score;

public Paddle(Pong pong, int paddleNumber)
{
this.paddleNumber = paddleNumber;

if (paddleNumber == 1)
{
this.x = 0;
}

if (paddleNumber == 2)
{
this.x = pong.width - width;
}

this.y = pong.height / 2 - this.height / 2;
}

public void render(Graphics g)
{
g.setColor(Color.WHITE);
g.fillRect(x, y, width, height);
}

public void move(boolean up)
{
int speed = 15;

if (up)
{
if (y - speed > 0)
{
y -= speed;
}
else
{
y = 0;
}
}
else
{
if (y + height + speed < Pong.pong.height)
{
y += speed;
}
else
{
y = Pong.pong.height - height;
}
}
}

}


Kegunaan :

Mengatur paddle pemain, posisinya, gerakannya, dan tampilannya.

Atribut:

  • paddleNumber : menentukan paddle kiri (1) atau kanan (2).

  • x, y : posisi paddle.

  • width, height : ukuran paddle.

  • score : skor pemain tersebut.

Method:

  • Paddle(Pong, int) → constructor, menentukan posisi awal paddle berdasarkan nomor.

  • render(Graphics g) → menggambar paddle sebagai kotak putih.

  • move(boolean up) → menggerakkan paddle ke atas atau ke bawah dengan batas layar.

3. Class Pong

package pong;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.Timer;

public class Pong implements ActionListener, KeyListener
{

public static Pong pong;

public int width = 700, height = 700;

public Renderer renderer;

public Paddle player1;

public Paddle player2;

public Ball ball;

public boolean bot = false, selectingDifficulty;

public boolean w, s, up, down;

public int gameStatus = 0, scoreLimit = 7, playerWon; //0 = Menu, 1 = Paused, 2 = Playing, 3 = Over

public int botDifficulty, botMoves, botCooldown = 0;

public Random random;

public JFrame jframe;

public Pong()
{
Timer timer = new Timer(20, this);
random = new Random();

jframe = new JFrame("Pong");

renderer = new Renderer();

jframe.setSize(width + 15, height + 35);
jframe.setVisible(true);
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jframe.add(renderer);
jframe.addKeyListener(this);

timer.start();
}

public void start()
{
gameStatus = 2;
player1 = new Paddle(this, 1);
player2 = new Paddle(this, 2);
ball = new Ball(this);
}

public void update()
{
if (player1.score >= scoreLimit)
{
playerWon = 1;
gameStatus = 3;
}

if (player2.score >= scoreLimit)
{
gameStatus = 3;
playerWon = 2;
}

if (w)
{
player1.move(true);
}
if (s)
{
player1.move(false);
}

if (!bot)
{
if (up)
{
player2.move(true);
}
if (down)
{
player2.move(false);
}
}
else
{
if (botCooldown > 0)
{
botCooldown--;

if (botCooldown == 0)
{
botMoves = 0;
}
}

if (botMoves < 10)
{
if (player2.y + player2.height / 2 < ball.y)
{
player2.move(false);
botMoves++;
}

if (player2.y + player2.height / 2 > ball.y)
{
player2.move(true);
botMoves++;
}

if (botDifficulty == 0)
{
botCooldown = 20;
}
if (botDifficulty == 1)
{
botCooldown = 15;
}
if (botDifficulty == 2)
{
botCooldown = 10;
}
}
}

ball.update(player1, player2);
}

public void render(Graphics2D g)
{
g.setColor(Color.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)
{

}
}


Kegunaan :

Menjadi inti game. Mengatur jendela permainan, update logika, input pemain, mode bot, scoring, dan menggambar semua objek.

Atribut:

  • pong : instance global

  • width, height : ukuran layar game

  • renderer : panel gambar

  • player1, player2 : paddle pemain

  • ball : bola

  • bot : apakah mode bot aktif

  • selectingDifficulty : apakah sedang memilih tingkat bot

  • w, s, up, down : status tombol keyboard

  • gameStatus : status game (menu, pause, main, selesai)

  • scoreLimit : batas skor untuk menang

  • playerWon : menyimpan nomor pemain yang menang

  • botDifficulty : tingkat kesulitan bot

  • botMoves, botCooldown : pengaturan perilaku bot

  • random : generator angka random

  • jframe : jendela game

Method:

  • Pong() : constructor, membuat window, timer, dan input listener

  • start() : memulai ulang game (buat objek paddle dan bola baru)

  • update() : logika game seperti gerakan pemain, bot, dan bola

  • render(Graphics2D g) : menggambar semua elemen game sesuai statusnya

  • actionPerformed() : dipanggil oleh timer untuk update dan repaint

  • keyPressed() / keyReleased() / keyTyped() : menangani input keyboard

  • main() : menjalankan game

4. Class Renderer

package pong;

import java.awt.Graphics;
import java.awt.Graphics2D;

import javax.swing.JPanel;

public class Renderer extends JPanel
{

private static final long serialVersionUID = 1L;

@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);

Pong.pong.render((Graphics2D) g);
}

}

Kegunaan :

Menggambar ulang tampilan game di layar setiap frame.

Atribut:

  • Tidak ada yang penting selain serialVersionUID.

Method:

  • paintComponent(Graphics g) : membersihkan layar dan memanggil pong.render().


D. Tampilan Game


Jika memencet space, maka bermain dengan lawan.




Jika memencet shift, maka bermain dengan bot.





E. Kesimpulan

Dari tugas ini, saya mempelajari konsep dasar pemrograman game menggunakan Java, yaitu:

  1. Game Loop (update dan render) menggunakan Timer.

  2. Pemodelan objek game dengan OOP, seperti Ball dan Paddle.

  3. Collision detection antara bola dan paddle.

  4. Handling keyboard input untuk kontrol permainan.

  5. AI sederhana untuk bot yang mengikuti posisi bola.

  6. Pembuatan antarmuka grafik menggunakan Java Swing.


Senin, 17 November 2025

Pertemuan 14 - Pemrograman GUI

 Nama    : Safa Mashita

 NRP      : 5025241022


 Pertemuan 14 - Pemrograman GUI


1. Membuat frame windows user login dan password

Jawab

Output Program

Tampilan Login



Jika Username & Password benar (Login berhasil)


Jika Username & Password benar (Login gagal)


Penjelasan

a. Class LoginFrame

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

public class LoginFrame extends JFrame {

    private JTextField usernameField;
    private JPasswordField passwordField;
    private JButton loginButton;
    private JLabel messageLabel;

    public LoginFrame() {
        setTitle("User Login");
        setSize(350, 200);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);

        // Panel utama
        JPanel panel = new JPanel(new GridLayout(4, 2, 5, 5));

        panel.add(new JLabel("Username:"));
        usernameField = new JTextField();
        panel.add(usernameField);

        panel.add(new JLabel("Password:"));
        passwordField = new JPasswordField();
        panel.add(passwordField);

        messageLabel = new JLabel("");
        panel.add(messageLabel);

        loginButton = new JButton("Login");
        panel.add(loginButton);

        add(panel);

        loginButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                String user = usernameField.getText();
                String pass = new String(passwordField.getPassword());

                if (user.equals("admin") && pass.equals("123")) {
                    messageLabel.setText("Login Berhasil!");
                } else {
                    messageLabel.setText("Username/Password Salah");
                }
            }
        });
    }

    public static void main(String[] args) {
        new LoginFrame().setVisible(true);
    }
}

Kegunaan:

Sebagai frame utama yang menampilkan form login user menggunakan Swing.

Atribut:

  • usernameField : input teks untuk username
  • passwordField : input password

  • loginButton : tombol untuk verifikasi

  • messageLabel : menampilkan pesan hasil login

Method:

  • LoginFrame() : konstruktor untuk membangun GUI (layout, label, tombol, event listener).
  • main() : menjalankan program dengan menampilkan frame login.

Hubungan:

  • LoginFrame berperan sebagai pintu masuk sebelum ImageViewer muncul.

  • Jika login berhasil, LoginFrame akan:

    • menutup frame login

    • membuat instance dari ImageViewer dan menampilkannya.

  • Jadi LoginFrame mengontrol kapan ImageViewer digunakan, tetapi bukan sebaliknya.


b. Class MainApp

public class MainApp {
    public static void main(String[] args) {
        LoginFrame.main(args);
    }
}

Kegunaan:

Sebagai class utama (entry point) yang memulai seluruh aplikasi. MainApp akan menjalankan proses login terlebih dahulu melalui LoginFrame.

Method:

  • main(String[] args)
    Method ini memanggil LoginFrame.main(args) untuk menampilkan form login. Setelah login berhasil, LoginFrame akan membuka ImageViewer.

Hubungan:

  • MainApp dan LoginFrame
  • MainApp hanya memanggil LoginFrame sebagai langkah awal aplikasi. Jadi MainApp berfungsi sebagai pengendali utama yang menentukan bahwa proses harus dimulai dari login.


2. Implementasikan aplikasi image viewer

Jawab

Output Program

Fit

Zoom In


Zoom Out


Penjelasan


a. Class ImageViewer

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

public class ImageViewer extends JFrame {

    private JLabel imageLabel;
    private JButton openButton;
    private JFileChooser fileChooser;

    public ImageViewer() {
        setTitle("Simple Image Viewer");
        setSize(600, 500);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);

        imageLabel = new JLabel("", SwingConstants.CENTER);
        openButton = new JButton("Open Image");
        fileChooser = new JFileChooser();

        add(openButton, BorderLayout.NORTH);
        add(imageLabel, BorderLayout.CENTER);

        openButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                int result = fileChooser.showOpenDialog(null);

                if (result == JFileChooser.APPROVE_OPTION) {
                    File selectedFile = fileChooser.getSelectedFile();
                    ImageIcon icon = new ImageIcon(selectedFile.getAbsolutePath());

                    Image img = icon.getImage();
                    Image scaledImg = img.getScaledInstance(550, 450, Image.SCALE_SMOOTH);

                    imageLabel.setIcon(new ImageIcon(scaledImg));
                }
            }
        });
    }

    public static void main(String[] args) {
        new ImageViewer().setVisible(true);
    }
}

Kegunaan:

Menjadi aplikasi sederhana untuk membuka dan menampilkan gambar.

Atribut:

  • imageLabel : area untuk menampilkan gambar

  • openButton : tombol untuk memilih file gambar

  • fileChooser : komponen dialog untuk memilih file

Method:

  • ImageViewer() : membangun GUI dengan layout BorderLayout

  • main() : menjalankan ImageViewer

Hubungan:

  • ImageViewer akan dipanggil oleh LoginFrame setelah login berhasil.
  • ImageViewer tidak memiliki hubungan balik ke LoginFrame (dia tidak perlu tahu siapa yang memanggilnya).


b. Class MainApp

public class MainApp {
    public static void main(String[] args) {
        LoginFrame.main(args);
    }
}

Kegunaan:

Sebagai class utama (entry point) yang memulai seluruh aplikasi. MainApp akan menjalankan proses login terlebih dahulu melalui LoginFrame.

Method:

  • main(String[] args)
    Method ini memanggil LoginFrame.main(args) untuk menampilkan form login. Setelah login berhasil, LoginFrame akan membuka ImageViewer.

Hubungan:

  • MainApp dan ImageViewer (tidak langsung)
    MainApp tidak memanggil ImageViewer secara langsung.
    Sebaliknya:

    • MainApp memanggil LoginFrame

    • LoginFrame yang akan memutuskan apakah membuka ImageViewer setelah login berhasil



 

Pertemuan 16 - Membuat Aplikasi CRUD Java

 Nama          : Safa Mashita  NRP            : 5025241022 Membuat Aplikasi CRUD Java - Manajemen Buku Perpustakaan Pada pertemuan ini, saya...