Wednesday, December 11, 2024

PBO G - Evaluasi Akhir Semester

Live Currency Changer

Nama  : Basten Andika Salim

NRP    : 5025231132

1. Apa yang dimaksud dengan inheritance dalam Java? Bagaimana implementasi inheritance dalam Final Project yang sedang dikerjakan?

    Inheritence adalah sebuah konsep fundamental dalam pemrograman berbasis obyek yang memberikan cara untuk sebuah Class mendapatkan atribut, method, dan properti lainnya dari sebuah Class lain. Class yang mendapatkan properti tersebut disebut dengan Subclass, sedangkan Class yang memberikan propertinya disebut dengan Superclass.


    Inheritance ini juga digunakan dalam Final Project yang sedang dikerjakan. Judul Final Project ini adalah Live Currency Converter, sehingga Class yang menggunakan konsep tersebut adalah Class Currency dan Subclass mata uang ( IDR, USD, SGD, dll). Karena seluruh mata uang memiliki atribut dan method yang sama, bisa dibuat sebuah superclass Currency untuk menghindari code duplication.


2. Jelaskan fitur aplikasi yang ada dalam Final Project

    Fitur-fitur yang telah dibuat untuk Final Project ini adalah sebagai berikut:

  • Konversi mata uang sederhana
  • Convertion Rate Fluctuation yang menjadi simulasi perubahan nilai mata uang yang terjadi pada setiap saat.
  • Economy Crash yang menjadi simulasi bagaimana konversi mata uang akan berubah bila sebuah mata uang / negara mengalami economical crash.


3. Buatlah desain Diagram Kelas dari aplikasi Final Project


    Diagram kelas dibuat dengan seluruh mata uang extend menuju Currency, sedangkan CurrencyConverter yang menjadi Class utama proyek melibatkan semua Class lain.


4. Implementasikan aplikasi yang telah didesain dengan menggunakan Pemrograman Berbasis Obyek Java

Class Currency

import java.util.List;
import java.util.ArrayList;

public class Currency {
    protected String name;
    protected double rateFromIDR;
    private List<Double> history;

    public Currency(String name, double rateFromIDR) {
        this.name = name;
        this.rateFromIDR = rateFromIDR;
        this.history = new ArrayList<>();
        this.history.add(rateFromIDR);        
    }

    public String getName() {
        return name;
    }

    public double getRateFromIDR() {
        return rateFromIDR;
    }

    public void fluctuateRate() {
        double fluctuation = 0.95 + (1.05 - 0.95) * Math.random(); // ±5% fluctuation
        rateFromIDR *= fluctuation;
        history.add(rateFromIDR);
    }
   
    public void economicalCrash() {
        rateFromIDR = rateFromIDR * (0.05 + (0.1) * Math.random());
    }
}

Class Currency ini akan menjadi superclass untuk semua currency yang akan digunakan. Superclass ini tidak perlu di Override oleh subclass manapun.

Class Currency memegang informasi penting, seperti:

- Nama dari currency.

- Value dari currency, yang didasarkan nilai dari IDR. Keputusan menggunakan IDR sebagai dasar seluruh currency adalah karena IDR merupakan salah satu mata uang terlemah di dunia, sehingga sangat cocok digunakan bila tidak ada mata uang yang lebih lemah darinya.

Subclass IDR

public class IDR extends Currency
{
    public IDR() {
        super("IDR", 1.0);
    }
}

Subclass USD

public class USD extends Currency
{
    public USD() {
        super("USD", 15947.0);
    }
}

Subclass W

public class W extends Currency
{
    public W() {
        super("W", 11.15);
    }
}

Subclass SGD

public class SGD extends Currency
{
    public SGD() {
        super("SGD", 11866.05);
    }
}

Subclass JPY

public class JPY extends Currency
{
    public JPY() {
        super("JPY", 104.6);
    }
}

Subclass EUR

public class EUR extends Currency
{
    public EUR() {
        super("EUR", 16471.0);
    }
}

Subclass AUD

public class AUD extends Currency
{
    public AUD() {
        super("AUD", 10151.0);
    }
}

Class CurrencyConverter

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

public class CurrencyConverter
{
    private JFrame frame;
    private JComboBox<String> fromCurrency;
    private JComboBox<String> toCurrency;
    private JComboBox<String> crashCurrency;
    private JTextField amountField;
    private JLabel resultLabel;
    private JTextArea ratesDisplay;
    private List<Currency> currencies;

    public CurrencyConverter()
    {
        currencies = new ArrayList<>();
       
        initializeCurrencies();
        createGUI();
        startFluctuationTimer();
    }

    private void initializeCurrencies() {
        currencies.add(new IDR());
        currencies.add(new USD());
        currencies.add(new EUR());
        currencies.add(new W());
        currencies.add(new SGD());
        currencies.add(new JPY());
        currencies.add(new AUD());
    }
   
    private void createGUI(){
        frame = new JFrame("Currency Converter");
        frame.setSize(800, 500);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new BorderLayout());
       
        fromCurrency = new JComboBox<>(currencies.stream().map(Currency::getName).toArray(String[]::new));
        toCurrency = new JComboBox<>(currencies.stream().map(Currency::getName).toArray(String[]::new));
        crashCurrency = new JComboBox<>(currencies.stream().map(Currency::getName).toArray(String[]::new));
       
        amountField = new JTextField();
        resultLabel = new JLabel("Converted Amount: ", JLabel.CENTER);
        ratesDisplay = new JTextArea();
       
        updateRatesDisplay();
       
       
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = new Insets(10, 10, 10, 10);
        gbc.fill = GridBagConstraints.HORIZONTAL;

        JPanel inputPanel = new JPanel(new GridBagLayout());
       
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.weightx = 0.5;
        inputPanel.add(new JLabel("From Currency:"), gbc);
       
        gbc.gridx = 1;
        gbc.weightx = 1.0;
        inputPanel.add(fromCurrency, gbc);
       
        gbc.gridx = 0;
        gbc.gridy = 1;
        gbc.weightx = 0.5;
        inputPanel.add(new JLabel("To Currency:"), gbc);
   
        gbc.gridx = 1;
        gbc.weightx = 1.0;
        inputPanel.add(toCurrency, gbc);
   
        gbc.gridx = 0;
        gbc.gridy = 2;
        gbc.weightx = 0.5;
        inputPanel.add(new JLabel("Amount:"), gbc);
   
        gbc.gridx = 1;
        gbc.weightx = 1.0;
        inputPanel.add(amountField, gbc);
       
        JPanel buttonPanel = new JPanel(new GridBagLayout());
        JButton convertButton = new JButton("Convert");
       
        GridBagConstraints gbcButton = new GridBagConstraints();
        gbcButton.insets = new Insets(5, 5, 5, 5);
        gbcButton.gridx = 0;
        gbcButton.gridy = 0;
        buttonPanel.add(convertButton, gbcButton);
   
        gbcButton.gridy = 1;
        buttonPanel.add(resultLabel, gbcButton);
       
        JButton crashButton= new JButton("Crash currency");
   
        gbcButton.gridx = 0;
        gbcButton.gridy = 2;
        buttonPanel.add(crashCurrency, gbcButton);
       
        gbcButton.gridx = 0;
        gbcButton.gridy = 3;
        buttonPanel.add(crashButton, gbcButton);
       
        JPanel centerPanel = new JPanel(new BorderLayout());
        centerPanel.add(buttonPanel, BorderLayout.NORTH);
   
        ratesDisplay = new JTextArea();
        ratesDisplay.setEditable(false);
        JScrollPane scrollPane = new JScrollPane(ratesDisplay);
        JPanel ratesPanel = new JPanel(new BorderLayout());
        ratesPanel.setPreferredSize(new Dimension(300, 200));
        ratesPanel.add(scrollPane, BorderLayout.CENTER);
        ratesPanel.setBorder(BorderFactory.createTitledBorder("Live Exchange Rates"));        
       
        JPanel mainPanel = new JPanel(new BorderLayout());
        mainPanel.add(inputPanel, BorderLayout.NORTH);
        mainPanel.add(centerPanel, BorderLayout.CENTER);
        mainPanel.add(ratesPanel, BorderLayout.SOUTH);
   
        frame.add(mainPanel, BorderLayout.CENTER);
       
        convertButton.addActionListener(e -> convertCurrency());
        crashButton.addActionListener(e -> crashCurrency());
       
       
        frame.setVisible(true);
       
    }
   
   
    private void convertCurrency(){
        try {
            String fromName = (String) fromCurrency.getSelectedItem();
            String toName = (String) toCurrency.getSelectedItem();
           
            double amount = Double.parseDouble(amountField.getText());
           
            Currency fromCur = currencies.stream().filter(c -> c.getName().equals(fromName)).findFirst().orElse(null);
            Currency toCur = currencies.stream().filter(c -> c.getName().equals(toName)).findFirst().orElse(null);
           
            if (fromCur != null && toCur != null){
                double converted = (fromCur.getRateFromIDR()/toCur.getRateFromIDR()) * amount;
                resultLabel.setText("Converted amount: " + String.format("%.2f", converted) + " " + toName);
            }
        } catch (NumberFormatException e) {
            JOptionPane.showMessageDialog(frame, "Please enter a valid number for the amount.");
        }
    }
   
    private void crashCurrency(){
        try {
            String targetName = (String) crashCurrency.getSelectedItem();
           
            Currency targetCur = currencies.stream().filter(c -> c.getName().equals(targetName)).findFirst().orElse(null);
       
            if (targetCur != null){
                targetCur.economicalCrash();
                updateRatesDisplay();
            }
        } catch (NumberFormatException e) {
            JOptionPane.showMessageDialog(frame, "Please select a currency.");
        }
    }
   
    private void startFluctuationTimer(){
        Timer timer = new Timer();
       
        timer.schedule(new TimerTask () {
            @Override
           
            public void run(){
                fluctuateRates();
                updateRatesDisplay();
            }
        }, 0, 10000);
    }
   
    private void fluctuateRates() {
        for (Currency currency : currencies) {
            if (!currency.getName().equals("IDR")) {
                currency.fluctuateRate();
            }
        }
    }
   
    private void updateRatesDisplay() {
        StringBuilder ratesText = new StringBuilder("Live Exchange Rates:\n");
        for (Currency currency : currencies) {
            ratesText.append(currency.getName()).append(": ").append(String.format("%.2f", currency.getRateFromIDR())).append("\n");
        }
        ratesDisplay.setText(ratesText.toString());
    }
   
    public static void main(String[] args) {
        new CurrencyConverter();
    }
}

Class CurrencyConverter adalah Class utama yang digunakan dalam proyek ini. Class inilah yang mengatur pembuatan GUI serta fungsi-fungsi dari proyek, yaitu untuk mengubah nilai mata uang, melakukan rate fluctuation, dan juga menyediakan fitur economy crash.

Hasil implementasi:








Wednesday, December 4, 2024

Tugas Pertemuan 14

 Nama:    Basten Andika Salim

NRP:      5025231132

Source code: https://github.com/rowlys/PBO-G/tree/main/LoginPanel

Tugas Implementasi Graphical User Interface

Untuk pengerjaan tugas ini, kedua permintaan tugas akan digabung. Sehingga image viewer dapat diakses setelah pengguna telah melalui login panel.

1. Membuat frame windows user login dan password

    Class Login


    Method go


    Inner Class LoginListener


    Inner Class CancelListener



    Hasil Implementasi:



2. Implementasikan aplikasi image viewer

    Class ImageChooserPanel


    Method chooseImage


    Hasil Implementasi: 

        Setelah melakukan login, panel berikut akan muncul:





Wednesday, November 27, 2024

Tugas Pertemuan 13

Nama:    Basten Andika Salim

NRP:      5025231132


Source code: https://github.com/rowlys/PBO-G/tree/main/Abstract%20Class

Tugas Implementasi Abstraksi Kelas

1. Tuliskan implementasi dari program kecil Abstract Class Mahluk Hidup yang diwariskan kepada manusai, hewan, dan tumbuhan.

Berikut adalah Class Diagram dari program:


Berikut adalah Class MahlukHidup:


Class MahlukHidup memiliki beberapa method yang akan di Override oleh subclass lainnya, seperti breathe dan grow. Class ini akan menjadi dasar dari seluruh subclass lain.

Berikut adalah Subclass Manusia:


Subclass Manusia memiliki method tambahan, yaitu speak.

Berikut adalah Subclass Programmer:


Subclass Programmer melakukan Override pada method dari MahlukHidup dan juga Manusia untuk menghasilkan output uniknya.

Berikut adalah Subclass Doctor:


Subclass Doctor melakukan Override pada method dari MahlukHidup dan juga Manusia untuk menghasilkan output uniknya.

Berikut adalah Subclass Hewan:


Subclass Manusia memiliki method tambahan, yaitu move.

Berikut adalah Subclass Anjing:


Subclass Anjing melakukan Override pada method dari MahlukHidup dan juga Hewan untuk menghasilkan output uniknya.

Berikut adalah Subclass Burung:


Subclass Burung melakukan Override pada method dari MahlukHidup dan juga Hewan untuk menghasilkan output uniknya.

Berikut adalah Subclass Tumbuhan:


Subclass Tumbuhan memiliki method tambahan, yaitu photosynthesize.

Berikut adalah Subclass TumbuhanBerbunga:


Subclass TumbuhanBerbunga melakukan Override pada method dari MahlukHidup dan juga Tumbuhan untuk menghasilkan output uniknya.

Berikut adalah Subclass TumbuhanTidakBerbunga:


Subclass TumbuhanTidakBerbunga melakukan Override pada method dari MahlukHidup dan juga Tumbuhan untuk menghasilkan output uniknya.

Berikut adalah Class Main


Class ini akan membuat instance-instance baru dari masing-masing Subclass dan menjalankan seluruh method pada Subclass tersebut.

Berikut adalah hasil implementasi menggunakan Class Main:


   2.  Pelajari dan baca simulasi Foxes and Rabbit yang ada di buku. Kemudian buat program perubahan dari struktur class umum menjadi bentuk Abstract Class.

Berikut adalah Class Diagram dari program:


Berikut adalah Class Animal:




Class ini akan menjadi dasar untuk Subclass Rabbit dan Subclass Fox yang akan memiliki perilakunya masing-masing.

Berikut adalah Subclass Rabbit:


Subclass Rabbit berperilaku bergerak secara acak. Perilaku acak ini akan diimplementasikan di Class Field.

Berikut adalah Subclass Fox:



Subclass Fox berperilaku dengan memeriksa location di sekitarnya untuk mangsa (rabbit). Bila ada, maka serigala akan 'memakannya' dan mengubah variabel "isAlive" Rabbit yang dimakannya menjadi FALSE. Bila Fox tidak menemukan mangsa, maka ia akan bergerak secara acak.

Berikut adalah Class Field:



Class Field bertindak sebagai 'lapangan' yang dapat dijelajahi para hewan (fox dan rabbit). Dalam class ini, terdapat fungsi untuk menempatkan hewan pada sebuah lokasi, menghapus object dari sebuah lokasi, mengembalikan informasi object pada suatu lokasi, dan mencari lokasi yang kosong. Fungsi freeAdjacentLocation ini akan mengembalikan lokasi yang kosong yang ditemukannya secara acak.

Berikut adalah Class Location:


Berikut adalah Class Simulator yang akan membuat field dan memasukkan object ke dalamnya:




Berikut adalah contoh output dari method simulate dari Class Simulator:





Wednesday, November 20, 2024

Tugas Pertemuan 12

Nama:    Basten Andika Salim

NRP:      5025231132


Source code: https://github.com/rowlys/PBO-G/tree/main/Airplane%20Ticket%20Reservation

Tugas Pembuatan Sistem 'Airplane Ticket Reservation'

Berikut adalah Class Diagram dari program:




Program memiliki sebuah Superclass yang merupakan dasar dari seluruh jenis tiket (Economy, Business, dan FirstClass) bernama Ticket. Class ini memiliki beberapa fungsi dasar seperti mengambil value dari variabel-variabel nya, seperti fare, baggage, dan destination.

Selain itu, Class ini memiliki fungsi yang akan menampilkan 'template' untuk informasi tiket yang telah direservasi dan juga fungsi yang menghitung harga akhir tiket. 


Semua jenis tiket memiliki Class nya masing-masing, yaitu:

Class Economy:

Class ini memiliki harga yang lebih murah 10% dari harga yang dimasukkan, memiliki batas berat bawaan sesuai dengan yang dimasukkan, dan tidak memiliki layanan tambahan. Pada class ini, terdapat dua 'Override' yang mengganti fungsi bawaan dari Class Ticket.


Class Business:

Class ini memiliki harga yang lebih mahal 25% dari harga yang dimasukkan, memiliki batas berat bawaan 5 kg lebih besar dari yang dimasukkan, dan memiliki layanan tambahan berupa makanan yang akan dihidangkan di pesawat. Pada class ini, terdapat dua 'Override' yang mengganti fungsi bawaan dari Class Ticket.


Class FirstClass:

Class ini memiliki harga yang lebih mahal 50% dari harga yang dimasukkan, memiliki batas berat bawaan 10 kg lebih besar dari yang dimasukkan, dan memiliki layanan tambahan berupa makanan yang akan dihidangkan di pesawat serta akses untuk lounge saat menunggu di bandara. Pada class ini, terdapat dua 'Override' yang mengganti fungsi bawaan dari Class Ticket.


Class Main adalah Class yang menyontohkan reservasi tiket dari jenis Economy, Business, dan First Class, lalu menunjukkan detailnya menggunakan fungsi displayInfo() yang telah di 'Override' masing-masing Class jenis tiket. 


Berikut adalah output dari Class Main:



Wednesday, November 13, 2024

Tugas Pertemuan 11

 Nama:    Basten Andika Salim

NRP:      5025231132


Source code: https://github.com/rowlys/PBO-G/tree/main/Rental%20Management

Tugas Pembuatan Sistem 'Rental Management'

Berikut adalah Class Diagram dari program:




Berikut adalah semua Class serta Method yang digunakannya:


Class Vehicle


Class ini merupakan class yang akan diambil oleh subclass kendaraan lain. Class ini dapat menampung merk, model, tahun pembuatan, serta availability dari sebuah kendaraan. Availability bekerja sebagai penanda status peminjaman kendaraan tersebut.

Class Car


Class ini adalah subclass dari Class Vehicle untuk kendaraan mobil. Class ini hanya memiliki tambahan berupa jumlah roda.

Class Motorcycle


Class ini adalah subclass dari Class Vehicle untuk kendaraan motor. Class ini hanya memiliki tambahan berupa jumlah roda.

Class Bike


Class ini adalah subclass dari Class Vehicle untuk kendaraan sepeda. Class ini hanya memiliki tambahan berupa tipe sepeda.

Class Renter


Class ini akan menyimpan informasi dari sebuah penyewa, yaitu nama dan kendaraan yang disimpannya. Selain itu, class ini memiliki boolean renting yang menunjukkan bila penyewa sedang menyewa atau tidak.

Class Rental



Class inilah yang menyediakan sebagian besar fungsi utama dari sistem rental. Yaitu menambahkan kendaraan, menambahkan penyewa, menunjukkan kendaraan, menunjukkan penyewa, mengambil data kendaraan, dan mengembalikkan kendaraan.

Class App






Class ini merupakan class yang menggunakan keseluruhan dari sistem dan menampilkan sebuah interface pada pengguna. Pengguna dapat menggunakan sistem melalu menu yang ditampilkan oleh class ini. Class ini memiliki berbagai kegunaan, yaitu menampilkan UI, mengambil input, dan memerintahkan Class Rental sesuai dengan kebutuhan.


Berikut adalah hasil penggunaan Class App:


Pengguna menambahkan mobil kedalam sistem. Dapat dilihat bahwa data mobil dapat diambil oleh sistem.


Pengguna menambahkan penyewa yang meminjam mobil yang telah dimasukkan ke sistem sebelumnya. Data mobil sudah tidak bisa dilihat karena telah dipinjam.


Data penyewa dapat ditampilkan.