Part 1: Iterating Over Collections



Objectives |1. Create an application with a graphical user interface. Separate the elements of the application into separate classes, for good O-O design.

2. Write an event handler (ActionListener) to handle user input events.

3. Implement an "enum" for constants needed in the program. | |

|Prerequisites |Read chapter 5 of textbook. |

|Evaluation |Instructor and TA will test your program. |

ALL WORK MUST BE YOUR OWN

Anyone who submits any work (lab, homework, quiz, programming assignment) that is not is own will receive "F" for the course and be reported to the university.

If you permit someone to copy your work, you will receive "F", too.

You can discuss concepts, method of solution, and conceptual design, but not share actual solutions or code. You can help identify defects, but don't correct another person's code.

Problem 1: Simple Distance Converter

Objective: create a visual distance converter for converting between kilometers and miles.

Task 1: Design Program Structure

Graphical elements and applications usually contain 3 parts: a "view" that is displayed on the screen, a "model" that contains the properties of the object being displayed, and a "controller" that handles events from the view.

In this lab, you must separate the user interface (view) from the converter logic (model).

Task 2: Write the UnitConverter class that Performs Computation

The UnitConverter class converts values between kilometers and miles. Store the conversion factor (meters per mile) as a static constant. Example: converter.mileToKilometer( 2 ) is 1.609344.

|UnitConverter |

|- METER_PER_MILE: double = 1609.344 |

|+ mileToKilometer( double ): double |

|+ kilometerToMile( double ): double |

Task 3: Design and Implement a Graphical User Interface

[pic]

You can use this code as a template. Add more components and complete the code.

import javax.swing.*;

import java.awt.*;

import java.awt.event.ActionEvent;

public class SimpleConverterUI extends JFrame

{

private JFrame frame; // a reference to our own frame.

// attributes for graphical components

private JLabel unitLabel1;

private JTextField inputField1;

//TODO define the other components

private JButton convertButton;

// The "view" needs a reference to the

// controller or other program parts.

private UnitConverter converter;

public SimplerConverterUI( UnitConverter uc ) {

this.converter = uc;

frame = this; // this class extends JFrame so this is a JFrame

frame.setTitle("..."); // set title bar of the window

initComponents( ); // add GUI components to the window

frame.pack(); // resize the Frame to match size of components

}

/** method to initialize components in the window */

private void initComponents() {

unitLabel1 = new JLabel("Kilometers");

inputField1 = new JTextField( 10 ); // 10 = width of the field

//TODO create the other components

// create a button and attach an action listener for "convert"

convertButton = new JButton( "Convert!" );

convertButton.addActionListener( new ConvertButtonListener() );

// get a reference to the JFrame's ContentPane (it is a Container)

Container contents = frame.getContentPane();

//TODO choose a layout manager to put the components on one row

contents.setLayout( ??????? ); // create a layout manager, chapter 5

// add the components to the layout

contents.add( inputField1 );

contents.add( unitLabel1 );

//TODO add the other components to content pane

}

class ConvertButtonListener implements ActionListener {

/** method to perform action when the button is pressed */

public void actionPerformed( ActionEvent evt ) {

//This line is for testing. Comment it out after you see how it works.

System.out.println("actionPerformed: evt="+evt.getActionCommand());

String s = inputField1.getText().trim();

if ( s.length() > 0 ) { // convert km to miles

//TODO handle errors. What if the input is not a number?

double km = Double.valueOf( s );

double miles = converter.kilometerToMile( km );

//TODO display result in JTextField for "miles" using setText( ) method.

inputField2.setText( _____________ );

}

}

} // end of the inner class

}

Task 4: Write a Main Class to Create Objects and Run the Application

In good layered software design, the user interface (upper layer) should not create the controller or model objects itself. Instead, another class sets a reference to those objects in the user interface. This is called "dependency injection". It helps reduce coupling and encourage software reuse.

Use a separate class to create your objects and connect them together.

Task 5: Test it!

[pic]

Task 6: Add a Clear Button

Add a "Clear" Button to clear the data from both JTextField. To clear a TextField, set the text to "" (empty string).

Task 7: Inverse Conversion

If the left JTextField (kilometers) is empty and the right JTextField (miles) has a number when the user presses Convert!, then convert value from miles to kilometers.

[pic]

Problem 2: Define Length Units for a General Distance Converter

The distance converter in Problem 1 is too limited. We want to convert between any type of length units, such as wa (Thai unit) to foot (English), or kilometer to light-years.

We will define a new data type named Length to hold the values for different units of length. Since these units are really just constants in the program, we will do this using an "enum".

1. Create an enum named Length.java and insert this code:

/** A definition of common units of length. */

public enum Length {

/* Define the members of the enumeration

* The attributes are:

* name = a string name for this unit,

* value = multiplier to convert to meters.

*/

/** meter */

METER( "Meter", 1.0 ),

/** foot, English unit = 0.3048 meter */

FOOT( "Foot", 0.3048 );

//TODO add more length units

/** name of this unit */

public final String name;

/** multiplier to convert this unit to meters */

public final double value;

/** Constructor for members of the enum */

Length(String name, double value){

//TODO complete this

}

public double getValue() { return value; }

public String toString() { return name; }

}

Add more units. For example:

1 mile = 1609.344 meter

1 inch = 0.0254 meter

1 micron = 1.0E-6 meter

1 wa = 2 meter (Thai unit)

2. Make a test file to print the elements of the enumeration. Run it!

public class TestLengths {

public static void showValues() {

/* display one element of an enumeration */

System.out.println( "1 mile is " + Length.MILE.value + " meters");

/* display all elements of an enumeration */

System.out.println( "Length contains: ");

for( Length u : Length.values() )

System.out.println( u + " = " + u.value );

}

public static void main(String[] args) { showValues(); }

}

4. For convenience, we defined the value of each unit as public static final. So you can get a unit's value by simply writing u.value. You can also use an accessor method: u.getValue( );

Problem 3: Use the Length data type in DistanceConverter

Copy SimpleConverterUI to ConverterUI. Replace the JLabel with JComboBox objects that contain the elements of your Length enum:

[pic]

1. Define two JComboBox components to replace the JLabel we used before. Use descriptive names for the JComboBox.

2. Initialize the JComboBox objects in initComponents() . JComboBox has an addItem( ) method to add one item to a combo box. Add all the elements of the Length class/enumeration:

private void initComponents( ) {

...

unitBox1 = new JComboBox( );

// add items to the combo box

for( Length u : Length.values() ) unitBox1.addItem( u );

2b. Another Way: JComboBox has a constructor that accepts an array of Objects as items.

// create ComboBox and add items to it using constructor

unitBox1 = new JComboBox( Length.values() );

3. Run the application. You should see combo boxes now.

(If you don't see them, maybe you forgot to add the combo boxes to the contentPane.)

4. Add a convert method to the LengthConverter class that converts any unit to any other unit:

For example, if you want to convert 3 kilometer to wa, you could use:

double wa = converter.convert( 3.0, Length.KILOMETER, Length.WA );

the convert method should return 3 (kilometer) * (1000 meter/kilometer) / (2 meter/wa).

The 1000 (meter/kilometer) is fromUnit.value (Length.KILOMETER) and 2 (meter/wa) is toUnit.value (Length.WA)

5. Modify the button ActionListener to get the current Length value from each JComboBox and call convert to convert the lengths.

To get the selected value of a JComboBox, call the getSelectedItem( ) method. getSelectedItem returns an Object, so we have to cast it back to the Length data type.

public void actionPerformed( ActionEvent evt ) {

// get the selected item from first ComboBox

Length unit1 = (Length) unitBox1.getSelectedItem( );

6. Run and test your code.

Define Your Own Length Units

Add some other units to the Length enumeration (or class). For example,

1 Light-year = 9460730472580800.0 meter

1 micron = 1.0E-6 meter

Notice that you don't have to modify any other part of your program to use the new units!

Review Questions

In the inner class named ConvertButtonListener we trimmed the input text like this:

String s = inputField1.getText().trim();

1. What class does the trim() method belong to?

2. Is it necessary to use trim here? How might it affect the program execution if we didn't trim the input?

3. When converting a String to a double, how do you avoid an error if the String does not contain a number?

4. What are the advantages of creating and using an enum? Compared to, say, using numbers in our UnitConverter class or defining constants in an interface (like "static double FOOT = 0.3408")?

References

How to Use Enumeration: lecture slides on class homepage. Textbook page 267-268.

List of Unit Conversions:

Definition of many length units:

-----------------------

convert to kilometers

UnitConverter

+ mileToKilometer( double ): double

+ kilometerToMile( double ): double

+ convert( quantity: double, fromUnit: Unit, toUnit: Unit ) : double

Add the member to the ComboBox. Java will use u.toString() to display u in ComboBox.

Loop over all members of the Unit class (enum)

call convert( 3 ) and output the result

create( uc )

SimpleConverterUI

Length

METER

KILOMETER

CENTIMETER

MILE

FOOT

WA

- name: String

+ value: double

+ values( ) : Unit[]

UnitConverter

Contains methods for converting lengths in different units.

ConverterUI

Graphical interface for unit converter

ConvertButtonListener is an ActionListener that performs an action when the button is pressed. It is an inner class so it can access the attributes of ConverterUI.

Read the number from a JTextField, convert the value, and write result in other field.

Constructor creates components and adds them to the content pane.

UI extends JFrame (a convenience).

Import AWT and Swing classes. components.

Define variables for components.

JButton

for action

JLabel

for unit2

JLabel

for "="

JLabel

for unit1

JTextField

for result

JTextField

for input

Title of JFrame

setVisible( true )

JComboBox of Length units

create

uc : UnitConverter

:Main

The names of static members of the enum. Put a comma after each name except the last one.

Each element has a String name and a value (in meters).

................
................

In order to avoid copyright disputes, this page is only a partial summary.

Google Online Preview   Download