14 Mar 2012 [ 201 week9 hw ]

Email all files as attachments (or zip up your full project folder) to me at jal2016@email.vccs.edu with subject CSC 201 HW6.

Alternately, put your homework in a hw6 folder in your 201-hw Mercurial repository on BitBucket.

Due Thursday, Mar 23.

1: Simple GUI example

Complete the program below so that it shows a count of the number of times you click the button. You'll need to determine how to change the text of the JLabel instance member. You might also need to add one or more additional instance variables.

import javax.swing.*;

/**
 * Class to test simple use of a button.
 * It should show a count of the button clicks in the label.
 */
public class ButtonTest extends JPanel {
    JLabel countLabel;
    JButton button;
    public ButtonTest() {
        countLabel = new JLabel("0");
        button = new JButton("Click me");
        add(button);
        add(countLabel);
    }
    
    // Set up main window and add our components.
    public static void buildGUI() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setContentPane(new ButtonTest());
        frame.pack();
        frame.setVisible(true);
    }
    
    public static void main(String[] args) {
        // A thread is a single sequence of logic within a program.  A single
        // program can have multiple threads executing concurrently.  The Swing
        // library is not thread safe, meaning that we can't work with it in
        // multiple concurrent threads.  Almost all Swing code must execute in a
        // special thread called the event dispatch thread.  The invokeLater
        // method allows us to run code on that thread, to make sure that no
        // errors can occur due to threading issues (even though for our simple
        // program such an error is very unlikely to happen).  The input makes
        // use of the Runnable interface, which we're creating an anonymous
        // class to implement.
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                buildGUI();
            }
        });
    }
}

2: Tic-Tac-Toe revisited

Implement yet another tic-tac-toe program, this time in a graphical way. If you want, you can start with the template below, which represents the game board using an array of buttons.

With this template, one way to handle the game logic is to add an action listener to each button that can change the button's label when it is clicked.

When the game is over, take some action to show that, like highlighting the winning 3 places.

import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import javax.swing.*;

public class TicTacToe extends JPanel {
    // Represent gameboard using a bunch of buttons
    JButton[][] buttons;
    
    public TicTacToe() {
        // Set layout and size to reasonable values
        setLayout(new GridLayout(3,3));
        setPreferredSize(new Dimension(500, 500));
        // Create a font object to use with the buttons
        Font font = new Font("Sans", Font.BOLD, 100);
        
        // Initialize buttons
        buttons = new JButton[3][3];
        for (int row = 0; row < buttons.length; row++)
            for (int col = 0; col < buttons[row].length; col++) {
                JButton b = new JButton("");
                b.setFont(font);
                buttons[row][col] = b;
                add(b);
                // Add action listeners here?
            }
    }
    
    // Set up main window and add our components.
    public static void buildGUI() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setContentPane(new TicTacToe());
        frame.pack();
        frame.setVisible(true);
    }
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                buildGUI();
            }
        });
    }
}

3: Statistic interface

The following code defines a simple interface that keeps track of a statistic about a stream of numbers (similar to the forecast example we saw earlier).

/**
 * Defines an interface that keeps track of a statistic
 * about a stream of numbers.
 */
public interface Statistic {
    /**
     * Provide a name describing the statistic.
     * @return the name of this statistic
     */
    String getName();
    /**
     * Provide the current statistic value.
     * @return the current statistic value.
     */
    double getValue();
    /**
     * Update the statistic value given a new observation.
     * @param x a new observation
     */
    void update(double x);
}

Create at least 2 classes that implement the Statistic interface, and test them using a program like the one shown below. A few possibilities (in roughly increasing order of complexity) include:

import java.util.ArrayList;
import java.util.Scanner;


public class StatTest {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        
        ArrayList<Statistic> stats = new ArrayList<>();
        // Add all the statistics you implemented; for example:
        // stats.add(new Mean());
        // stats.add(new Max());
        
        // Read input and update all statistics with each new value.
        while (input.hasNextDouble()) {
            double value = input.nextDouble();
            for (Statistic s : stats)
                s.update(value);
        }
        
        for (Statistic s : stats)
            System.out.println(s.getName() + ": " + s.getValue());
    }
}