Question: Objective: You will use the vehicle library you developed over the previous few assignments to provide a basic user interface that will allow ordinary (non-programmers)

Objective:

You will use the vehicle library you developed over the previous few assignments to provide a basic user interface that will allow ordinary (non-programmers) to build, store, display, and sort vehicle objects in a car garage.

This will be the last project dealing with the theme of cars and vehicles --- in some sense, it's replacing the Tester classes you've been writing with a user interface. In particular, you will practice:

  • construction of a basic Graphical User Interface (GUI) with some input validation logic;
  • use of the Model View Controller (MVC) architectural pattern;
  • writing code in anevent-drivenstyle that employs lambda expressions and higher order functions as means of responding to user-input events (e.g.: clicks, button presses, mouse-drags, etc.).
  • use of Java's native Swing graphics library and it's included JComponents (JTextField, JComboBox, JLabel, etc.);
  • implementing functional interfaces (ActionListener, for example, is a functional interface);

All remaining programming assignments will involve the development of some user interface component (some more intricate than others) + construction of model classes --- so start early on them!

Getting Started:

Since MVC will be used, you will use packages to structure and organize your classes in a way that reflects the separation of concerns dictated by the MVC architectural pattern:

  1. Make an empty project called asg4,
  2. right click the blue "src" folder and select "New" > "Package" > then type edu.psu.ist into the dialog box,
  3. right click on the newly created package > select "New" > "Java Class" > and name it "App",
  4. now add the following packages to the edu.psu.ist package: model, view, and controller (keep the "App" class outside of these).

Below you'll find a picture illustrating the project structure (note:yours won't have classes other than "App" yet).

Your first order of business will be moving over all the classes you developed in asg3 (except Tester) into the "edu.psu.ist.model" package. The primary model class that this particular app will manipulate is just be the Garage class you developed previously.

Part 1: Designing a GarageForm

You can construct the GarageForm class manually or using the IDE's swing form builder (if you have no experience organizing JComponents manually, I suggest using the form builder).

Below is a picture of one potential organization of the GarageForm along with the various JComponents that were used to make it:

Technically, all of the illustrated JComponents rest on a JPanel. I'll leave the minutiae of the GUI's visual appearance to you, however itmustprovide:

  • a button to add a car to the garage,
  • a button sort the garage,
  • a button clear/empty the garage.

Itmustalso provide JTextfields suitable for building an entire Truck, Dually Truck, or Sedan object..

  • .. this implies that you'll also need JTextFields for entering the information required to instantiate AutoModel and Manufacturer model objects (since vehicle objects can't be instantiated without them).

Itmustprovide a region where one can render the vehicles stored in the garage on separate lines, this is what the JTextArea is used for in the above example (in this region, you can simply populate/render it by calling toString() on your Garage model object --- though that will be done in the GarageController class).

Feel free to use radio buttons or some other means of specifying what type of vehicle one is adding to the garage (and whether or not it is still in production). This is required as well.

Part 2: The View Class

The View class should encapsulate an instance of the garage form class. The basic setup is given below:

/** * A basic view class that serves as the outer frame for the garage application. *

* It also serves as a sort of "helper layer" between the {@link JComponent}s that * make up the actual {@link GarageForm} class while also providing some utility/helper * methods. */ public class GarageView extends JFrame { private final GarageForm form; public GarageView() { this.form = new GarageForm(); // you'll need to add getters for all JComponents in // the form class that is generated by the IDE's formbuilder. // I suggest having the IDE generate getter methods for you once // you are happy with the visual appearance of your form. JPanel content = form.getMyPanel(); // Can set min/max dimensions of the window by calling: // this.setMaximumSize(new Dimension(/*desired width*/, /*desired height*/)); // this.setMinimumSize(..); // TODO: // can include custom setup code for some JComponents involved in your form // (e.g.: do you want a box always checked when the app boots? Do it here) // boilerplate/standard code -- include this.. this.setContentPane(content); this.pack(); this.setTitle("Garage Gui"); // change if you want :-) this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } // Some ideas for potential helper methods your view class might offer: /** * Returns a reference to the {@link GarageForm} instance stored in this * class. */ public GarageForm garageForm() { return form; } /** * Returns an inclusive list of well-formed {@link Year} objects from * production start and stop year text fields. *

* For example, if the start year field holds 2000 and the stop year * field holds 2004 then the returned list should include the following * {@link Year} objects: 2000, 2001, 2002, 2003, 2004. *

* Note: This method assumes that the start year is <= to the * stop year and that the text in both the start and stop textfields * are valid integers (note: this should be validated in the controller logic) */ public List retrieveProductionYears() { // todo.. } }

Tip:since this class is only intended to support/facilitate the work you will need to do in the GarageController class, keep the View class methods simple, straightforward, and short (no terribly complex logic ---you should not, for example, be attaching listeners for buttons, etc. in this class).

Part 3: The GarageController Class

This is where a bulk of your application's logic will reside. Below is a snippet to get you started on it:

public class GarageController { private Garage garageModel; // the controller can see both the view and model private GarageView view; // the view and model classes (by themselves) should be totally // oblivious to each other public GarageController(Garage garageModel, GarageView view) { this.garageModel = garageModel; this.view = view; // TODO: // attach action listeners (using lambda expressions) to // the various JComponents using the view class and its // underlying form } // if you don't want a lot of clutter in your constructor above, // you can define "inner classes" for your various action listeners (if you prefer) // ... for example: private class SomeListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { } } }

A fair bit of code will go inside the constructor if all your event handling code is carried out using lambda expressions (this is totally fine). Though, that said, see the code snippet above for an alternative if you feel your lambda expressions is getting too lengthy.

As you start working on this, and implementing the controller logic, you'll likely notice that a fair bit of the data should being received by the controller's listener classes will require validation.

This assignment requires you to provide the following input validation logic as part of your controller:

  • You should not be able to add a car to the garage if the any of the text fields are blank.
  • The start and stop production year textfields should contain valid integers and the start production year given should be <= the stop production year --- the action listener you attach to the add car button should be a good place to check this (and many of these items)
  • Ensure the mpg entered is a valid int and that it is positive and nonzero
  • When the form indicates the car is in production, the stop production year field had better contain the current year (hint: use Year.now() to retrieve the current year)

Test these carefully! And make sure you add a few cars to the garage to ensure all the buttons are working and updating the UI accordingly (sorting, clearing, etc.).

Step by Step Solution

There are 3 Steps involved in it

1 Expert Approved Answer
Step: 1 Unlock blur-text-image
Question Has Been Solved by an Expert!

Get step-by-step solutions from verified subject matter experts

Step: 2 Unlock
Step: 3 Unlock

Students Have Also Explored These Related Programming Questions!