Date post: | 26-Dec-2015 |
Category: |
Documents |
Upload: | dwight-kelley |
View: | 218 times |
Download: | 3 times |
I/O in AP Java
Enjoyable, Meaningful, Non-Distracting I/O in AP Java
Ken Lambert, Washington and Lee UniversityMartin Osborne, Western Washington University
Copyright 2002
Free Supplemental Materials
www.cs.wwu.edu/martin Slides for this talk Software packages
– TerminalIO – TurtleGraphics– BreezySwing
Languages for Introductory Programming Fortran (60's) PL/1 (70's) Pascal and Modula (80's) C++ (90's) Java (2000 and beyond)
Why Java?
Pascal a teaching language C++ a developer's language Java a bit of both
– For teaching• Smaller, simpler syntax than C++
– For developer's• Safe, portable, vast supporting libraries
C++ I/O
Stream I/O– Simple, flexible– Supports both terminal and files– cin, cout for console– Stream objects for files– Suitable for introductory course
GUI's – Platform dependent– Complex – Not suitable for introductory course
Java I/O
Stream I/O – Moderately difficult– Several simple patterns cover basic situations– Somewhat suitable for introductory course
GUIs– Platform independent– Complex
• but several complex patterns cover basic situations
– Doable but not really suitable for introductory course
AP I/O Requirements
Terminal output with System.out Package supported stream input
– Basic read functions for intrinsic data types
Advantage of AP Approach Leaves more time for everything else Including some I/O that is
– Enjoyable– Meaningful– Non-distracting
Most Basic Program Structure
import …;
public class <ProgramName> {
public static void main(String [] args) {
… statements…
}
}
Temperature Conversion
User InterfaceEnter degrees Fahrenheit: 212
The equivalent in Celsius is 100.0
Implementation
import TerminalIO.KeyboardReader;
public class Convert {
public static void main(String [] args) {
double fahrenheit;
double celsius;
KeyboardReader reader = new KeyboardReader();
fahrenheit = reader.readDouble("Enter degrees Fahrenheit: ");
celsius = (fahrenheit - 32.0) * 5.0 / 9.0;
System.out.println("The equivalent in Celsius is " + celsius);
}
}
Menu Driven Conversion1) Convert from Fahrenheit to Celsius
2) Convert from Celsius to Fahrenheit
3) Quit
Enter your option: 1
Enter degrees Fahrenheit: 212
Degrees Celsius = 100.0
1) Convert from Fahrenheit to Celsius
2) Convert from Celsius to Fahrenheit
3) Quit
Enter your option: 2
Etc…
Implementation (1 of 2)
import TerminalIO.*;
public class ConvertWithMenu {
public static void main (String [] args) {
KeyboardReader reader = new KeyboardReader();
double fahrenheit, celsius;
String menu; //The multiline menu
int menuOption; //The user's menu selection
menu = "\n1) Convert from Fahrenheit to Celsius"
+ "\n2) Convert from Celsius to Fahrenheit"
+ "\n3) Quit"
+ "\nEnter your option: ";
Implementation (2 of 2)
do { menuOption = reader.readInt(menu); System.out.println (""); if (menuOption == 1){ fahrenheit = reader.readDouble("Enter degrees Fahrenheit: "); celsius = (fahrenheit - 32.0) * 5.0 / 9.0; System.out.println ("Degrees Celsius = " + celsius); }else if (menuOption == 2){ celsius = reader.readDouble("Enter degrees Celsius: "); fahrenheit = celsius * 9.0 / 5.0 + 32.0; System.out.println ("Degrees Fahrenheit = " + fahrenheit); }else if (menuOption != 3){ System.out.println ("Invalid option"); } } while (menuOption != 3); }}
Formatted Output
The number with precision 0: 1
The number with precision 1: 1.2
The number with precision 2: 1.23
The number with precision 3: 1.235
The number with precision 4: 1.2346
The number with precision 5: 1.23456
The number with precision 6: 1.234560
The number with precision 7: 1.2345600
The number with precision 8:1.23456000
The number with precision 9:**********
Implementation
import BreezySwing.Format;public class TerminalFormatDemo { public static void main (String [] args) { double number = 1.23456; for (int i = 0; i <= 9; i++){ String str = "The number with precision " + i + ":" + Format.justify ('r', number, 10, i); System.out.println (str); } }}
Temperature Conversion Revisited
User InterfaceEnter degrees Fahrenheit: 212
The equivalent in Celsius is 100.0
Native Implementation (1 of 2)
import java.io.*;
public class Convert{
public static void main (String[] args){
…
try{
InputStreamReader reader = new InputStreamReader(System.in);
BufferedReader buffer = new BufferedReader(reader);
… = Double.parseDouble(buffer.readLine());
… = Integer.parseInt(buffer.readLine());
…
}catch(Exception e){
System.err.println("Input error -- " + e.toString());
}
}
}
Native Implementation (2 of 2)
import java.io.*;
public class Convert{
public static void main (String[] args){
double fahrenheit;
double celsius;
try{
InputStreamReader reader = new InputStreamReader(System.in);
BufferedReader buffer = new BufferedReader(reader);
System.out.print("Enter degrees Fahrenheit: ");
fahrenheit = Double.parseDouble(buffer.readLine());
celsius = (fahrenheit - 32.0) * 5.0 / 9.0;
System.out.println("The equivalent in Celsius is " + celsius);
}catch(Exception e){
System.err.println("Input error -- " + e.toString());
}
}
}
Factoring Out the Complexitywith a static method (1 of 2)
import java.io.*;
public class Convert2{
public static void main (String[] args){
double fahrenheit;
double celsius;
fahrenheit = readDouble("Engter degrees Fahrehheit: ");
celsius = (fahrenheit - 32.0) * 5.0 / 9.0;
System.out.println("The equivalent in Celsius is " + celsius);
}
Factoring Out the Complexity with a static method (2 of 2)
public static double readDouble(String prompt){ double theNumber; try{ InputStreamReader reader = new InputStreamReader(System.in); BufferedReader buffer = new BufferedReader(reader); System.out.print(prompt); theNumber = Double.parseDouble(buffer.readLine()); return theNumber; }catch(Exception e){ System.err.println("Input error -- " + e.toString()); return 0; } }}
Factoring Out the Complexity with a supporting class (1 of 2)
public class Convert3 {
public static void main(String [] args) {
double fahrenheit;
double celsius;
KeyboardReader reader = new KeyboardReader();
fahrenheit = reader.readDouble("Enter degrees Fahrenheit: ");
celsius = (fahrenheit - 32.0) * 5.0 / 9.0;
System.out.println("The equivalent in Celsius is " + celsius);
}
}
Factoring Out the Complexity with a supporting class (2 of 2)import java.io.*;public class KeyboardReader{ public double readDouble(String prompt){ double theNumber; try{ InputStreamReader reader = new InputStreamReader(System.in); BufferedReader buffer = new BufferedReader(reader); System.out.print(prompt); theNumber = Double.parseDouble(buffer.readLine()); return theNumber; }catch(Exception e){ System.err.println("Input error -- " + e.toString()); return 0; } }}
Implementationimport TurtleGraphics.StandardPen;public class DrawSquare { public static void main (String [] args) {
// Instantiate a pen object StandardPen pen = new StandardPen(); // Lift the pen, move it to the square's top left corner, // and lower it again pen.up(); pen.move(25); pen.turn(90); pen.move(25); pen.down(); // Draw the square pen.turn(90); pen.move(50); pen.turn(90); pen.move(50); pen.turn(90); pen.move(50); pen.turn(90); pen.move(50); }}
import TurtleGraphics.StandardPen;public class Draw100gon { public static void main (String [] args) { int i; StandardPen pen = new StandardPen(); // Lift, move to top of circle, lower pen.up(); pen.move(25); pen.turn(90); pen.move(0.8); pen.down(); // Draw the 100gon for (i = 1; i <= 100; i++){ pen.turn(3.6); pen.move(1.6); } }}
Implementation
Outline of Classpublic class SmilingFace {
public SmilingFace(){...}
public SmilingFace(double x, double y){...}
public void draw(){
public void erase(){
public void move(double x, double y){...}
private void drawCircle(double x, double y, double r){...}
private void drawLine(double x1, double y1,
double x2, double y2){...}
private StandardPen pen;
private double xPosition, yPosition;
}
Using the Classimport TurtleGraphics.*;import TerminalIO.*;public class TestSmilingFace { public static void main (String[] args){ KeyboardReader reader = new KeyboardReader(); double x, y, radius;
x = reader.readDouble("Initial x position: "); y = reader.readDouble("Initial y position: "); SmilingFace face = new SmilingFace(x, y); face.draw (); while (true){ x = reader.readDouble("New x position: "); y = reader.readDouble("New y position: "); face.erase(); face.move(x, y); face.draw(); } }}
Implementation of Class (1 of 4)
import TurtleGraphics.*;
import java.awt.Color;
public class SmilingFace {
private StandardPen pen;
private double xPosition, yPosition;
public SmilingFace(){
xPosition = 0;
yPosition = 0;
pen = new StandardPen();
pen.setColor(Color.red);
}
public SmilingFace(double x, double y){
this();
xPosition = x;
yPosition = y;
}
Implementation of Class (2 of 4)
public void erase(){
pen.setColor(Color.white);
draw();
pen.setColor(Color.red);
}
public void move(double x, double y){
xPosition = x;
yPosition = y;
}
Implementation of Class (3 of 4)
public void draw(){
double radius = 50.0;
// Draw the outline of the face
drawCircle(xPosition, yPosition, radius);
// Draw the left and right eye.
drawCircle(xPosition - radius / 2.5, yPosition + radius / 3, radius / 4);
drawCircle(xPosition + radius / 2.5, yPosition + radius / 3, radius / 4);
// Draw the horizontal part of the mouth
drawLine(xPosition - radius / 3, yPosition - radius / 2,
xPosition + radius / 3, yPosition - radius / 2);
// Draw the left and right smile line
drawLine(xPosition - radius / 3 , yPosition - radius / 2,
xPosition - radius / 3 - 5, yPosition - radius / 2 + 5);
drawLine(xPosition + radius / 3 , yPosition - radius / 2,
xPosition + radius / 3 + 5, yPosition - radius / 2 + 5);
}
Implementation of Class (4 of 4)
private void drawCircle(double x, double y, double r){ double side = 2.0 * Math.PI * r / 120.0; pen.up(); pen.move(x + r, y - side / 2.0); pen.setDirection(90); pen.down(); for (int i = 0; i < 120; i++){ pen.move(side); pen.turn(3); } }
private void drawLine(double x1, double y1, double x2, double y2){ pen.up(); pen.move(x1, y1); pen.down(); pen.move(x2, y2); }}
Implementation (1 of 2)
import java.awt.Color;
import TurtleGraphics.*;
public class Recursion {
public static void main (String [] args) {
Pen pen = new StandardPen();
pen.setWidth(1);
for (int i = 1; i <= 6; i++){
pen.up();
pen.move(-100, 245 - 70 * i);
pen.down();
pen.setDirection(0);
drawFractal(i, pen, 200);
}
}
Implementation (2 of 2)
private static void drawFractal(int depth, Pen pen, double length){
if (depth <= 1)
pen.move(length);
else{
drawFractal(depth - 1, pen, length / 3);
pen.turn(60);
drawFractal(depth - 1, pen, length / 3);
pen.turn(-120);
drawFractal(depth - 1, pen, length / 3);
pen.turn(60);
drawFractal(depth - 1, pen, length / 3);
}
}
}
Implementationimport java.applet.Applet;import java.awt.Graphics;import java.awt.Graphics2D;import java.awt.Rectangle;import java.awt.geom.Ellipse2D;import java.awt.geom.Line2D;import java.awt.geom.Point2D;
public class Shapes extends Applet{ public void paint(Graphics g){ Graphics2D g2 = (Graphics2D)g; Rectangle rectangle = new Rectangle(50, 50, 100, 50); Ellipse2D.Double ellipse = new Ellipse2D.Double(50, 50, 100, 50); Point2D.Double point1 = new Point2D.Double(50, 50); Point2D.Double point2 = new Point2D.Double(150, 100); Line2D.Double line = new Line2D.Double(point1, point2); g2.draw(rectangle); g2.draw(ellipse); g2.draw(line); }}
Breezy Implementation (1 of 4)
import javax.swing.*;
import BreezySwing.*;
public class ConvertWithGUI extends GBFrame{
private JLabel fahrenheitLabel;
private JLabel celsiusLabel;
private DoubleField fahrenheitField;
private DoubleField celsiusField;
private JButton fahrenheitButton;
private JButton celsiusButton;
Breezy Implementation (2 of 4)
public ConvertWithGUI(){
fahrenheitLabel = addLabel ("Fahrenheit" ,1,1,1,1);
celsiusLabel = addLabel ("Celsius" ,1,2,1,1);
fahrenheitField = addDoubleField (32.0 ,2,1,1,1);
celsiusField = addDoubleField (0.0 ,2,2,1,1);
fahrenheitButton = addButton (">>>>>>" ,3,1,1,1);
celsiusButton = addButton ("<<<<<<" ,3,2,1,1);
}
Breezy Implementation (3 of 4)
public void buttonClicked (JButton buttonObj){ double fahrenheit, celsius; if (buttonObj == fahrenheitButton){ fahrenheit = fahrenheitField.getNumber(); celsius = (fahrenheit - 32.0) * 5.0 / 9.0; celsiusField.setNumber (celsius); }else{ celsius = celsiusField.getNumber(); fahrenheit = celsius * 9.0 / 5.0 + 32.0; fahrenheitField.setNumber (fahrenheit); } }
Breezy Implementation (4 of 4)
public static void main (String[] args){
ConvertWithGUI theGUI = new ConvertWithGUI();
theGUI.setSize (250, 100);
theGUI.setVisible (true);
}
Native Implementation (1 of 6)
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class ConversionWithSwing extends JFrame{
private JLabel fahrenheitLabel;
private JTextField fahrenheitField;
private JLabel celsiusLabel;
private JTextField celsiusField;
private JButton fahrenheitButton;
private JButton celsiusButton;
Native Implementation (2 of 6)
public ConversionWithSwing(){
fahrenheitLabel = new JLabel ("Fahrenheit");
celsiusLabel = new JLabel ("Celsius");
fahrenheitField = new JTextField ("212", 6); // 6 columns wide
celsiusField = new JTextField ("100", 6); // 6 columns wide
fahrenheitButton = new JButton (">>>>>>");
celsiusButton = new JButton ("<<<<<<");
Native Implementation (3 of 6)
Container contentPane = getContentPane();
contentPane.setLayout (new FlowLayout());
contentPane.add (fahrenheitLabel);
contentPane.add (celsiusLabel);
contentPane.add (fahrenheitField);
contentPane.add (celsiusField);
contentPane.add (fahrenheitButton);
contentPane.add (celsiusButton);
fahrenheitButton.addActionListener(new MyActionListener());
celsiusButton.addActionListener(new MyActionListener());
addWindowListener(new MyWindowAdapter());
}
Native Implementation (4 of 6)
public static void main (String[] args){
ConversionWithSwing theGUI = new ConversionWithSwing();
theGUI.setSize (200, 125);
theGUI.setVisible (true);
}
Native Implementation (5 of 6) private class MyActionListener implements ActionListener{ public void actionPerformed (ActionEvent event){ double fahrenheit, celsius; String str; Object source = event.getSource(); if (source == fahrenheitButton){ str = fahrenheitField.getText().trim(); fahrenheit = Double.parseDouble(str); celsius = (fahrenheit - 32) * 5 / 9; celsiusField.setText ("" + celsius); }else{ str = celsiusField.getText().trim(); celsius = Double.parseDouble(str); fahrenheit = celsius * 9 / 5 + 32; fahrenheitField.setText ("" + fahrenheit); } } }
Native Implementation (6 of 6)
private class MyWindowAdapter extends WindowAdapter{
public void windowClosing (WindowEvent e){
System.exit(0);
}
}
}
Drawback of Flow Layout Fields move around when window
resized Solution – use a gridbag layout
– Unfortunately, considerably more complex