Big Java / Java Concepts Lab 15 - Ryerson University



Big Java / Java Concepts Lab 14

Buttons

|1. |All problems in this lab are based on the HelloTester program: |

| | |

| |/** File HelloTester.java */ import javax.swing.JFrame; public class HelloTester {     public static void main(String |

| |args[])     {         JFrame frame = new HelloFrame();         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        |

| |frame.setTitle("HelloTester");         frame.setVisible(true);     } } /** File HelloFrame.java */ import |

| |javax.swing.JFrame; import javax.swing.JLabel; import java.awt.BorderLayout; import java.awt.Font; public class HelloFrame |

| |extends JFrame {     public HelloFrame()     {         message = "Hello, World!";         label = new JLabel(message);     |

| |    label.setFont(new Font("serif", Font.PLAIN, DEFAULT_SIZE));         add(label, BorderLayout.CENTER); |

| |        setSize(FRAME_WIDTH, FRAME_HEIGHT); |

| |    } |

| |    private String message; |

| |    private JLabel label; |

| |    private static int FRAME_WIDTH = 300; |

| |    private static int FRAME_HEIGHT = 300; |

| |    private static int DEFAULT_SIZE = 20; |

| |} |

| |In this problem, you need to add two buttons to the bottom of the frame, like this: |

| |[pic] |

| |Follow these steps: |

| |1. Make two instance variables of the class JButton: |

| |private JButton smallerButton; |

| |private JButton largerButton; |

| |2. Create a method called createSouthPanel and place the following two lines inside the method to initialize the variables |

| |with JButton objects: |

| |smallerButton = new JButton("Smaller"); |

| |largerButton = new JButton("Larger"); |

| | |

| | |

|3. Place the buttons into a panel: |

|JPanel southPanel = new JPanel(); southPanel.add(smallerButton);southPanel.add(largerButton); |

|4. Add the south panel to the frame: |

|add(southPanel, BorderLayout.SOUTH); |

|5. In the frame constructor, call the method createSouthPanel: |

|createSouthPanel(); |

|Make these changes in your program. Run the program to confirm that the buttons appear. |

|(a) What happens when you click the buttons? Why? |

|(b) Provide the source code for your createSouthPanel method. |

|2. |Next, you need to connect the buttons to actions. For each button, carry out these steps: |

| |1. Create a class that implements the ActionListener interface and override the actionPerformed method. |

| |2. Make an object of that class. |

| |3. Install that object as the action listener of the button. |

| |Perform these steps one at a time. |

| |When the "Larger" button is clicked, we want to increase the font size by 25 percent. When the "Smaller" button is |

| |clicked, we want to decrease it. To avoid integer rounding errors, keep a floating-point instance variable fontSizeFactor|

| |that is initialized with 1. Clicking on the buttons multiplies by 1.25 or 0.8 (because 0.8 = 1/ 1.25). |

| |private double fontSizeFactor = 1; |

| |Here is an appropriate action listener for the "Larger" button. |

| |class LargerFontListener implements ActionListener |

| |{ |

| |   public void actionPerformed(ActionEvent event) |

| |   { |

| |      fontSizeFactor = 1.25 * fontSizeFactor; |

| |      label.setFont(new Font("serif", Font.PLAIN, |

| |            (int) (DEFAULT_SIZE * fontSizeFactor))); |

| |      label.repaint(); |

| |   } |

| |} |

| |Place this class inside the createSouthPanel method, since actionPerformed needs to access the panel and fontSizeFactor |

| |variables. |

| |To connect it to the "Larger" button, you need to create an object of this class and set it as an action listener of the |

| |button. Place the following instructions into the frame constructor: |

| |ActionListener largerListener = new LargerFontListener(); |

| |largerButton.addActionListener(largerListener); |

| |Add the code, compile the program, and run it. Don't add the code for the "Smaller" button yet. |

| |Click on both buttons several times. What happens? |

|3. |Repeat the steps above for the "Smaller" button. Make an action listener class and add an instance of that class as an |

| |action listener of the smallerButton. Run your program. Both buttons should work. |

| |Provide the complete code for the createSouthPanel method. |

Layout Management

|4. |In the preceding program, the buttons were placed on the bottom of the frame, next to each other. Change your program so |

| |that they are placed on the right of the frame, one above the other other. |

| | |

| |What is the code for the HelloFrame class now? |

Menus

|5. |In this program, we will use a menu instead of a set of buttons to increase and decrease the font size. |

| |[pic] |

| |As with buttons, you need to solve two unrelated issues: |

| |How to place the menu items |

| |How to connect actions to the menu items. |

| |In Java, there is a three-level hierarchy for menus. |

| |  A menu bar is attached to a window. |

| |  The menu bar contains menus, rectangular panels with menu strings inside them. |

| |  Menus contain submenus and menu items. |

| |Only menu items have actions associated with them. |

| |Here are the instructions to build the menu for this program. |

| |JMenuBar menuBar = new JMenuBar(); |

| |setJMenuBar(menuBar); |

| | |

| |JMenu fontMenu = new JMenu("Font"); |

| |menuBar.add(fontMenu); |

| | |

| |JMenuItem largerItem = new JMenuItem("Larger"); |

| |fontMenu.add(largerItem); |

| | |

| |JMenuItem smallerItem = new JMenuItem("Smaller"); |

| |fontMenu.add(smallerItem); |

| |Start again with the HelloFrame class. |

| |Create a method called createMenu, and place these instructions inside this method. |

| |Run yor. (a) |

Run your program and check that the menu works. Don't forget to call createMenu from within the constructor. (a) What is the code for your HelloFrame class? (b) What happens when you select a menu item?

|6. |Next, you need to attach actions to the menu items. This process is identical to attaching actions to buttons. |

| |Attach the actions to the two menu items and run your program. Check that selecting the menu items respectively increases|

| |and decreases the font size. |

| |What is the complete source code for your frame class now? |

Combo Boxes

|7. |In this exercise, you will see how to offer a user a selection among multiple choices. You can place all choices into a |

| |combo box. |

| |[pic] |

| | |

| |To build such a combo box, you add items to it: |

| |final JComboBox comboBox = new JComboBox(); |

| |comboBox.addItem("Small"); |

| |comboBox.addItem("Medium"); |

| |comboBox.addItem("Large"); |

| |comboBox.addItem("Extra Large"); |

| |Then place the combo box in the south end of the content pane. |

| |add(comboBox, BorderLayout.SOUTH); |

| |Add a createSouthPanel method and paste the lines indicated above inside the method. Try it out. Don't forget to call the|

| |createSouthPanel method from within the constructor. Run the program and compare it against the figure. |

| |The program looks different. Why? |

|8. |The border layout grows all items to their maximum size. To avoid this, enclose the combo box inside a panel, even though|

| |it is a single item. |

| |JPanel southPanel = new JPanel(); |

| |southPanel.add(comboBox); |

| |add(southPanel, BorderLayout.SOUTH); |

| |Try it out. Add the combo box to the frame of the HelloTester program. Compile and run the program. Pull down the item |

| |list of the combo box to see the items. |

| |What happens if you select one of the items? |

|9. |To activate the combo box, you need to attach an action listener. The actionPerformed method needs to determine which |

| |item the user selected. |

| |class ComboListener implements ActionListener |

| |{ |

| |   public void actionPerformed(ActionEvent event) |

| |   { |

| |      String item = (String) comboBox.getSelectedItem(); |

| |      . . . |

| |   } |

| |} |

| |You need to cast the return value of the getSelectedItem method to a String because it is possible to put other objects, |

| |such as icons, into a combo box. |

| |Now you simply set the correct font size, depending on the item string. |

| |int messageSize = DEFAULT_SIZE; |

| |if (item.equals("Small")) { messageSize = SMALL_SIZE; } |

| |else if (item.equals("Medium")) { messageSize = MEDIUM_SIZE; } |

| |else if (item.equals("Large")) { messageSize = LARGE_SIZE; } |

| |else if (item.equals("Extra Large")) { messageSize = EXTRA_LARGE_SIZE; } |

| |label.setFont(new Font("serif", Font.PLAIN, messageSize)); |

| |label.repaint(); |

| |Define the size constants as follows: |

| |public static final int SMALL_SIZE = 12; |

| |public static final int MEDIUM_SIZE = 18; |

| |public static final int LARGE_SIZE = 24; |

| |public static final int EXTRA_LARGE_SIZE = 36; |

| |Add the combo action listener and try out your program. When you select an item from the combo box, the message should be|

| |displayed in the appropriate size. |

| |Provide the complete source code for your createSouthPanel method. |

Radio Buttons and Check Boxes

|10. |Radio buttons are another way to offer the user a selection among multiple alternatives. |

| |[pic] |

| |These buttons are called radio buttons because they work like the channel buttons on a radio. When you select a radio |

| |button, the previously selected radio button is turned off. |

| |However, radio buttons take up more screen "real estate" than combo boxes and therefore are best used when you need to |

| |offer users only a small selection. |

| |Here are the instructions to construct two radio buttons: |

| |helloButton = new JRadioButton("Hello"); |

| |goodbyeButton = new JRadioButton("Goodbye") ; |

| |To get the "radio button" effect, where all other buttons are turned off when one of the buttons is clicked, you need to |

| |place the buttons in a button group: |

| | |

| |ButtonGroup group = new ButtonGroup(); |

| |group.add(helloButton); |

| |group.add(goodbyeButton); |

| |Finally, you want to turn the first button on: |

| | |

| |helloButton.setSelected(true); |

| |The button group is a logical grouping of the buttons. You still need to physically lay out the buttons on the screen: |

| |JPanel southPanel = new JPanel(); |

| |southPanel.add(helloButton); |

| |southPanel.add(goodbyeButton); |

| |add(southPanel, BorderLayout.SOUTH); |

Add the two radio buttons to the frame of the HelloTester program. Add a createSouthPanel method, just like you did in the previous problems. (a) What is the code for your HelloFrame class? (b) Run the program. What happens when you click the radio buttons?

|11. |Now change the message text when the user clicks a radio button. To assemble the correct text, simply check which button |

| |is currently selected. |

| |class MessageListener implements ActionListener |

| |{ |

| |   public void actionPerformed(ActionEvent event) |

| |   { |

| |      String message = ""; |

| |      if (helloButton.isSelected()) message = "Hello"; |

| |      else if (goodbyeButton.isSelected()) message = "Goodbye"; |

| |      message = message + ", World!"; |

| |      label.setText(message); |

| |   } |

| |} |

| |Note that you can attach the same action object to both buttons. |

| |Add the action listener and attach it to the radio buttons. Run the program. Observe how clicking the buttons changes the|

| |message text. |

| |What is the complete source code for your HelloFrame class? |

|12. |Check boxes are used to allow users to select a single logical alternative, typically of the form "do X" or "do nothing".|

| |Here, a check box is used to allow the user to specify whether the word "cruel" should be added to the message text: |

| |[pic] |

| |Follow these steps to add the check box to the program. |

| |1. Construct the check box. |

| |cruelCheckBox = new JCheckBox("Cruel"); |

| |2. Attach the same action listener to the check box and the radio buttons. |

| |cruelCheckBox.addActionListener(listener); |

| |3. Add the check box to the south panel. |

| |southPanel.add(cruelCheckBox); |

| |4. In the actionPerformed method of the MessageAction class, check |

| |if (cruelCheckBox.isSelected()) . . . |

| |Run the program. Observe how clicking the check box changes the message text. |

| |What is the complete source code for your HelloFrame class now? |

Big Java / Java Concepts Lab 15

Throwing Exceptions

|1. |The BankAccount class has three methods with preconditions: |

| |1. the constructor (initial balance must not be negative) |

| |2. the withdraw method (withdrawal amount must not be greater than the balance) |

| |3. the deposit method (deposit amount must not be negative) |

| |Modify the code for the BankAccount class so that each of the three methods throws an IllegalArgumentException if the |

| |precondition is violated. |

| |What is the code for your modified BankAccount class? |

|2. |Write a tester program that asks the user for: |

| |the initial balance |

| |an amount to deposit |

| |an amount to withdraw |

| |Have the program construct a BankAccount object and make the deposit and withdrawal. |

| |What is your tester program? |

|3. |What happens when you make the following errors? |

| |Construct an account with a negative balance |

| |Withdraw more money than the account balance |

| |Enter an illegal input (such as "ten" instead of "10") |

Custom Exceptions

|4. |It is often a good idea to define your own exception class rather than rely on a predefined class. |

| | |

| |Define a class BankAccountException that can be used by the BankAccount class. |

| | |

| |Your exception should be an unchecked exception. |

| | |

| |What is the code for your exception class? |

|5. |Why does it make sense to define the BankAccountException class as an unchecked exception class? |

|6. |Now modify the BankAccount class to throw BankAccountException objects instead of IllegalArgumentException objects. |

| | |

| |What is the code for your modified class? |

|7. |If the BankAccountException class had been a checked exception, then what changes would you need to make |

| | |

| |in the definition of the exception class? |

| |in the BankAccount methods? |

Propagating Checked Exceptions

|8. |The DateFormat class of the standard Java library has a method |

| |Date parse(String source) |

| |that converts a string such as |

| |"2/27/05 8:00 AM" |

| |into an object of type Date: |

| |DateFormat formatter = DateFormat.getDateTimeInstance( |

| |DateFormat.SHORT, DateFormat.SHORT); |

| |String source = . . .; |

| |Date d = formatter.parse(source); |

| |If the source string is not in the correct format, then the parse method throws a ParseException, which is a checked |

| |exception. |

| |In this exercise, you will implement a class Appointment that stores the date and description of an appointment: |

| |public class Appointment |

| |{ |

| |   . . . |

| |   public String toString() |

| |   { |

| |      return "Appointment[date=" |

| |            + formatter.format(date) |

| |            + "description=" + description + "; " |

| |            + "]"; |

| |   } |

| | |

| |   private Date date; |

| |   private String description; |

| |   private static DateFormat formatter = DateFormat.getDateTimeInstance( |

| |         DateFormat.SHORT, DateFormat.SHORT); |

| |} |

| |Supply a constructor |

| |Appointment(String aDate, String aDescription) |

| |that constructs an Appointment object from two strings. If the first string is not in a legal format, your constructor |

| |should throw a ParseException. |

|9. |Now you will create a class AppointmentBook that keeps an array list of appointments. Part of the class has been provided|

| |for you: |

| | |

| |import java.util.ArrayList; |

| |import java.text.ParseException; |

| | |

| |public class AppointmentBook |

| |{ |

| |   public AppointmentBook() |

| |   { |

| |      book = new ArrayList(); |

| |   } |

| |   . . . |

| | |

| | |

| |   public void addAll(ArrayList list) |

| |   { |

| |      book.addAll(list); |

| |   } |

| |   public int getNumAppointments() |

| |   { |

| |      return book.size(); |

| |   } |

| |   public Appointment getAppointment(int i) |

| |   { |

| |      return book.get(i); |

| |   } |

| | |

| | |

| |   public String toString() |

| |   { |

| |      String out = ""; |

| |      for (Appointment a : book) |

| |      { |

| |         out = out + a.toString() + "\n"; |

| |      } |

| |      return out; |

| |   } |

| |   private ArrayList book; |

| |} |

| |Add a method add, that adds a new appointment to the book. The method should not catch the ParseException, but propagate |

| |it to the calling method. |

| |public void add(String aDate, String aDescription) |

Catching Exceptions

|10. |Write a program AppointmentBookTester whose main method asks the user to enter a series of appointments. Add the |

| |appointments into an appointment book object. If a parse error occurs in the add method, have the program instruct the |

| |user to reenter the appointment. |

| |Here is an outline of the main method, which does not yet catch any exceptions. |

| |boolean done = false; |

| |while (!done) |

| |{ |

| |   System.out.println("Next date (or -1 when done):"); |

| |   String input1 = in.nextLine(); |

| |   if (input1.equals("-1")) |

| |   done = true; |

| |   else |

| |   { |

| |      System.out.println("Description:"); |

| |      String input2 = in.nextLine(); |

| |      book.add(input1, input2); |

| |   } |

| |} |

| |System.out.println(book); |

| |Add the appropriate try/catch block and test your program. |

| |What is the complete code for your AppointmentBookTester class? |

|11. |The preceding program is tedious to use because the user must type all appointment data on the command-line. Improve the |

| |method so that the data can be stored in a file. |

| |Put the data in a text file, say, appts.txt, and then provide this file name when the programs asks you to. |

| |Create an AppointmentBookReader class that will read appointments stored in a file. Use the following class: |

| | |

| |import java.util.Scanner; |

| |import java.text.ParseException; |

| |import java.io.FileReader; |

| |import java.io.IOException; |

| | |

| |public class AppointmentBookReader |

| |{ |

| |   public AppointmentBookReader() |

| |   { |

| |      book = new AppointmentBook(); |

| |   } |

| | |

| |   public AppointmentBook read(String filename) |

| |         throws IOException, ParseException |

| |   { |

| |      FileReader reader = new FileReader(filename); |

| |      Scanner in = new Scanner(reader); |

| |      while (in.hasNextLine()) |

| |      { |

| |         String input1 = in.nextLine(); |

| |         String input2 = in.nextLine(); |

| |         book.add(input1, input2); |

| |      } |

| |      reader.close(); |

| |      return book; |

| |   } |

| |   private AppointmentBook book; |

| |} |

| |To read from an appointment book, use the following code: |

| | |

| |AppointmentBookReader bookReader = new AppointmentBookReader(); |

| |AppointmentBook book = bookReader.read(filename); |

| |System.out.println(book); |

| |Now change the AppointmentBookTester program so that it uses an AppointmentBookReader. |

| |If there is any exception, describe the nature of the exception in English. Print the contents of the appointment book at|

| |the end of your program, whether or not there is any exception. |

| |What is the complete code for your AppointmentBookTester class? |

|12. |Give an example of an input file that causes the AppointmentBookReader to throw a ParseException. |

|13. |Give an example of an input file that causes the AppointmentBookReader to throw an NoSuchElementException. |

The finally Clause

|14. |When there is an input error and the AppointmentBookReader class exits with an exception, it should close its FileReader |

| |object by calling reader.close(). |

| |Modify the read method of the AppointmentBookReader class to close reader in a finally clause. |

| |What is the code for your modified read method? |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

Big Java / Java Concepts Lab 16

Reading and Writing Text Files

|1. |Write a program to store multiple memos in a file. Allow a user to enter a topic and the text of a memo (the text of the |

| |memo is stored as a single line and thus cannot contain a return character). Store the topic, the date stamp of the memo,|

| |and the memo message. |

| |Use a text editor to view the contents of the "memo.dat" file and to check that the information is stored correctly. |

| |Creating a java.util.Date object with no arguments will initialize the Date object to the current time and date. A date |

| |stamp is obtained by calling the Date.toString() method. |

| |Part of the code of the program has been provided for you: |

| |import . . . public class MemoPadCreator {    public static void main(String args[])    {       Date now;       Scanner |

| |console = new Scanner(System.in);       System.out.print("Output file: ");       String filename = console.nextLine();   |

| |   try       {          PrintWriter out = . . .;          boolean done = false;          while (!done)          {       |

| |      System.out.println("Memo topic (enter -1 to end):");             String topic = console.nextLine();             if |

| |(topic.equals("-1"))                done = true;             else             {                System.out.println("Memo |

| |text:");                String message = console.nextLine();                /** Create the new date object and obtain a |

| |dateStamp */                out.println(topic + "\n" + dateStamp + "\n" + message);             }          }          /**|

| |Close the output file*/       }       catch (. . .)       {          . . .       }    } }What is the code for your |

| |program? |

|2. |Modify your memo writing program to read multiple memos stored in a text file. Memos are stored in three lines. The first|

| |line is the memo topic, the second line is the date stamp, and the third line is the memo message. Display the memos one |

| |at a time, and allow the user to choose to view the next memo (if there is one). |

| |Part of the program code has been provided for you: |

| | |

| |. . . |

| | |

| |public class MemoPadReader |

| |{ |

| |   public static void main(String[] args) |

| |   { |

| |      Scanner console = new Scanner(System.in); |

| |      System.out.print("Input file: "); |

| |      String inputFileName = console.nextLine(); |

| |      try |

| |      { |

| |         FileReader reader = . . .; |

| |         Scanner in = new Scanner(reader); |

| | |

| |         boolean done = false; |

| |         while (in.hasNextLine() && !done) |

| |         { |

| |            String topic = . . .; |

| |            String dateStamp = . . .; |

| |            String message = . . .; |

| |            System.out.println(topic + "\n" + dateStamp + "\n" + message); |

| |            if (. . .) // You should only ask to display the next memo if there are more memos in the file |

| |            { |

| |               System.out.println("Do you want to read the next memo (y/n)?"); |

| |               String ans = console.nextLine(); |

| |               if (ans.equalsIgnoreCase("n")) |

| |               done = true; |

| |            } |

| |         } |

| | |

| |         reader.close(); |

| |      } |

| |      catch (. . .) |

| |      { |

| |         . . . |

| |      } |

| |   } |

| |} |

| | |

| |What is the code for your program? |

|3. |Modify your simple memo reader program. Use the JFileChooser to allow the user to choose the file from which the memos |

| |will be read. |

| |You can use the showOpenDialog method to enable the user to select a file to "open". This method returns either |

| |JFileChooser.APPROVE_OPTION, if the user has chosen a file, or JFileChooser.CANCEL_OPTION, if the user canceled the |

| |selection. |

| |If a file was chosen, then you call the getSelectedFile method to obtain a File object that describes the file. Here is a|

| |complete example: |

| |JFileChooser chooser = new JFileChooser(); |

| |FileReader in = null; |

| |if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) |

| |{ |

| |   File selectedFile = chooser.getSelectedFile(); |

| |   reader = new FileReader(selectedFile); |

| |   . . . |

| |} |

| |What is the code for your program? |

File Encryption

|4. |Write a program that encrypts (or decrypts) a file using an XOR cipher. An XOR cipher encrypts a byte by performing an |

| |XOR bitwise operation with the byte to be encrypted and a key. In Java, you can perform bitwise XOR using the ^ operator.|

| |First, write a class XorEncryptor that encrypts or decrypts a file using an XOR cipher. Part of the code of the class has|

| |been provided for you: |

| |import . . . |

| | |

| |/** |

| |   An encryptor encrypts files using a "XOR" cipher. |

| |*/ |

| |public class XorEncryptor |

| |{ |

| |   /** |

| |      Constructs an encryptor. |

| |      @param aKey the encryption key |

| |   */ |

| |   public XorEncryptor(byte aKey) |

| |   { |

| |      key = aKey; |

| |   } |

| | |

| |   /** |

| |      Encrypts the contents of a file. |

| |      @param inFile the input file |

| |      @param outFile the output file |

| |   */ |

| |   public void encryptFile(String inFile, String outFile) |

| |      throws . . . |

| |   { |

| |      InputStream in = null; |

| |      OutputStream out = null; |

| | |

| |      try |

| |      { |

| |         in = . . .; |

| |         out = . . .; |

| |         encryptStream(in, out); |

| |      } |

| |      finally |

| |      { |

| |         /** Close the files */ |

| |      } |

| |   } |

| | |

| |   /** |

| |      Encrypts the contents of a stream. |

| |      @param in the input stream |

| |      @param out the output stream |

| |   */ |

| |   public void encryptStream(InputStream in, OutputStream out) |

| |      throws . . . |

| |   { |

| |      boolean done = false; |

| |      while (!done) |

| |      { |

| |         int next = . . .; |

| |         if (next == -1) done = true; |

| |         else |

| |

|         { |

|            byte b = (byte) next; |

|            byte c = encrypt(b); |

|            out.write(c); |

|         } |

|      } |

|   } |

| |

|   /** |

|      Encrypts a byte. |

|      @param b the byte to encrypt |

|      @return the encrypted byte |

|   */ |

|   public byte encrypt(byte b) |

|   { |

|      return . . .; |

|   } |

| |

|   private byte key; |

|} |

| |

|What is the complete code for the XorEncryptor class? |

|5. |Write a tester program that asks the user for the name of a file to encrypt (or decrypt) and the name of the output file,|

| |and encrypts (or decrypts) the file. Note that both operations are performed in exactly the same way. Your program should|

| |also ask the user for the encryption key to use. |

| |What is the complete code for your tester class? |

|6. |Test your program. Create a file with the following content and encrypt it. Use "a" as the encryption key. |

| |This is a test for the XOR encryptor. |

| |Open the encrypted file with a text editor. What are the contents of the encrypted file? |

|7. |Decrypt the file you just encrypted using your program. Don't forget to use "a" as the decryption key. What is the |

| |output? |

Command Line Arguments

|8. |Modify your testing program so that the input file, output file, and encryption key are supplied on the command line. |

| |What is the code for your modified tester class? |

|9. |What command do you use to run your program to encrypt the file message.txt into the file message.enc, using a as the |

| |encryption key? What command do you use to decrypt the message.enc file? |

Random Access Files

|10. |Create a program that reads and stores memos in a RandomAccessFile. To be able to read and write memos in a random access|

| |file, the topic, date stamp and message should each have a fixed size. |

| |First, complete the code for the class MemoPad. You will write the tester program in the next problem. |

| | |

| |public class MemoPad |

| |{ |

| |   public MemoPad() |

| |   { |

| |      file = null; |

| |   } |

| |   public void open(String filename) throws IOException |

| |   { |

| |      . . . |

| |   } |

| |   /** |

| |      Gets the number of memos in the file. |

| |      @return the number of memos |

| |   */ |

| |   public int size() throws IOException |

| |   { |

| |      . . . |

| |   } |

| |   public void close() throws IOException |

| |   { |

| |      if (file != null) file.close(); |

| |      file = null; |

| |   } |

| | |

| |   /** |

| |      Reads a memo record. The values of the last record read can be obtained |

| |      with the getTopic, getDateStamp and getMessage methods. |

| |      @param n the index of the memo in the file |

| |   */ |

| |   public void read(int n) throws IOException |

| |   { |

| |      file.seek(. . .); |

| |      byte[] topic = new byte[MAX_CHARS_TOPIC]; |

| |      byte[] date = new byte[MAX_CHARS_DATE]; |

| |      byte[] message = new byte[MAX_CHARS_MSG]; |

| |      /* Read the topic, date and message from the file (use the method "read(byte[])". |

| |         Then, convert the byte arrays to strings and store them in the variables currentTopic, |

| |         currentDateStamp and currentMessage |

| |      */ |

| |   } |

| |   public String getTopic() |

| |   { |

| |      return currentTopic; // returns the topic of the last memo read |

| |   } |

| | |

| |   public String getDateStamp() |

| |   { |

| |      return currentDateStamp; |

| |     |

public String getDateStamp()

   {

      return currentDateStamp;

   }

   public String getMessage()

   {

      return currentMessage;

   }

   public void write(int n, String topic, String dateStamp, String message) throws IOException

   {

      file.seek(. . .);

      file.writeBytes(. . .); // "topic" should have a fixed size

      file.writeBytes(. . .); // "dateStamp" should have a fixed size

      file.writeBytes(. . .); // "message" should have a fixed size

   }

   /**

      Adds white spaces to a string or cuts the string, so the string has a length of exactly "size".

      @param str the input string

      @param size the desired size

      @return the new string

   */

   private String padOrTrim(String str, int size)

   {

      if (str.length() < size)

      {

         String pad = "";

         for (int i = str.length(); i < size; i++)

         pad = pad + " ";

         return str + pad;

      }

      else

         return str.substring(0, size);

   }

   private RandomAccessFile file;

   private String currentTopic;

   private String currentDateStamp;

   private String currentMessage;

   public static final int MAX_CHARS_TOPIC = 25;

   public static final int MAX_CHARS_DATE = 40;

   public static final int MAX_CHARS_MSG = 250;

   public static final int RECORD_SIZE = MAX_CHARS_TOPIC + MAX_CHARS_DATE

      + MAX_CHARS_MSG;

}

What is the complete code for this class?

|11. |Write a tester program that allows the user to add or display a memo. Memos should be added to the end of the file. If |

| |the user wants to display a memo, a list of the existing topics should be provided, so that the user can select which one|

| |he/she wants to see. Complete the following program: |

| | |

| |public class MemoPadTester |

| |{ |

| |   public static void main(String args[]) |

| |   { |

| |      Scanner console = new Scanner(System.in); |

| |      System.out.println("Input file:"); |

| |      String filename = console.nextLine(); |

| |      try |

| |      { |

| |         MemoPad memoPad = new MemoPad(); |

| |         memoPad.open(. . .); |

| |         boolean done = false; |

| |         while (!done) |

| |         { |

| |            System.out.print("Enter A to add a memo, D to display an existing memo or Q to quit: "); |

| |            String choice = console.nextLine(); |

| |            if (choice.equalsIgnoreCase("A")) |

| |            { |

| |               System.out.println("Topic (max 25 characters):"); |

| |               String topic = console.nextLine(); |

| |               String dateStamp = (new Date()).toString(); |

| |               System.out.println("Message (max 250 characters):"); |

| |               String message = console.nextLine(); |

| |               memoPad.write(. . ., topic, dateStamp, message); |

| |            } |

| |            else if (choice.equalsIgnoreCase("D")) |

| |            { |

| |               if (memoPad.size() > 0) |

| |               { |

| |                  // Display the list of topics |

| |                  for (int i = 0; i < . . .; i++) |

| |                  { |

| |                     memoPad.read(. . .); |

| |                     System.out.println(i + " " + . . .); |

| |                  } |

| | |

| |                  System.out.println("Enter the number of the memo to display:"); |

| |                  int n = Integer.parseInt(console.nextLine()); |

| |                  memoPad.read(. . .); |

| |                  System.out.println(. . .); // topic |

| |                  System.out.println(. . .); // date stamp |

| |                  System.out.println(. . .); // message |

| |               } |

| |               else |

| |               { |

| |                  System.out.println("There are no memos in the file."); |

| |               } |

| |            } |

| |            else if (choice.equalsIgnoreCase("Q")) |

| |               done = true; |

| |          |

}

         memoPad.close();

      }

      catch (IOException exception)

      {

         System.out.println("Input/output error: " + exception);

      }

   }

}

What is the complete code for this class?

Object Streams

|12. |Write a program that writes memos to a file as object streams.The Memo class should have fields to store a topic, a date |

| |stamp and the memo message. Allow a user to enter multiple memos, supplying the topic and message. Your program should |

| |provide the date stamp using the java.util.Date object. (Creating a Date object with no arguments initializes the object |

| |to the current time and date). |

| |Let the user choose the file name to which the memos are saved. |

| |What is the code for your Memo class? Remember to implement the Serializable interface! |

|13. |Provide a tester program for your Memo class. Allow a user to enter multiple memos, supplying the topic and message. Your|

| |program should provide the date stamp using the java.util.Date object (creating a Date object with no arguments |

| |initializes the object to the current time and date). Let the user choose the file name to which the memos are saved. |

| | |

| |After saving the file, your tester program should open the file and print out all memos. |

| |You can modify the program you created in problem 1. |

| |What is the code for your tester program? |

Big Java / Java Concepts Lab 17

Discovering Classes

|1. |You have been given an assignment to write a program to schedule classrooms in your college's building. Classrooms can be|

| |reserved for classes, seminars, guest speakers, and for meetings for clubs (such as the Java Users Group). Clubs can meet|

| |only after 5 p.m. and only if the room is not needed by any other group. Each group needing a classroom is given a |

| |priority. Classes in your college have the highest priority, with clubs having the lowest priority. Some classes in your |

| |college have higher priority over others, especially if the instructor has tenure. Classrooms are characterized by size, |

| |amenities (overhead projectors, etc.) and comfortable seats. Groups can specifically request a room by room number or |

| |simply give a description of what they need. Groups also may request specific time slots or give a range of acceptable |

| |time slots. Rooms are not available after 10 p.m. and before 5 a.m. |

| |Make a list of classes that you may need for your program. |

|2. |From your list of potential classes in your classroom-scheduling program, pick three potential classes and identify their|

| |main responsibilities. |

|3. |A CRC card describes a class, its responsibilities, and its collaborating classes. You already identified the classes and|

| |responsibilities in the classroom-scheduling program. Now you will identify the collaborating classes. |

| | |

| |From your list of potential classes in your classroom-scheduling program, pick three potential classes and identify their|

| |collaborators. |

Relationships Between Classes

|4. |Using the list of classes for your classroom-scheduling program, identify any objects that may use inheritance. List the |

| |superclasses (if any) followed by their subclasses. If you see no need for inheritance, explain. |

|5. |Inheritance can be described as an "is-a" relationship between classes. Aggregation can be described as a "has-a" |

| |relationship. Identify any aggregation relations in the classroom scheduling problem. |

|6. |Identify the relationships between classes in the following code: |

| |class GroceryBag extends BasicContainer |

| |{ |

| |    private Fruit[] fruits; |

| |    private Vegetable[] veggies; |

| | |

| |. . . |

| | |

| |    public void addItem(Food item) |

| |    { |

| |       . . . |

| |    } |

| | |

| |    public Money computeTotal() |

| |    { |

| |       . . . |

| |    } |

| | |

| |    . . . |

| |} |

| |Inheritance |

| |From which classes does GroceryBag inherit? |

| |Aggregation |

| |Identify any aggregation relationships (has-a relationship). |

| |Dependency |

| |On which classes does GroceryBag depend (uses relationship)? |

Case Study

|7. |In this case study, you will develop a program to be used for ordering from an online pizza restaurant. Allow the user |

| |the following choices: pizza size (small, medium, or large), pizza crust type (thin or thick), pizza toppings, as well as|

| |small, medium, and large drinks. The user may select specific toppings. A user can order multiple pizzas and drinks. The |

| |order should include the customer's delivery address. After taking the order, print an order slip that shows the order |

| |information and total price. |

| |Each topping has a price (for example, onions $1 and pepperoni $2). The price of a pizza is the sum of the base price |

| |($10 for a small pizza, $13 for a medium, and $16 for a large pizza), plus the sum of the topping prices. The crust type |

| |doesn't affect the price. |

| |The price of a drink is the base price of the drink ($1 for soda, $2 for beer) multiplied by a size factor (0.8 for |

| |small, 1.0 for medium, 1.2 for large drinks). |

| |The delivery charge is $3. It is waived for pickup orders. |

| |What classes can you identify using the "nouns from the requirements specification" technique? |

|8. |Not all of the classes are immediately visible in the requirements specification. In our example, a pizza and a drink |

| |have common properties: |

| |the price |

| |the description that is printed on the order slip |

| |In fact, if the restaurant were to start serving other items (such as bread sticks or sandwiches), those items also would|

| |have a price and a description. |

| | |

| |Define a suitable class that captures this commonality, and indicate how the classes Pizza and Drink are related to this |

| |class. |

|9. |What are the responsibilities and collaborators of the Order class?  |

|10. |You probably decided you need a class Topping. What is the code for your Topping class? If you think you do not need a |

| |class Topping, explain why. |

|11. |A very important class in your program is probably going to be called Pizza. What is the code for your Pizza class. If |

| |you think you need superclasses and/or subclasses of Pizza, supply the code for these classes too. |

|12. |Supply the code for your Drink class. |

|13. |An order should contain a list of items (pizzas or drinks), so that the total price can be calculated and the order can |

| |be formatted to be printed. Supply the code for your Order class here. |

|14. |Supply the code of any other classes you need to complete your program. |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

| | |

Big Java / Java Concepts Lab 18

Recursion

|1. |The factorial of a positive integer is the product of all nonnegative integers less than or equal to that number. (The symbol for |

| |factorial is "!" - the exclamation mark.) |

| |The formula for factorials for all nonnegative integers is: |

| |n! = n * (n-1)! for n > 0; |

| |Zero factorial is a special case and 0! = 1 |

| |From this definition, 5! is 120:1! = 1 * 0! = 12! = 2 * 1! = 23! = 3 * 2! = 64! = 4 * 3! = 245! = 5 * 4! = 120 |

| |Write a recursive factorial method |

| |long factorial(int n) |

|2. |You can also compute the factorial values iteratively, without using recursion. Supply a non-recursive factorial method. |

|3. |Write a tester class that tests both solutions. |

|4. |A formula for finding the greatest common divisor (GCD) of two numbers was formulated by the mathematician Euclid around |

| |300 BCE. The GCD of two numbers is the largest number that will divide into both numbers without any remainder. For |

| |example, the GCD of 12 and 16 is 4, the GCD of 18 and 12 is 6. |

| |The basic algorithm is as follows: |

| |Let a be the larger, b the smaller number. (We will assume that both values are positive.) |

| |Let c be the remainder that is obtained after dividing a through b. |

| |If c is zero, then the GCD is b. |

| |Otherwise, the GCD of a and b is the same as the GCD of b and c. |

| |Recall that in Java, the % operator computes the remainder. For example, to compute the GCD of 12 and 16, you compute |

| |16 % 12 = 4 |

| |Now you need to compute the GCD of 12 and 4. |

| |12 % 4 = 0 |

| |Therefore, the GCD is 4. |

| |Write a recursive method that finds the GCD of two numbers using Euclid's algorithm. (You may assume--or, better, |

| |assert--that both inputs are positive.) |

|5. |Write a tester program for your GCD class. |

Recursive Helper Methods

|6. |Write a program to draw the logarithmic spiral recursively. |

| |The logarithmic spiral or Fibonacci spiral is a shape often found in nature. The nautilus shell is the classic example of the |

| |logarithmic spiral. Seed patterns in sunflowers and pinecones also demonstrate the spiral. |

| |[pic] |

| |To construct a logarithmic spiral, begin with a "golden" rectangle. A golden rectangle is a rectangle with sides of length A |

| |and φA, where φ (Phi) is the golden mean or the value ( 1 + sqrt(5) ) / 2 or 1.61803 . . . A square with length equal to the |

| |smallest side of the rectangle is drawn inside the rectangle. A quarter arc (arcAngle = 90 degrees) is drawn within this |

| |square. The remaining rectangle is also a golden rectangle. This remaining rectangle is divided into a square and another |

| |smaller golden rectangle. A quarter arc connected to the previous arc is drawn inside the square, and the remaining rectangle |

| |is once again subdivided with an arc drawn in it. |

| |Create a panel in which to draw the spiral: |

| |public class LogSpiralPanel extends JPanel  |

| |Given the dimensions of the panel, draw the largest golden rectangle that will fit within the panel. Part of the code of the |

| |class has been provided for you: |

| |import java.awt.Graphics2D; |

| |import java.awt.Graphics; |

| |import java.awt.Rectangle; |

| |import java.awt.geom.Arc2D; |

| |import javax.swing.JPanel; |

| | |

| |public class LogSpiralPanel extends JPanel |

| |{ |

| |   public void paintComponent(Graphics g) |

| |   { |

Graphics2D g2 = (Graphics2D) g;

       /*

         Your code goes here.

         1. create the goldenRectangle (you can use getHeight() to obtain the side size

         2. draw the golden rectangle

         3. call the recursive helper method "recursiveDraw" which will draw the spiral

       */

   }

   /**

      Method that recursively draws a logarithmic spiral.

      @param x The upper left corner x-coordinate of the golden rectangle

      @param y The upper left corner y-coordinate of the golden rectangle

      @param side the smallest side size of the golden rectangle

      @param angle the angle (0, 90, 180 or 270) where the top of the golden rectangle is located.

      For the outermost golden rectangle, the angle is 90.

*/

    private void recursiveDraw(Graphics2D g2, double x, double y, double side, int angle)

    {

       // we'll do this in the next section. . .

    }

    

    private static final double GOLDEN_MEAN = (1 + Math.sqrt(5)) / 2;

}

What is the code of your completed paintComponent method?

|7. |Now you will complete the code of the recursive helper method recursiveDraw. To recursively draw the logarithmic spiral, |

| |you first need to draw the square. The square's upper-left corner is at position (x, y), and its side size is side. Then |

| |you need to draw the arc. You can use the method drawArc that has been provided for you. Then you need to recursively |

| |call recursiveDraw to continue drawing the spiral recursively. Before making the recursive call you need to calculate the|

| |new side size, the new x-coordinate, the new y-coordinate and the new angle. Two methods calculateNewX and calculateNewY |

| |have been provided for you. You can use these methods to calculate the new x and y coordinate, but you need to calculate |

| |the new side size and the new angle yourself. Remember that the new side size is the difference between the sizes of the |

| |two sides of the current rectangle. The new angle is given by rotating the current angle 90 degrees in clock-wise |

| |direction. |

| | |

| |public class LogSpiralPanel extends JPanel |

| |{ |

| |    public void paintComponent(Graphics g) |

| |    { |

| |    . . . |

| |    } |

| | |

| |    /** |

| |        Method that recursively draws a logarithmic spiral. |

| |        @param x The upper left corner x-coordinate of the golden rectangle |

| |        @param y The upper left corder y-coordinate of the golden rectangle |

| |        @param side the smallest side size of the golden rectangle |

| |        @param angle The angle (0, 90, 180 or 270) where the top of the         current golden rectangle is located. |

| |        For the outermost golden rectangle, the angle is 90. |

| |     */ |

| |    private void recursiveDraw(Graphics2D g2, double x, double y, double side, int angle) |

| |    { |

| |        /* Recursion ending condition: when the side is very small */ |

| |        . . . |

| | |

| |        /* Draw the current square and arc */ |

| |        . . . |

| | |

| |        /* Continue drawing the spiral recursively: calculate the new side size, calculate the new |

| |            (x, y) coordinates and the new angle. Then, call "recursiveDraw" again. */ |

| |        . . . |

| |    } |

| |    /** |

| |        Draws the arc of the current iteration. |

| |        @param x The upper-left corner x-coordinate of the square |

| |        @param y The upper-left corner y-coordinate of the square |

| |        @param side The size of the side of the square (or the arc's radius) |

| |        @param angle The angle (0, 90, 180 or 270) where the top of the current golden rectangle is located. |

| |        For the outermost golden rectangle, the angle is 90. |

*/

    private void drawArc(Graphics2D g2, double x, double y, double side, int angle)

    {

        double auxX = x;

        double auxY = y;

        if (angle == 0 || angle == 270)

            auxX = x - side;

        if (angle == 270 || angle == 180)

            auxY = y - side;

        Rectangle2D.Double boundingRectangle =

new Rectangle2D.Double(auxX, auxY, side * 2, side * 2);

        Arc2D.Double arc = new Arc2D.Double(boundingRectangle, angle, 90, Arc2D.OPEN);

        g2.draw(arc);

    }

    private double calculateNewX(double x, double angle, double side, double newSide)

    {

        if (angle == 0)

            x = x + side - newSide;

        else if (angle == 90)

            x = x + side;

        else if (angle == 270)

            x = x - newSide;

        return x;

    }

    private double calculateNewY(double y, double angle, double side, double newSide)

    {

        if (angle == 0)

            y = y + side;

        else if (angle == 180)

            y = y - newSide;

        else if (angle == 270)

            y = y + side - newSide;

        return y;

    }

    private static final double GOLDEN_MEAN = (1 + Math.sqrt(5)) / 2;

}

What is the code of your recursiveDraw method?

|8. |Create a LogSpiralFrame class that will contain the LogSpiralPanel. What is the code of your class? |

|9. |What is the code of your viewer class? |

The Efficiency of Recursion

|10. |The golden mean, often referred to as the golden ratio, divine proportion, or the golden number is represented by the |

| |Greek letter phi (φ). The value of the golden mean is (1 + sqrt(5)) / 2 or 1.61803 . . . The golden mean is found in |

| |nature and art and tends to yield the most "aesthetically pleasing" arrangements of objects. |

| |Fibonacci numbers are directly related to the golden mean. The definition of Fibonacci numbers is |

| |fib(1) = 1 |

| |fib(2) = 1 |

| |fib(n) = (fib(n-1) + fib(n-2)) |

| |After the first two numbers, each of which has the value of 1, the next number in the Fibonacci sequence is the sum of |

| |the two preceding numbers. |

| |Computing ratios of Fibonacci numbers can approximate the value of the golden mean. The value of. |

| |g(n) = fib(n) / fib(n-1) |

| |approximates the golden mean as n goes to infinity. |

| | |

| |These values can be computed recursively as well. Note that |

| |g(n) = (fib(n - 1) + fib(n - 2)) / fib (n - 1) |

| |Simplify this expression so that g(n) is expressed in terms of g(n - 1). |

| |(a) What is your recursive definition for g(n)? |

| |(b) When does the recursion stop? |

|11. |Write a recursive method that computes the nth iteration of the golden ratio. What is the code of your method? |

|12. |What is the tenth approximation of the golden ratio? |

|13. |As you learned in the textbook, the recursive computation of fib(n) can be inefficient. Add trace statements to verify |

| |that your method for computing g(n) does not calculate each number more than once. What is the output of your trace |

| |messages? |

Mutual Recursion (and More Efficiency)

|14. |In one variant of the game of Nim, two players alternately take marbles from a pile. In each move, a player chooses how |

| |many marbles to take. The player must take at least one but at most half of the marbles. Then the other player takes a |

| |turn. The player who is left with one marble loses. |

| |Clearly, if you start with two marbles, you are going to win. Take one marble, and your opponent loses right away. We |

| |therefore say that 2 is a winning position. |

| |In general, a winning position is a position in which you can force a win. That is, there is at least one move that leads|

| |to a losing position. |

| |Conversely, a losing position is a position that is either an outright loss, or in which every move leads to a winning |

| |position. |

| |Following these definitions, write mutually recursive methods |

| |public class NimCalculator |

| |{ |

| |   public boolean isWinningPosition(int n) |

| |   { |

| |      for (int i = 1; i ................
................

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

Google Online Preview   Download