PBO - Tugas 2 - Aplikasi Traffic Light
Tugas 2 PBO - Aplikasi Traffic Light
Kevin Ashil Faadilah
05111740000178
Deskripsi
Sebuah traffic light terdiri dari 3 lampu rambu (berwarna merah, kuning, hijau), dan sebuah timer internal. Hanya ada satu rambu yang bisa menyala pada setiap waktu dan rambu yang menyala akan berubah setiap x detik. Pergantian diatur oleh timer internal dari traffic light, saat timer mencapai nol rambu akan berubah dan timer kembali di set seperti semula.
Class Diagram
Dekonstruksi Module/Class yang dibutuhkan
Maka, untuk membangun aplikasi sesuai deskripsi diatas kita memerlukan beberapa modul:
- Modul GUI (java.awt dan java.swing)
- Timer (java.swing.Timer)
- Signal untuk rambu
- Panel untuk menunjukkan countdown dari timer
Object Diagram
Overview Class di BlueJ
Implementasi (Source Code)
AppFrame.java
/**
* Class untuk menampilkan WindowFrame aplikasi
*/
import java.awt.*;
import javax.swing.*;
public class AppFrame extends JFrame{
public static void main(String[] args) {
new AppFrame(10);
}
public AppFrame (int duration){
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Traffic Light");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout(1,1));
frame.add(new TrafficLightPane(duration));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
TrafficLightPane.java
/**
* Class untuk menampilkan traffic light
*/
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class TrafficLightPane extends JPanel {
int tick = 1;
int duration = 10;
int state = 0;
SignalPane green = new SignalPane(Color.green);
SignalPane yellow = new SignalPane(Color.yellow);
SignalPane red = new SignalPane(Color.red);
DigitPane timerDigit = new DigitPane();
public TrafficLightPane(int s){
duration = s;
setLayout(new GridLayout(4,1));
green.turnOn(false);
yellow.turnOn(false);
red.turnOn(true);
timerDigit.setValue(duration);
add(red);
add(yellow);
add(green);
add(timerDigit);
Timer timer = new Timer(1000, new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
int timeRemaining = duration - tick;
if (timeRemaining <= 0) {
tick = 0;
state++;
changeSignalState(state);
}
timerDigit.setValue(duration - tick);
tick++;
}
});
timer.setRepeats(true);
timer.setCoalesce(true);
timer.start();
}
//function u/ mengubah integer menjadi boolean
private boolean changeToBool(int state){
if (state % 3 > 0 ){
return false;
} else {
return true;
}
}
// function untuk mengubah state (on/off) dari object Signal
private void changeSignalState(int state){
green.turnOn(changeToBool(state + 2));
yellow.turnOn(changeToBool(state + 1));
red.turnOn(changeToBool(state));
}
public void setDuration(int s){
duration = s;
}
}
DigitPane.java
/**
* Class untuk menampilkan timer
*/
import java.awt.*;
import javax.swing.*;
public class DigitPane extends JPanel {
private int second;
public Dimension getPreferredSize(){
FontMetrics fm = getFontMetrics(getFont());
return new Dimension(fm.stringWidth("00"), fm.getHeight());
}
// function untuk mengubah nilai timer dan mengupdate tampilan
public void setValue(int newVal){
if (second != newVal) {
second = newVal;
repaint();
}
}
public int getValue(){
return second;
}
// function u/ menampilkan integer sebagai string
private String pad(int value){
return String.format("%02d", value);
}
protected void paintComponent(Graphics g){
super.paintComponent(g);
g.setFont(new Font("LCD", Font.PLAIN, 24));
FontMetrics fm = getFontMetrics(g.getFont());
String text = pad(getValue());
int x = (getWidth() - fm.stringWidth(text)) / 2;
int y = ((getHeight()- fm.getHeight()) / 2) + fm.getAscent();
g.drawString(text, x, y);
}
}
SignalPane.java
/**
* Class untuk menggambar Lampu Traffic Light
*/
import java.awt.*;
import javax.swing.*;
class SignalPane extends JPanel{
Color on;
int radius = 50;
int border = 10;
boolean isOn;
SignalPane(Color color){
on = color;
isOn = false;
}
public void turnOn(boolean a){
isOn = a;
repaint();
}
public Dimension getPreferredSize(){
int size = (radius+border)*2;
return new Dimension( size, size );
}
protected void paintComponent(Graphics graphics){
graphics.setColor( Color.black );
graphics.fillRect(0,0,getWidth(),getHeight());
if (isOn){
graphics.setColor( on );
} else {
graphics.setColor( on.darker().darker().darker() );
}
graphics.fillOval( border,border,2*radius,2*radius );
}
}