14: Input and Output

What We Will Cover


Illuminations

Questions from last class or the Reading?

Homework Questions?

Final Boss Event Approaching

  • Final Examinations Schedule
  • Note: If you need the proctoring center, schedule it two weeks early and overlapping the scheduled final exam time

14.1: Worlds and Files

Learner Outcomes

At the end of the lesson the student will be able to:

  • Read text files with a loop
  • Read and display a map file in a tile world

14.1.1: Review of Files and Streams

  • Sometimes we want to save data after our scenario finishes
  • For instances, we could store a high score list of players
  • Sometimes we want to use stored data so it is easier to make changes to scenarios
  • For example, we can read information from files to create tile maps
  • Reading a tile map from a file would let us change maps without recompiling
  • Also, we could have multiple tile map files to allow us to more easily create multiple levels in a scenario

Types of Files

  • All data in a file is ultimately just zeros and ones (bits)
  • However, we can classify the files based on their data into two broad categories: text and binary
  • In text files, the bytes in the file represent printable characters
  • Text files usually store Latin based characters (like English) in one byte
  • The byte for each character is defined by a standard such as ASCII (ASCII table) or UTF-8
  • Every line of text is delimited by end-of-line characters:
    • Unix/OS-X: "\n"
    • Windows: "\r\n"
  • We can read text files because each byte is interpreted by a program as textual characters
  • Data other than text is usually referred to as binary data
  • Each bit represents some type of encoded information like program instructions or integer data
  • Binary files are easily read by the computer but not by humans

Streams

  • To read and write files, we use a stream
  • A file stream is used to connect a file to a program
  • Input stream: accepts bytes from a source and delivers them to a program

    Input stream

  • Output stream: accepts bytes from a program and delivers the data to a destination

    Output stream

  • We use character streams to read and write text files:

Layering Streams

  • Usually, any one stream does have not all the functionality we want
  • Instead, it is common to "layer" two or more streams
  • We add buffers to our streams to make reading and writing faster

Buffer

  • When writing, we add a stream to convert from binary to character data like PrintWriter
  • When reading, we add an object to convert the character data into other types like int, double and String using a Scanner
  • The following instructions include the layers normally used to write and read text files

Step by Step Procedure for Writing Text Files

  1. Import the API libraries for file output.
    import java.io.*;
  2. Create the layered output stream.
    String fileName = "data.txt";
    PrintWriter out = new PrintWriter( // encode data as characters
                      new BufferedWriter( // buffer data for speed
                      new FileWriter(fileName))); // write bytes
    
  3. Write the data like printing to a terminal window.
    out.println("This is a string");
    out.println('c');
    out.println(1234);
    out.println(1.234);
    for (int i = 0; i <= 10; i++) {
        out.print(i + ",");
    }
    out.println();
    
  4. Close the file.
    out.close(); // flush buffer and free up resources
    

Step by Step Procedure for Reading Text Files

  1. Import the API libraries for file input.
    import java.io.*;
    import java.util.Scanner;
    
  2. Create the input stream.
    String fileName = "data.txt";
    Scanner in = new Scanner( // parse characters into data types
                 new BufferedReader( // buffer data for speed
                 new InputStreamReader( // read bytes as characters
                 getClass().getResourceAsStream(fileName)))); //JAR
    
  3. Read the data.
    String str = in.nextLine();
    char ch = in.nextLine().charAt(0);
    int x = in.nextInt();
    double d = in.nextDouble();
    while (in.hasNextInt()) {
        x = in.nextInt();
    }
    
  4. Close the file.
    in.close();  // flush buffer and free up resources
    

Check Yourself

  1. To store information, the computer saves the data in a __________.
  2. True or false: data in a file is restricted to characters only.
  3. When we want to write binary data to a file as character, we add the "layer" named ________.
  4. When we want to read character data and convert it to data types like int, double and String , we add a(n) ________.

14.1.2: Using Loops to Read a File

  • Sometimes we do not know how many data items are in a file
  • To solve this, the typical approach is to use a loop to read the file data
  • Within the loop we check whether or not more data is available from the input stream
  • The Scanner object has methods like hasNext() to see if there is any more input in the stream
  • We can use these methods to signal when your program reaches the end of a file
  • The following table shows some methods of the Scanner class for detecting if more data is available
  • Following the table is an example of a method that read an indefinite number of lines from a file

Some Test Methods of a Scanner Object

Method Description
hasNext() Returns true if this scanner has another token in its input.
hasNextLine() Returns true if there is another line in the input of this scanner.
hasNextDouble() Returns true if the next token can be interpreted as a double value.
hasNextInt() Returns true if the next token can be interpreted as an int value.

Method to Read a File with a Loop

public void readMap(String fileName)
{
    Scanner in = new Scanner(
                 new BufferedReader(
                 new InputStreamReader(
                 getClass().getResourceAsStream(fileName))));
    while (in.hasNext())
    {
        String line = in.nextLine();
        System.out.println(line);
    }
    in.close();
}

Try It: Read a File with a Loop (4m)

  1. Download the following scenario file, save it to a convenient location like the Desktop and unzip the file.

    Scenario file: platformer6.gfar or platformer6.zip.

  2. If using the zip version, extract the file and double-click the project.greenfoot file in the extracted folder
  3. Open the editor for the GameManager class and import the API libraries for file input.
    import java.io.*;
    import java.util.Scanner;
    
  4. Also in the GameManager class, add the readMap() method listed above.
  5. Compile the program to verify you implemented the new method correctly.
  6. To test the method, right-click on the scenario background and select the readMap(), entering an argument of: "maps/map1.txt" (with the quotes).

    Remember to include the double-quote marks (") because the entry is a string. You should see the map file in the terminal window. If you have problems, ask a guild mate or the instructor for help as needed.

  7. Save your updated scenario as we will be adding to it as the lesson continues.
  8. When finished, please help those around you.
  9. Be prepared to answer the following Check Yourself questions when called upon.

Check Yourself

  1. When the number of file data items is unknown you can use a ________ statement to read all the data.
  2. Of the following, the answer that is NOT a method of the Scanner class for testing the input stream is ________.
    1. hasNext()
    2. hasNextLine()
    3. hasNextInt()
    4. hasNoInput()
  3. When typing the file name, double-quotes are required to indicate a data type of ________.

14.1.3: Loading Files with ArrayList

  • We can read data from a file but we still need to store the data into the map array
  • We could load each line of the file directly into an array like:
    int i = 0;
    while (in.hasNext()) {
        String line = in.nextLine();
        map[i] = line;
    }
    
  • However, an array must be set to the correct size before we read from the file
  • Unless we know the number of lines in the map ahead of time, we need a list type that can grow as needed
  • One list type that can grow as needed is an ArrayList

Array Lists

  • An ArrayList is a class that organizes data into a List
  • We discussed the List type in lesson 8.1.4: Interacting with Lists of Actors
  • The ArrayList class is part of the standard library classes of Java
  • To make use of an ArrayList, we must import the class library
    import java.util.ArrayList;
  • The general syntax for declaring an ArrayList is:
    ArrayList<elementType> objectName;
    
  • Where:
    • elementType: the type of data stored in the list
    • objectName: the name you make up for the ArrayList
  • For example, to store a list of String objects we can declare:
    ArrayList<String> list;
  • After declaring an ArrayList, we construct one using the new operator
  • For example, to declare and construct an ArrayList to store strings:
    ArrayList<String> list = new ArrayList<String>();
    
  • The above declaration creates an ArrayList with zero elements
  • To add items to the list, we call the method add():
    list.add(element);
    
    Where element is a variable or literal of the correct type.
  • Each time we call the add() method, the ArrayList adds a new element to the end of the list

Some Commonly Used Constructors and Methods of the ArrayList<type> Class

Constructor/Method Description
ArrayList() Creates an empty list.
add(object) Adds the specified object to the end of the list.
get(index) Returns the object at the specified index in the list.
set(index, element) Returns the number of elements in the list.
size() Replaces the element at index with the new element.
toArray(array) Returns an array containing all of the elements in proper sequence.

Converting an ArrayList to an Array

  • Notice that the last method above returns an array from the ArrayList
  • After we have loaded all the lines from the file into an ArrayList, we call the toArray() method like:
    map = list.toArray(new String[0]);
    
  • Using an ArrayList we can read any number of lines from a file
  • After reading the lines, we then convert the lines to an array
  • We will update readMap() to complete this task in the next exercise

Updated Method readMap()

public void readMap(String fileName)
{
    ArrayList<String> list = new ArrayList<String>();
    Scanner in = new Scanner(
                 new BufferedReader(
                 new InputStreamReader(
                 getClass().getResourceAsStream(fileName))));
    while (in.hasNext()) {
        String line = in.nextLine();
        list.add(line);
        //System.out.println(line);
    }
    in.close();
    map = list.toArray(new String[0]);
    createPlatforms(map);
}

Check Yourself

  1. Of the following statements, the one that constructs a new ArrayList that stores String data is ________.
    1. ArrayList<GreenfootImage> images = new ArrayList<GreenfootImage>();
    2. ArrayList<String> strList = new ArrayList();
    3. ArrayList<String> strList = new ArrayList<String>;
    4. ArrayList<String> strList = new ArrayList<String>();
  2. To add an item to an ArrayList, call the method ________.
  3. To convert an ArrayList to an array, call the method ________.

Exercise 14.1: Reading a Map File (5m)

In this exercise, we load map data from a file and display the tile map in a scenario using a file chooser.

Specifications

  1. Start Greenfoot and open the scenario from the last Try It exercise.

    If you did not keep the scenario, then complete Try It: Read a File with a Loop now and then continue with these instructions.

  2. Open the editor for the GameManager class and import the API library for the ArrayList.
    import java.util.ArrayList;
    
  3. In addition, add the following instance variable::
    private String[] map;
    
  4. In the GameManager class, update the readMap() method as shown below.
    public void readMap(String fileName)
    {
        ArrayList<String> list = new ArrayList<String>();
        Scanner in = new Scanner(
                     new BufferedReader(
                     new InputStreamReader(
                     getClass().getResourceAsStream(fileName))));
        while (in.hasNext()) {
            String line = in.nextLine();
            list.add(line);
            //System.out.println(line);
        }
        in.close();
        map = list.toArray(new String[0]);
        createPlatforms(map);
    }
    
  5. Also in the constructor of GameManager, add the following method call before calling createPlatforms(map)
    readMap("maps/map1.txt");
    
  6. Now remove the MAP variable and replace all the uses of the MAP variable with map.

    Hint: use the search and replace function in the editor menu: Tools : Replace...

  7. Now remove the entire String[] MAP variable from the scenario by commenting or deleting:
    // private static final String[] MAP =
        // {
            // "BBBBBBBBBBBB                       BBBBBBBBBBBBB",
            // "BBBBBBBBBBBB                       BBBBBBBBBBBBB",
            // "BBBBBBBBBBBB                       BBBBBBBBBBBBB",
            // "BBBBBBBBBBBB    LMMMMR    LMR      BBBBBBBBBBBBB",
            // "BBBBBBBBBBBB       P       P      LBBBBBBBBBBBBB",
            // "BBBBBBBBBBBB       P       P       BBBBBBBBBBBBB",
            // "BBBBBBBBBBBB       P     LMMMR     BBBBBBBBBBBBB",
            // "BBBBBBBBBBBBMMR    P       P       BBBBBBBBBBBBB",
            // "BBBBBBBBBBBB       PMR     P     LMBBBBBBBBBBBBB",
            // "BBBBBBBBBBBB       P       P       BBBBBBBBBBBBB",
            // "BBBBBBBBBBBB       P       P       BBBBBBBBBBBBB",
            // "BBBBBBBBBBBB     LMMMMMMMMMMMR     BBBBBBBBBBBBB",
            // "BBBBBBBBBBBB           P           BBBBBBBBBBBBB",
            // "BBBBBBBBBBBB           P           BBBBBBBBBBBBB",
            // "BBBBBBBBBBBBMMMR       P        LMMBBBBBBBBBBBBB",
            // "BBBBBBBBBBBB           P           BBBBBBBBBBBBB",
            // "BBBBBBBBBBBB           P                        ",
            // "BBBBBBBBBBBB           P                        ",
            // "MMMMMMMMMMMMMMMMMMMMMMMMMMR   LMMMMMMMMMMMMMMMMM"
        // };
    
  8. Compile the GameManager class to verify you implemented the variable changes correctly.
  9. Compile and run your updated scenario and verify the map is still displayed.

    If you have problems, ask a guild mate or the instructor for help as needed.

  10. We can now load other maps by changing the line:
    readMap("maps/map1.txt");
    
    to something like:
    readMap("maps/map2.txt");
    
  11. Save your updated scenario as we will be adding to it as the lesson continues and eventually turning it in as part of lab 14.

As time permits, read the following sections and be prepared to answer the Check Yourself questions in the section: 14.1.4: Review.

14.1.4: Review

Answer these questions to check your understanding. You can find more information by following the links after the question.

  1. What is the difference between a text file and a binary file? (14.1.1)
  2. What is an input stream? (14.1.1)
  3. What is an output stream? (14.1.1)
  4. What are three streams we typically layer for program output? (14.1.1)
  5. What are the steps for writing files? (14.1.1)
  6. What are the steps for reading files? (14.1.1)
  7. What technique can we use to read all the data from a file, if we do not know how much data is in the file? (14.1.2)
  8. Which of the following statements constructs a new ArrayList that stores String data? (14.1.3)
    1. ArrayList<GreenfootImage> images = new ArrayList<GreenfootImage>();
    2. ArrayList<String> strList = new ArrayList();
    3. ArrayList<String> strList = new ArrayList<String>;
    4. ArrayList<String> strList = new ArrayList<String>();
  9. Which of the following statements adds a new string to the end of the list? (14.1.3)
    1. add("foo");
    2. strList.add("foo");
    3. strList.addToEnd("foo");
    4. strList.addString("foo");

14.2: Buttons, Labels and TextFields

Learner Outcomes

At the end of the lesson the student will be able to:

  • Write code to add buttons to scenarios
  • Write code to add labels to scenarios
  • Write code to add text fields to scenarios
  • Write code that responds to action events

14.2.1: Adding GUI Components to Scenarios

  • A Graphical User Interface (GUI) allows users to interact with a program through graphical icons and other visual indicators
  • GUI components, like buttons and text fields, are typical in a GUI system
  • Java provides GUI components through libraries for buttons and text fields
  • However, we cannot directly display these GUI components in a Greenfoot scenario window
  • Instead, we would have to create a separate GUI window which is cumbersome
  • To get around this limitation, your instructor created a GUI library that runs in Greenfoot

Introducing GreenGUI

  • Let us look at the GreenGUI scenario:

    Scenario file: GreenGUI.gfar or GreenGUI.zip

  • Save the file in a convenient location like the Desktop and launch the archive
  • If using the zip version, extract the file and double-click the project.greenfoot file in the extracted folder
  • The Green GUI scenario shows how to fully utilize buttons and labels
  • Notice the rollover and pressed effects on the buttons
  • Also, notice how we can ask the user for information

GUI Organization

  • Each component is in its own class:
    • Button: Constructs and handles buttons
    • Label: Constructs and handles text labels
  • The user input text field is from the ask() method of the Greenfoot class
  • The button and label components allows many options like changing font sizes, foreground and background colors, and changing the text
  • The GUIWorld class has many examples of how to install the components
  • The ButtonChecker class shows examples of how to use the various features
  • We will look at how to use individual components in the following sections

Try It: Install the GUI Components (3m)

  1. Download the Green GUI scenario and save it to a convenient location like the Desktop and then double-click to open the gfar file.

    Scenario file: GreenGUI.gfar or GreenGUI.zip

    If you download the zip version, extract the file first and then double-click the project.greenfoot file in the extracted folder.
  2. Download the following scenario file, save it to a convenient location like the Desktop, and double-click to open the gfar file.

    Scenario file: platformer7.gfar or platformer7.zip.

    If you download the zip version, extract the file first and then double-click the project.greenfoot file in the extracted folder.
  3. Copy the following source code files from the Green GUI to the Platformer scenario:
    • Button.java
    • Label.java

    If you have problems, ask a classmate or the instructor for help as needed.

  4. In addition, copy the images from the Green GUI scenario to the Platformer scenario's images folder.

    You may skip copying the person.png image file.

  5. If the Platformer scenario is started, then exit the scenario.
  6. Restart the Platformer scenario and compile it to verify you copied the component classes correctly.

    If you have problems, ask a classmate or the instructor for help as needed.

  7. When finished please help those around you.
  8. Be prepared to answer the following Check Yourself questions when called upon.

Check Yourself

  1. GUI stands for G________ U________ I________.
  2. True or false: we cannot add Java's GUI components to a scenario's window.
  3. Of the following, ________ is not a component provided by GUI World.
    1. Button
    2. Dialog
    3. Label
    4. TextField
  4. True or false: to use a GUI component (like Button) we must include all the component files (like Label) in our scenario.

14.2.2: Creating a Label Component

  • A Label is an Actor with an image containing text that we may add to a scenario
  • To construct a label we must include the Label class in our scenario

Constructing a Label

  • To create a label, we write code like the following:
    Label myLabel = new Label("Some text");
    
  • To add the label to a scenario, we use the addObject() method of World
  • For example:
    addObject(myLabel, 115, 50);
    
  • As we can see below, Label has several constructors and methods that let us choose how the label looks
  • For instance, if we want a label with larger blue text we write:
    Label colorful = new Label("Some text", 24, Color.BLUE);
    addObject(label, x, y);
    
  • We can see the list of constructors in the following table

Constructors and Methods of the Label Class

Constructor Description
Label() Constructs a label with a default message and settings.
Label(textString) Constructs a label with the specified text using default settings.
Label(textString, textSize) Constructs a label with black text of the specified text size on a clear background.
Label(textString, textSize, colorObj) Constructs a label of the specified size and text color on a clear background.
Label(textString, textSize, textColorObj, bgColorObj) Constructs a label with text of the specified size and color on a background of the specified color.
String getText() Returns the text for this label.
void setText(textString) Sets the text to be displayed.
void setBackgroundColor(colorObj) Sets a new background color for this button.

Getting and Setting Text

  • We may construct a Label with specified text like
    Label label = new Label("Label 24", 24);
    
  • We can set new text using code like:
    label.setText(answer);
    
  • We can retrieve the current text of a label using getText() like:
    String text = label2.getText();
    System.out.println(text);
    
  • Using getText() may be useful when trying to find a specific label:
    String answer = "42";
    List<Label> labels = getWorld().getObjects(Label.class);
    for (Label label : labels)
    {
        if (label.getText().equals("Label"))
        {
            label.setText(answer);
        }
    }
    

Setting a Background Color

  • The default background color for a Label object is clear (transparent)
  • We can change the background color to a new color by calling setBackgroundColor() like:
    label.setBackgroundColor(Color.GREEN);
    

Mutliple-Line Labels

  • We can specify labels with multiple lines of text
  • To manually break lines, we use the "\n" character
  • For example, this code creates a three-line label:
    Label label = new Label("Lines\nwrapped\nwith \\n");
    
    That looks like this:

    Multiple line label

  • Notice how we are printing a "\n" character by escaping the "\n" with an extra "\"
  • The backslash is known as an escape character

Try It: Make a Label (5m)

  1. Start Greenfoot and open the platformer scenario from the last Try It exercise.

    If you did not keep the scenario, then complete Try It: Install the GUI Components now and then continue with these instructions.

  2. Open the editor for GameManager.
  3. Add the following Label object to the world at the end of the constructor.
    Label label = new Label("Exit \u2192", 18, Color.WHITE);
    addObject(label, 400, 50);
    
    The \u2192 is a right arrow in unicode.
  4. Compile the scenario to see the label.

    Experiment with different label possibilities by making changes to the text, text size, and colors.

  5. Save your updated scenario as we will be adding to it as the lesson continues.
  6. When finished please help those around you.
  7. Be prepared to answer the following Check Yourself questions when called upon.

Check Yourself

  1. Enter the code to construct a Label object with the text, "Java rules!" in a red color.

    (an answer)

  2. To add a label object to a scenario, call the ________ method of the World class.
  3. True or false: we can construct a text image with GreenfootImage, but we always need a Label or other Actor object to add the image to a scenario.
  4. To cause a new line in the text of a label use the character sequence ________.

14.2.3: Creating a Button Component

  • A Button is a GUI component that responds to mouse clicks
  • To construct a button we must include the Button class in our scenario

Buttons States

  • A button has three different images it presents depending on the mouse
  • The following are the different images for the default Style.RECTANGLE:

    Button up Button hover Button down
    Button up Button hover Button down

  • To make use of these images, we place them in our scenario's images folder

Constructing a Button

  • To create a Button, we write code like:
    Button button = new Button("Click me");
    
  • To add the button to a scenario, we use the addObject() method of World
  • For example:
    addObject(button, 350, 50);
    
  • As we can see below, Button has several constructors and methods that let us choose how the button looks
  • For instance, if we want a button with larger blue text we write:
    Button btn = new Button("Click me", 24, Color.BLUE);
    addObject(btn, x, y);
    
  • We can see the list of constructors and methods in the following table

Constructors of the Button Class

Constructor Description
Button() Constructs a button with no set text or image.
Button(textString) Constructs a button with the specified text using default settings.
Button(textString, textSize) Constructs a button with black text of the specified text size.
Button(textString, textSize, textColorObj) Constructs a button of the specified size and text color.
Button(textString, textSize, textColorObj, style) Constructs a button with text of the specified size and color on a button object of the specified style.

Some Commonly Used Methods of the Button Class

Method Description
String getText() Returns the text for this button.
void setText(textString) Sets the text to be displayed.
void setBackgroundColor(colorObj) Sets a new background color for this button.
boolean isPressed() Returns true if this button is currently down (pressed), otherwise returns false.
int getID() Gets the identifier number of the component.
void setID(idNumber) Sets the identifier number of the component.

Button Methods

  • The Button class methods work like the Label methods of the same name
  • However, the button has a few extra methods that the label does not
  • For example, isPressed() tests if the button is currently down (pressed)
  • We call the isPressed() method to see if we need to respond to a button press
    if (button.isPressed())
    {
        // do something
    }
    
  • We may use the getID() and setID() methods to identify a particular button in the scenario
  • By calling setID(), we can set a unique id number
    button.setID(42);
    
  • Later, we may test the id number to see if it is the button we are looking for
    if (button.getID() == 42)
    {
        // do something with this button
    }
    

Button Styles

  • The current styles supported by the Button class are: RECTANGLE, ROUNDED, CIRCLE
  • Thus there are nine images needed to use the Button class
  • To select a style write: Style.X, where X is one of the styles
  • For example, to select the ROUNDED style write the code:
    Style.ROUNDED

Try It: Make a Button (5m)

  1. Start Greenfoot and open the scenario from the last Try It exercise.

    If you did not keep the scenario, then complete Try It: Make a Label now and then continue with these instructions.

  2. Open the editor for GameManager and add the following instance variables to the class:
    private Button button;
    
  3. Locate the constructor and add the following code at the end of the constructor:
    button = new Button("Choose level");
    addObject(button, 85, 28);
    
  4. Compile and run the scenario to see the button.

    Notice how the button changes when the mouse moves over it and when pressed.

  5. Experiment with different button options by making changes to the style, text and colors.
  6. Add the following act() method to the GameManager.
    public void act()
    {
        if (button.isPressed())
        {
            System.out.println(button);
        }
    }
    
  7. Test your act() method by running the scenario and pressing the button.

    Notice that each button press prints the button information more than one time. Sometimes we will need to limit the number of button presses to which our code responds.

  8. Update the if-statement of the act method by adding a second test condition as shown.
    if (button.isPressed() && Greenfoot.mouseClicked(button))
    
  9. Retest your act() method by running the scenario and pressing the button.

    Notice that now each button press prints the button information only one time. The mouseClicked() only returns true after the mouse button is no longer pressed.

  10. Save your updated scenario as we will be adding to it as the lesson continues.
  11. When finished please help those around you.
  12. Be prepared to answer the following Check Yourself questions when called upon.

Check Yourself

  1. True or false: we can adjust the way a button looks using the same options as a label.
  2. Enter the code to create a button with the text, "Click for Java".

    (an answer)

14.2.4: Collecting Player Input as Text

  • The Greenfoot class has a method that collects player input:
    String ask(String prompt)
    
  • The method freezes the scenario and asks the user for a value
  • For example if we wrote the following code in an act() method:
    String map = Greenfoot.ask("Enter the name of the map:");
    
    we would see at the bottom of the world:

    ask method call

  • Once the user types in a value and presses the Enter key, the scenario resumes
  • We will explore how to use this technique in the following exercise

Check Yourself

  1. Write the code to ask the player for their name.

Exercise 14.2: Adding GUI Components (8m)

In this exercise, we add a level system to the platformer7 scenario.

Specifications

  1. Make sure you have already completed the following Try It exercises from this lesson:
  2. Open the editor for GameManager and locate the act() method added in the last exercise
    public void act()
    {
        if (button.isPressed() && Greenfoot.mouseClicked(button))
        {
            System.out.println(button);
        }
    }
    
  3. Replace System.out.println(button); with the following statements shown in bold.
    public void act()
    {
        if (button.isPressed() && Greenfoot.mouseClicked(button))
        {
            String map = Greenfoot.ask("Enter the name of the map:");
            map = "maps/" + map;
            System.out.println(map);
        }
    }
    
  4. Test your code by running the scenario, pressing the button, typing in text and pressing the Enter key.

    Notice that the information typed by the user in the text box is displayed in the Terminal window.

  5. We now want to let the user enter a map to read from a file. Replace System.out.println(map); with the following statements shown in bold.
    public void act()
    {
        if (button.isPressed() && Greenfoot.mouseClicked(button))
        {
            String map = Greenfoot.ask("Enter the name of the map:");
            map = "maps/" + map;
            readMap(map);
        }
    }
    
  6. Test your code by running the scenario, pressing the button, typing in the other map file: map2.txt

    Notice that the old platforms are still in place an we have overlaid two map files. Before we can load a new map file, we need to remove the previous platforms.

  7. Add the code shown in bold to the act() method.
    public void act()
    {
        if (button.isPressed() && Greenfoot.mouseClicked(button))
        {
            String map = Greenfoot.ask("Enter the name of the map:");
            map = "maps/" + map;
            removeObjects(getObjects(Platform.class));
            readMap(map);
        }
    }
    
  8. Test your code by running the scenario, pressing the button, typing in the other map file: map2.txt

    You should now see a new map loaded. If you have problems, please ask a classmate or the instructor for help.

  9. Save your platformer7 scenario to submit to Canvas as part of the Final Lab.

As time permits, read the following sections and be prepared to answer the Check Yourself questions in the section: 14.2.5: Review.

14.2.5: Review

  • A Graphical User Interface (GUI) allows users to interact with a program through graphical icons and other visual indicators
  • GUI components, like buttons and text fields, are typical in a GUI system
  • Java provides GUI components through libraries for buttons and text fields
  • However, we cannot directly display these GUI components in a Greenfoot scenario window
  • To add a GUI, your instructor created a GUI library for Greenfoot
  • Each component has its own class:
    • Button: Constructs and handles buttons
    • Label: Constructs and handles text labels
  • To use any component, we must include the class for the component
  • The GUIWorld class has many examples of how to use the various features

    Scenario file: GreenGUI.gfar.

  • For instructions on installing GUI Components into a scenario, see Try It: Install the GUI Components

Constructing Label's

  • A label is an image with text that we can add to a scenario
  • To create a label, we write code like the following:
    Label myLabel = new Label("Some text");
    
  • To add the label to a scenario, we use the addObject() method of World like:
    addObject(myLabel, x, y);
    
  • We can construct labels with various settings as described in section 14.2.2: Creating a Label Component

Creating Button's

  • A button is a GUI component that responds to mouse clicks
  • To create a Button, we write code like:
    Button btn = new Button("Click me");
    
  • To add the button to a scenario, we use the addObject() method of World like:
    addObject(btn, x, y);
    
  • We can construct buttons with various settings as described in section 14.2.3: Creating a Button Component
  • To detect button presses we call the isPressed() method of the Button class.

Creating TextField's

  • A text field is a GUI component that allows the user to enter a single line of text
  • Text input is provided by Greenfoot.ask()

Answer these questions to check your understanding. You can find more information by following the links after the question.

  1. GUI stands for G___________ U_________ I___________. (14.2.1)
  2. True or false: we cannot add Java's GUI components to a scenario's window. (14.2.1)
  3. What are two GUI components provided by GUI World? (14.2.1)
  4. True or false: to use a GUI component (like Button) we must include all the component files (like Label) in our scenario. (14.2.1)
  5. Write a statement to create a label with the text, "Java rules!" in a red color. (14.2.2)
  6. Write the code to construct a label with the text, "Java rules!", in a large blue font color on a yellow background. (14.2.2)
  7. What special character sequence will cause a new line in the text of a label? (14.2.2)
  8. True or false: we can adjust the way a button looks using the same options as a label. (14.2.3)
  9. Write code to create a button with the text, "Click for Java". (14.2.3)
  10. Write the code to ask the player for their name. (14.2.4)

14.3: User Testing

Learner Outcomes

At the end of the lesson the student will be able to:

  • Provide feedback on other student' scenarios
  • Received feedback on your own scenario

14.3.1: About User Testing

  • The user-testable prototype is a complete and useable scenario
  • Some final touches, like opening screens, may be absent
  • However, the scenario is playable and testable
  • During testing, we have the opportunity to provide the developers with important feedback
  • With the feedback, they can improve the quality of the scenario before submitting the final project

User-Testable Prototype Developer Instructions

  1. Load your guild's project prototype onto at least three classroom computers
  2. Be prepared to let other students come and test your project
  3. Place written instructions next to each computer
  4. Open a browser with a link to the online form (see below)
  5. After the testing session is complete, you can view the reports online (see below)

Testing the Scenario

  • Do not discuss the game with a developer until after your play testing is complete.
  • Read the instructions for the game and then play the game through at least once.
  • Fill out the online form to record your observations (see below).
  • Make certain to correctly spell both your avatar name and the guild name to ensure credit.
  • Also make sure the instructor knows your avatar name

Instructor Evaluation of Project

  • During user testing, the instructor will also be evaluating projects
  • Because time is tight, please come and demo your project if your name is called
  • Instructor feedback will be reported in Canvas

14.3.2: Steer Clear of the Dark Path

  • Even if you enjoy talking trash with friends, do not indulge during the review
  • Avoid ridicule or dismissive language
    • NO: "The feeling was Meh. The ball of light was uninspiring."
    • NO: "I can't see around that ridiculous ball of puke-colored light."
    • YES: "The concept is good but the light around this character obstructs the view and is an unpleasant shade of yellow."
  • Do not use irony and sarcasm
    • NO: "The art for that makes me want to gouge out my eyes."
    • NO: "I'm so amazed by that effect, I just want to quit my job and worship the developer."
    • NO: "The fire effect is super impressive. It's the most amazing fire I've ever seen. Really."
    • YES: "The fire effect is good but would be more impressive if it was larger and if it shimmered more."
  • Do not make it personal
    • NO: "If you can't see how this isn't fun, then you're stupid."
    • YES: "The scenario would be more enjoyable if I did not die every time I started.
    • NO: "Whoever coded this [particular feature] deserves to fail."
    • YES: "The player takes off like a rocket when falling and then dies."
  • The NO comments like those above may see funny, but hurting others is never funny
  • Treat scenario creators with courtesy and respect
  • We will explore how to give constructive feedback in the next section

14.3.3: How to Give Constructive Scenario Feedback

  • The goal of reviewing a student's scenario is to help them improve
  • While they may want to improve, people are generally sensitive to criticism
  • We want to phrase our feedback so that it is valued by the recipient
  • Here are some suggestions on how to give constructive scenario feedback

Review as you want to be reviewed

  • Most people want the same thing: to have people enjoy their scenarios
  • Make sure your feedback is courteous and thoughtful
  • Review other scenarios as you would want other people to review your scenario
  • Avoid antisocial comments

Bundle suggestions with compliments

  • Overall, give at least as much positive feedback as you do negative
  • Start with a positive observation before offering a criticism
  • Make sure you follow criticism with a suggested solution
  • After the solution, offer a positive observation again
  • The courtesy of placing some praise before and after a suggestion for improvement makes receiving the criticism easier to take

Be specific

  • Describe specifically what you have observed
  • Where in the scenario did you observe something and what were you doing?
  • For example, "I was playing _____ and I tried _____ when ____ happened."
  • Describe how you reacted to what you observed

Put the feedback in perspective

  • Describe whether your criticism or suggestion is major or minor
  • When you are sending a message, make sure the tone of your words is appropriate

Starter Phrases for Giving Feedback

  • "I thought you did a good job with/of _____."
  • "One area I thought could be improved was _____."
  • "The core mechanic was _____. It made it fun to _____."
  • "The visual design was _____ and it made me think/feel _____."
  • "I was playing _____ and I tried _____ when ____ happened."

14.3.4: Forms and Feedback Results

Reading Feedback

  • Determine whether the comment is legitimate. Don't waste time if the comment is just to bully or offend you.
  • Pick out useful information. If someone is alerting you to a problem with your scenario that you were not aware of, then read it carefully.
  • Decide which points you agree with. Think about whether your scenario would be better if you followed the reviewer's advice.
  • Keep track of aspects you want to fix.
  • Think about what you are doing right.
  • Take note of concepts or techniques that should be extended or repeated.

Wrap Up

Due Next:
Q13: User-Testable Prototype (11/30/17)
Lab 14: Final Lab (12/5/17)
Q14: Final Project (12/7/17)
  • When class is over, please shut down your computer
  • You may complete unfinished lesson exercises at any time before the due date.
Home | Canvas | Schedule | Syllabus | Room Policies
Help | FAQ's | HowTo's | Links
Last Updated: December 01 2017 @01:55:45