Loyola College in Maryland

CS 202 - Computer Science II
Spring 2008


Loyola College > Department of Computer Science > Dr. James Glenn > CS 202 > Homework > Exam #2 Practice > Solutions

Problem 1: Suppose you have to implement a class called Image that can be used to create objects that represent two-dimensional grayscale images. Each object will have a 2-D array of ints that records how much gray is in each pixel of the image (0 means black; 255 means white). The skeleton of the class definition is below.

public class Image {
  // Constructs a new image with the given dimensions and initializes it
  // to all white.
  public Image(int w, int h)
    {
	width = w;
	height = h;

	grayMap = new int[h][w];

	for (int row = 0; row < h; row++)
	    for (int col = 0; col < w; col++)
		grayMap[row][col] = 255;
    }

   // Sets the pixel at the given coordinates to the given value.
  public void setPixel(int x, int y, int grayValue)
    {
	grayMap[y][x] = grayValue;
    }


  // Sets the pixels in the given row to the values in the given string.
  // The values in the string should be separated by spaces
  // (e.g. "100 125 ...").
  public void setRow(int y, String values)
    {
	StringTokenizer tok = new StringTokenizer(values);

	for (int col = 0; col < width; col++)
	    grayMap[y][col] = Integer.parseInt(tok.nextToken());
    }

  // Reads an image from a file.
  public void readImage(String filename) { ... }

  protected int[][] grayMap;
  protected int width, height;
}

Problem 2: Suppose you have a complete implementation of the Image class. Write the complete class definition for a new class called Icon that has the same functionality as Image except:

The completed Icon class should work with the following code.
Icon ico = new Icon("flag.pgm");
ico.setPixel(0, 0, 128); // set upper left to middle gray
public class Icon extends Image
{
  public Icon(String fname)
  {
    super(8, 8);
    readImage(fname);
  }
}

Problem 3: Rewrite the following classes so they are both subclasses of a class called Dwelling. Write the code for Dwelling as well. Try to avoid repeating code as much as possible. Write the classes so that any common methods can be called through a Dwelling reference.


public class Dwelling
{
    protected int size;
    protected String address;

    public Dwelling(int sz, String addr)
    {
	size = sz;
	address = addr;
    }

    public double estimateUtilities() {
        return size * size / Math.exp(size / 3.0);
    }

    public String getAddress() {
        return address;
    }

    public int getSize() {
        return size;
    }
}


public class House extends Dwelling {
    private int size, taxes;
    private String address;

    public House(int sz, String addr, int t) {
        super(sz, addr);
        size = sz;
        address = addr;
        taxes = t;
    }

    public int getTaxes() {
        return taxes;
    }

    public double estimateUtilities() {
        return size * size / Math.exp(size / 3.0);
    }

    public String getAddress() {
        return address;
    }
}

public class Apartment extends Dwelling {
    private int size;
    private String address;

    public Apartment(int sz, String addr) {
        super(sz, addr);
        size = sz;
        address = addr;
    }

    public double estimateUtilities() {
        return size * size / Math.exp(size / 3.0) super.estimateUtilities() - size getSize()/ 10;
    }

    public String getAddress() {
        return address;
    }
}

Problem 4: Write an applet that has two text fields and a button. One of the text fields is used for user input. The other is used to display the total of the numbers the user has entered. The total starts at zero and is updated each time the user clicks the button. The applet should display an error message if the user enters a non-numeric value.

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;

// Model/View/Controller would be a much nicer design for this problem.

public class AddingMachine extends JApplet implements ActionListener
{
    private JTextField inputField;
    private JTextField outputField;
    private JLabel statusLabel;
    private double total = 0.0;

    public void init()
    {
        // make a panel to hold the text fields

        JPanel textPanel = new JPanel(new GridLayout(2, 2));

        inputField = new JTextField();
        textPanel.add(new Label("Input:"));
        textPanel.add(inputField);

        outputField = new JTextField("0.0");
        outputField.setEditable(false);
        textPanel.add(new Label("Total:"));
        textPanel.add(outputField);

        // make a panel to hold the button and status

        JPanel bottomPanel = new JPanel(new BorderLayout());

        // put the button in another panel so it won't get stretched

        JPanel buttonPanel = new JPanel();
        JButton addButton = new JButton("Add");
        addButton.addActionListener(this);
        buttonPanel.add(addButton);

        statusLabel = new JLabel(" ");

        bottomPanel.add(buttonPanel, BorderLayout.CENTER);
        bottomPanel.add(statusLabel, BorderLayout.SOUTH);

        // put the panels in the applet

        getContentPane().setLayout(new BorderLayout());
        getContentPane().add(textPanel, BorderLayout.CENTER);
        getContentPane().add(bottomPanel, BorderLayout.SOUTH);
    }

    public void actionPerformed(ActionEvent e)
    {
        try
            {
                // read user input and add to total

                total += Double.parseDouble(inputField.getText());

                // display new total

                outputField.setText(String.valueOf(total));

                // clear any error message

                statusLabel.setText(" ");
            }
        catch (NumberFormatException ex)
            {
                statusLabel.setText("Please enter a number");
            }
    }
}

Problem 5: Create an application with the following interface.

The application should print the address and selected options using System.out.println when the "Create" button is clicked, it should clear the address input and checkboxes when "Clear" is clicked, and it should close when the "Quit" button is clicked.

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

public class X2P_Q1 extends JApplet
{
    private JTextField addrInput;
    private JCheckBox[] options;
    private static final String[] optionNames = {
        "Dishwasher", "Washer/Dryer", "Refrigerator", "Fireplace",
        "Garage", "Pool"
    };

    public void init()
    {
        Container c = getContentPane();
        
        addrInput = new JTextField();

        JPanel addrPanel = new JPanel(new BorderLayout());
        addrPanel.add(new JLabel("Address"), BorderLayout.WEST);
        addrPanel.add(addrInput, BorderLayout.CENTER);

        JPanel optionPanel = new JPanel(new GridLayout(2, 3));
        options = new JCheckBox[optionNames.length];
        for (int i = 0; i < optionNames.length; i++)
                {
                    options[i] = new JCheckBox(optionNames[i]);
                    optionPanel.add(options[i]);
                }

        JButton createButton = new JButton("Create");
        createButton.addActionListener(new CreateListener());

        JButton clearButton = new JButton("Clear");
        clearButton.addActionListener(new ClearListener());

        JButton quitButton = new JButton("Quit");
        quitButton.addActionListener(new QuitListener());

        JPanel buttonPanel = new JPanel(new GridLayout(1, 3, 5, 5));
        buttonPanel.add(createButton);
        buttonPanel.add(clearButton);
        buttonPanel.add(quitButton);

        c.setLayout(new BorderLayout());
        c.add(addrPanel, BorderLayout.NORTH);
        c.add(optionPanel, BorderLayout.CENTER);
        c.add(buttonPanel, BorderLayout.SOUTH);
    }

    private class CreateListener implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            System.out.println("Created " + addrInput.getText());
            for (int i = 0; i < options.length; i++)
                if (options[i].isSelected())
                    System.out.println(optionNames[i]);
        }
    }

    private class ClearListener implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            addrInput.setText("");
            for (int i = 0; i < options.length; i++)
                options[i].setSelected(false);
        }
    }

    private class QuitListener implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            System.exit(1);
        }
    }
}


Problem 6: Assume that the given class definitions are in the appropriate files. There are 16 statements below the comment in main, which is in the SubC class. Some of those 16 statements are illegal. Cross out the illegal statements and indicate whether they cause a compiler error or a runtime error. Give the output of the remaining statements (ignore the effects of any illegal statements). Some legal statements may produce no output.

abstract public class Super {
    abstract public void kick();
    public void pass() {System.out.println("Super.pass");}
    private void tackle() {System.out.println("Super.tackle");}
}

public class SubA extends Super {
    public void kick() {System.out.println("SubA.kick");}
    public void pass() {System.out.println("SubA.pass");}
    public void punt() {System.out.println("SubA.punt");}
}

public class SubB extends Super {
    public void kick() {System.out.println("SubB.kick");}
    public void punt() {System.out.println("SubB.punt");}
}

public class SubC extends SubA {
    public void kick() {System.out.println("SubC.kick"); super.kick();}
    public static void main(String[] args) {
        SubA one = new SubA();
        SubB two = new SubB();
        Super three = new SubC();

        // Some of these statements may cause errors at compile- or run- time.

        one.kick();
        one.pass();
        one.punt();
        one.tackle(); // tackle is private

        two.kick();
        two.pass();
        two.punt();
        two.tackle(); // still private

        three.kick();
        three.pass();
        three.punt(); // three declared as Super; punt not declared in Super
        three.tackle(); // funny how some things don't change

	SubA four = (SubA)two; // no ancestor/descendant relationship
	SubA five = (SubA)three;

        three = new Super(); // Super is abstract
        two = three; // can't do subclass (SubB) = superclass (Super)
        three = one;
        three.pass();
    }
}

All of the errors were compiler errors. The output is given below.

SubA.kick
SubA.pass
SubA.punt
SubB.kick
Super.pass
SubB.punt
SubC.kick
SubA.kick
SubA.pass
SubA.pass