// OdometerBuilder.java
// Simulates a simple car odometer
// import necessary components
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Random;
import javax.swing.*;
public class OdometerBuilder extends JFrame // create GUI and add elements
{
Odometer odometerSetter = new Odometer();
private JPanel titleJPanel; // JPanel to attach title
private JLabel title; // JLabel for title
private JLabel[] odometerJLabels; // JLabel with array of space for odometer
private JPanel titleAndOdometerJPanel; // JPanel to attach title panel and odometer panel to
private JPanel odometerJPanel; // JPanel for Jlabel odometer to be placed on
private JLabel prompt; // prompt to enter vehicle speed
private JTextField inputField; // field for user to enter vehicle speed
private JTextArea output; // window for displaying various outputs
private JPanel clockJPanel; // JPanel for clock to be attached to
private JLabel clock; // label of clock
private JPanel buttonsJPanel; // JPanel to attach buttons to
private JPanel westJPanel; // JPanel to attach clock, input and prompt onto
private JPanel centerJPanel; // JPanel to attach west panel and output label onto
private JPanel promptAndInputJPanel; // JPanel to attach prompt and input onto
private JButton startTrip; // start trip button
private JButton stopTrip; // stop trip button
private JButton tripLog; // trip log button
private JButton clear; // clear button
private JButton exit; // exit button
private int input = 0; // integer value for speed. set to 0 for error handling later
private int[] odometer; // array of integers for odometer
private int startOdometer; // starting odometer generated by random number
private int endOdometer; // odometer value when stop trip is pressed
private int distanceTravelled = 0; // distance travelled, set to 0 for error handling
private String startTime; // time of system clock at beginning of trip
private String stopTime; // time of system clock at end of trip
private Timer clockTimer; // timer object for the clock
private Timer odometerTimer; // timer object for the odometer
private final int CLOCK_DELAY = 1000; // 1000 milliseconds = 1 second delay
private int ODOMETER_DELAY; // delay for odometer defined later on
public OdometerBuilder() // method to build the GUI
{
titleAndOdometerJPanel = new JPanel(); // creates panel
titleAndOdometerJPanel.setBorder(BorderFactory.createMatteBorder(
5, 5, 5, 5, Color.yellow)); // adds a yellow border to panel
titleAndOdometerJPanel.setLayout( new GridLayout(2,1 ) ); // set layout of JPanel
titleJPanel = new JPanel(); // creates panel for title
titleJPanel.setBorder(BorderFactory.createMatteBorder(
0, 0, 5, 0, Color.yellow)); // adds yellow border
title = new JLabel( "Trip Logging System" ); // create label for title
title.setFont(new Font("Arial", Font.BOLD, 16)); // set font and size of title
title.setForeground( Color.BLUE ); // set colour of title
title.setHorizontalAlignment( JLabel.CENTER ); // set title to center of JLabel
titleJPanel.add( title ); // add title to JPanel
titleAndOdometerJPanel.add( titleJPanel ); // add titleJPanel to titleAndOdometerJPanel
odometerJLabels = new JLabel[ 6 ]; // create array for odometer digits
odometerJPanel = new JPanel(); // create JPanel for odometer labels
odometerJPanel.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0)); // create empty border to add space between components
odometerJPanel.setLayout( new GridLayout() ); // set layout of odometer panel
// the following sets labels to 0, colour to blue and size of font.
odometerJLabels[0] = new JLabel ("0");
odometerJLabels[0].setForeground( Color.BLUE );
odometerJLabels[0].setFont(new Font("Arial", Font.BOLD, 16));
odometerJLabels[1] = new JLabel ("0");
odometerJLabels[1].setForeground( Color.BLUE );
odometerJLabels[1].setFont(new Font("Arial", Font.BOLD, 16));
odometerJLabels[2] = new JLabel ("0");
odometerJLabels[2].setForeground( Color.BLUE );
odometerJLabels[2].setFont(new Font("Arial", Font.BOLD, 16));
odometerJLabels[3] = new JLabel ("0");
odometerJLabels[3].setForeground( Color.BLUE );
odometerJLabels[3].setFont(new Font("Arial", Font.BOLD, 16));
odometerJLabels[4] = new JLabel ("0");
odometerJLabels[4].setForeground( Color.BLUE );
odometerJLabels[4].setFont(new Font("Arial", Font.BOLD, 16));
odometerJLabels[5] = new JLabel ("0");
odometerJLabels[5].setForeground( Color.BLUE );
odometerJLabels[5].setFont(new Font("Arial", Font.BOLD, 16));
// add labels to odometer panels
odometerJPanel.add( odometerJLabels[0] );
odometerJPanel.add( odometerJLabels[1] );
odometerJPanel.add( odometerJLabels[2] );
odometerJPanel.add( odometerJLabels[3] );
odometerJPanel.add( odometerJLabels[4] );
odometerJPanel.add( odometerJLabels[5] );
titleAndOdometerJPanel.add( odometerJPanel ); // adds odometer panel to titleAndOdometerJPanel
prompt = new JLabel( "Enter vehicle speed(kmph): " ); // prompt to user
prompt.setForeground( Color.BLUE ); // set colour of prompt
inputField = new JTextField( 5 ); // create new input field to accept speed
inputField.addActionListener( new OdometerBuilder.InputHandler() ); // creates actionlistener to handle input from user
clockJPanel = new JPanel(); // creates new jpanel to attach clock to
clockJPanel.setLayout( new BorderLayout() ); // sets layout to borderlayout
clockJPanel.setBorder(BorderFactory.createMatteBorder(
1, 0, 0, 0, Color.gray)); // adds a border onto clock panel
clock = new JLabel( "00:00:00" ); // sets clock to 00:00:00 initially
clock.setFont(new Font("Arial", Font.BOLD, 16)); // sets fonts and size
clock.setForeground( Color.BLUE ); // sets colour of clock
clock.setHorizontalAlignment( JLabel.CENTER ); // sets clock to the center of the jpanel
clockJPanel.add( clock, BorderLayout.CENTER ); // adds clock to clock panel
output = new JTextArea( "" ); // creates new area for output
output.setBorder(BorderFactory.createMatteBorder(
0, 1, 0, 0, Color.gray)); // adds a border to output field
promptAndInputJPanel = new JPanel(); // creates new panel for prompy and input
promptAndInputJPanel.setBorder(BorderFactory.createEmptyBorder(25, 5, 25, 5)); // creates empty border to control size of components
promptAndInputJPanel.setLayout( new BorderLayout() ); // sets layout
promptAndInputJPanel.add( prompt, BorderLayout.WEST ); // adds prompt to the west of panel
promptAndInputJPanel.add( inputField, BorderLayout.CENTER ); // adds input to center of panel
westJPanel = new JPanel(); // creates panel for some components
westJPanel.setLayout( new BorderLayout() ); // sets layout
westJPanel.add( promptAndInputJPanel, BorderLayout.NORTH ); // adds prompt and input to north of west panel
westJPanel.add( clockJPanel, BorderLayout.CENTER ); // adds clock to center of west panel
centerJPanel = new JPanel(); // creates center panel
centerJPanel.setBorder(BorderFactory.createMatteBorder(
0, 5, 5, 5, Color.yellow)); // adds a yellow border to center panel
centerJPanel.setLayout( new GridLayout(1,2) ); // sets layout of center panel
centerJPanel.add( westJPanel ); // adds west panel to center panel
centerJPanel.add( output ); // adds output to center panel
buttonsJPanel = new JPanel(); // creates buttons panel
buttonsJPanel.setBorder(BorderFactory.createMatteBorder(
0, 5, 5, 5, Color.yellow)); // adds yellow border to buttons panel
buttonsJPanel.setLayout( new GridLayout() ); // sets layout of buttons panel
startTrip = new JButton( "Start Trip" ); // creates new jbutton for start trip
startTrip.addActionListener( // action listener for startTrip button
new ActionListener() // creates a new ActionListener
{
public void actionPerformed(ActionEvent e) // action performed method for startTrip button
{
if ( input == 0 ) // if input is still 0, displays following message
{
output.setText( "A Speed value between 1-150kmph "
+ "\nmust be entered before trip can begin." );
} // end if statement
else // if input has been set, the following occurs
{
output.setText( "" ); // resets outputJLabel after setting speed
generateOdometer(); // generate new random number for odometer
startOdometerTimer(); // calls method to start odometer timer
String timeformat = "HH:mm:ss"; // sets format for clock display
SimpleDateFormat obDateFormat = new SimpleDateFormat(timeformat); // creating time format
Calendar time = Calendar.getInstance(); // get systems time
clock.setText( obDateFormat.format( time.getTime()) ); // display systems time
startTime = clock.getText(); // saves systems time into startTime variable
startClockTimer(); // start timer for clock
} // end else
} // end actionPerformed method for start trip JButton
});// end new ActionListener
stopTrip = new JButton( "Stop Trip" ); // create new button for stop trip
stopTrip.addActionListener( // adds action listener
new ActionListener() // creates new action listener
{
public void actionPerformed(ActionEvent e) // method for action listener
{
if ( startOdometer == 0 ) // if startOdometer is still 0, display message
{
output.setText( "Trip needs to begin first."
+ "\nEnter a Speed and click Start Trip." );
} // end if
else // when start odometer is set approproately
{
stopClockTimer(); // stops timer for clock
stopOdometerTimer(); // stops timer for odometer
distanceTravelled(); // calls method to calculate distance travelled
} // end else
} // end method for action listener
}); // end action listener
tripLog = new JButton( "Trip Log" ); // creates new button for trip log
tripLog.addActionListener( // adds new action listener
new ActionListener() // creates new action listener
{
public void actionPerformed(ActionEvent e)
{
if ( distanceTravelled == 0 ) // if distance traveled is still 0, display following message
{
output.setText( "No trip recorded. "
+ "\nEnter a Speed to begin trip." );
} // end if
else // if user has set speed, the following is displayed
{
output.setText( String.format(
"TRIP LOG"
+ "\nSpeed: " + input + "kmph"
+ "\nEnd Meter Reading: " + endOdometer
+ "\nStart Meter Reading: " + startOdometer
+ "\nDistance Travelled (m): " + distanceTravelled + "metres"
+ "\nStart Time: " + startTime
+ "\nStop Time: " + stopTime ));
} // end else
} // end method for action listener
}); // end action listener
clear = new JButton( "Clear" ); // create new button for clear
clear.addActionListener( // add action listener for clear
new ActionListener() // creates new action listener
{
public void actionPerformed(ActionEvent e) // method for clear button
{
input = 0; // sets input back to 0
startOdometer = 0; // reset to 0 for error handling
clock.setText( "00:00:00" ); // resets clock label to 00:00:00
inputField.setText( "" ); // clears input field
inputField.setEditable( true ); // unlocks input field
output.setText( "" ); // clears output field
resetOdometer(); // calls reset odometer method to reset labels to 0
} // end method for action listener
}); // ends action listener
exit = new JButton( "Exit" ); // creates new button for exit
exit.addActionListener( // adds new action listener for exit
new ActionListener() // creates new action listener
{
public void actionPerformed(ActionEvent e) // method for exit button
{
exitWindow(); // method call to close window
} // end method for exit action listener
}); // end action listener
// adds all the buttons to buttons panel
buttonsJPanel.add( startTrip );
buttonsJPanel.add( stopTrip );
buttonsJPanel.add( tripLog );
buttonsJPanel.add( clear );
buttonsJPanel.add( exit );
// panels to JFrane
add( titleAndOdometerJPanel, BorderLayout.NORTH );
add( centerJPanel, BorderLayout.CENTER );
add( buttonsJPanel, BorderLayout.SOUTH );
} // end GUI constructor
private class InputHandler implements ActionListener // handler for user input
{
public void actionPerformed(ActionEvent event) // action performed method for user input
{
input = Integer.parseInt(inputField.getText()); // retrieves users input
if ( input > 0 && input <= 150 ) // if statement for appropriate input
{
inputField.setEditable( false ); // lock inputfield and display following message
output.setText( String.format("Speed registered successfully.\n"
+ "Click Start Trip.\nIf incorrect, click Clear and re-enter.") );
} // end if
else
{
inputField.setText( "" ); // reset input field and display following message
output.setText( String.format( "Speed must be 1-150kmph.\n"
+ "Please re-enter." ));
} // end else
} // end actionPerformed method
} // end ActionListener
private void generateOdometer() // method to generate a random number
{
odometerSetter.setOdometer();
endOdometer = startOdometer; // set endOdometer equal to startOdometer
odometerJLabels[0].setText(Integer.toString( odometer[0] ));
odometerJLabels[1].setText(Integer.toString( odometer[1] ));
odometerJLabels[2].setText(Integer.toString( odometer[2] ));
odometerJLabels[3].setText(Integer.toString( odometer[3] ));
odometerJLabels[4].setText(Integer.toString( odometer[4] ));
odometerJLabels[5].setText(Integer.toString( odometer[5] ));
} // end generateOdometer method
public void startOdometerTimer() // method to start timer for odometer
{
ODOMETER_DELAY = 3600000/(input*1000); // delay for odometer timer
odometerTimer = new Timer( ODOMETER_DELAY, new OdometerBuilder.OdometerHandler()); // creates new timer and handler
odometerTimer.start(); // starts timer
} // end method
private class OdometerHandler implements ActionListener // handler for odometer timer
{
public void actionPerformed( ActionEvent actionEvent )
{
// the following occurs every time the timer wakes up
endOdometer = endOdometer + 1; // adds one to odometer value
int rem; // int for calculations
// splits digits and sets into array and display new odometer on labels
odometer[0] = endOdometer/100000;
rem = endOdometer%100000;
odometerJLabels[0].setText(Integer.toString( odometer[0] ));
odometer[1] = rem/10000;
rem = rem%10000;
odometerJLabels[1].setText(Integer.toString( odometer[1] ));
odometer[2] = rem/1000;
rem = rem%1000;
odometerJLabels[2].setText(Integer.toString( odometer[2] ));
odometer[3] = rem/100;
rem = rem%100;
odometerJLabels[3].setText(Integer.toString( odometer[3] ));
odometer[4] = rem/10;
rem = rem%10;
odometerJLabels[4].setText(Integer.toString( odometer[4] ));
odometer[5] = rem/1;
odometerJLabels[5].setText(Integer.toString( odometer[5] ));
} // end method for action listener
} // end handler for odometer timer
public void stopOdometerTimer() // method to stop odometer timer
{
odometerTimer.stop(); // stops odometer timer
} // end method
public void startClockTimer() // method to start timer for clock
{
clockTimer = new Timer( CLOCK_DELAY, new OdometerBuilder.TimerHandler() ); // creates new timer and new handler for clock timer
clockTimer.start(); // starts clock timer
} // end method to start clock timer
// JOIN THIS CODE AND THE CODE IN THE NEXT POST TOGETHER TO MAKE THE COMPLETE CLASS