Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Java: The White Paper The White Paper on Java uses the following eleven adjectives to describe the Java Language and Platform: Simple Object Oriented Distributed Robust Secure Architecture Neutral Portable Interpreted High Performance Multithreaded Dynamic Simple o o Streamlined C++ No Header Files No Pointer Arithmetic No Structures, Unions, Operator Overloading, Virtual Base Classes, etc. Small Only 250K for the interpreter and base libraries Distributed o import v. #include o networking Robust o Java pointers o extensive error checking at both compile and run time Secure o Java pointers o Class Loader o Byte Verifier Security Manager Applications v. Applets Architecture Neutral o Portable o o Fixed sizes primitive data types 32-bit Integers Unicode AWT to Swing Interpreted o o Byte Code is Byte Code Faster than data stream C++ simply waits longer Recent optimized compilers get close to C++ JIT Compilers x10-x20 Multithreaded o Multiprocessing at the sub-process level o Extremely useful on Server side Dynamic o o Class Loader Virtually All Objects Dynamically Allocated . . . and Garbage Collected Reflection and Introspection JDK1.0.2 JDK1.1 better interactive responsiveness and real time behavior o JDK1.1.1 o ... o JDK1.1.8 JDK1.2 - Platform 2 o http://java.sun.com/ add "C:\jdk1.x\bin" to path Compiling and Running the Hello World Application class HelloWorldApp { public static void main(String[] args) { System.out.println("Hello World!"); } } o save as text file HelloWorldApp.java o at command line type>javac HelloWorldApp.java o execute program by typing>java HelloWorldApp Compiling and Running the Hello World Applet import java.applet.Applet; import java.awt.Graphics; class HelloWorldApplet extends Applet { public void paint(Graphics g) { g.drawString("Hello World!", 50, 25); } } o save as text file HelloWorldApplet.java o at command line type>javac HelloWorldApplet.java o execution is performed by viewer (browser) Methods to override: init(); start(); stop(); destroy(); paint(); Simple HTML Texts: o Core Java by Horstmann and Cornell (Sun and Prentice Hall) o The Java Tutorial by Campione and Walrath (Sun and Prentice Hall) Online: o The Java Tutorial - http://java.sun.com/tutorial o JavaWorld Magazine - http://www.javaworld.com o Gamelan - http://www.gamelan.com o Excite, AltaVista, WebCrawler, etc. o A Beginner's Guide to HTML (NSCA) Lecture 1b Differences between C++ and Java C++ is a superset of C while Java is a strictly Object Oriented Language. C is procedural while C++ is object oriented o Many C++ programmers write non-OO code o Can't get away with that in Java o In Java, all classes descend from "Object" C++ allows multiple inheritance while Java uses Interfaces. o Object Communication o An interface is a protocol by which two otherwise unrelated objects communicate C++ runs on the hardware machine while Java runs on a Virtual machine. o Java Virtual Machine - Java Runtime Environment C++ makes extensive use of pointers while Java has no specific pointer type. In addition to the access specifiers of C++ (public, protected & private), Java adds a new one (package). o Individually tagged C++ allows operator overloading; Java does not. Java allows inner classes and anonymous inner classes; C++ does not. Java is Garbage Collected; C++ is not. o new o no delete In Java, arrays are objects. o out of bounds o length class HelloWorldApp { public static void main(String[] args) { System.out.println("Hello World!"); } } // Not a GUI program. GUI For even the most basic GUI, one needs a working knowledge of : o Layout Managers o Interfaces o AWT (or Swing) widgets 1.1 Event Handling import java.awt.*; import java.awt.event.*; public class CloseableFrame extends Frame { public CloseableFrame() { addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } } ); setSize(300, 200); setTitle(getClass().getName()); } } Resources Texts: o Core Java by Horstmann and Cornell (Sun and Prentice Hall) o The Java Tutorial by Campione and Walrath (Sun and Prentice Hall) Online: o The Java Tutorial - http://java.sun.com/tutorial o JavaWorld Magazine - http://www.javaworld.com o Gamelan - http://www.gamelan.com o Excite, AltaVista, WebCrawler, etc. Lecture #2 Reserved Words abstract do boolean double break else byte extends byvalue false case final cast finally catch char implements private import protected transient inner public instanceof rest int interface short float for new var void static native true try return long throws volatile strictfp super while widefp class future null const generic operator synchronized continue goto default outer if switch this package throw Reserved Words (Not Currently Used) byvalue cast future generic const inner rest operator var goto outer Non-Reserved Words (Examples) delete include define inline friend using ifdef virtual Identifiers o Theoretically may be made up from the Unicode character set but the tools only work with ASCII. o The first character may only be a letter, a dollar sign or and underscore. MyVariable o $anotherName _yetAnotherName However, the convention is that method names start with a lower case letter: public void myMethodThatDoesAmazingThings(){} o While Variables and Class names start with an upper case letter: public class MyClass { public int MyVariable = 5; } Primitives Type byte short Contains Size signed integer Range 8 bits signed integer 16 bits -128 to 127 -32768 to 32767 char unsigned Unicode 16 bits \u0000 to \u FFFF int signed integer -231 to 231 – 1 float single precision 32 bits 32 bits 1.4 x 10-45 to 3.4 x 1038 double double precision 64 bits 4.9 x 10-324 to 1.8 x 10308 boolean true or false --------- true or false Primitives v. Reference Variables (Object Wrappers) Primitive Object byte Byte short Short char Char int Integer float Float double Double boolean Boolean public class SimplePoint { public int x = 0; public int y = 0; } public class SimpleRectangle { public int width = 0; public int height = 0; public SimplePoint origin = new SimplePoint(); } public class Point { public int x = 0; public int y = 0; // a constructor! public Point(int x, int y) { this.x = x; this.y = y; } } Passing Arguments o In Java variables are passed by value. The Class Declaration o public By default, a class can be used only by other classes in the same package. The public modifier declares that the class can be used by any class regardless of its package. o abstract o final o Declares that the class cannot be instantiated. Declares that the class cannot be subclasssed. class NameOfClass The class keyword indicates to the compiler that this is a class declaration and that the name of the class is NameOfClass. o extends Super The extends clause identifies Super as the superclass of the class, thereby inserting the class within the class hierarchy. o implements Interfaces To declare that your class implements one or more interfaces, use the keyword implements followed by a comma-delimited list of the names of the interfaces implemented by the class. public final class MyClass extends Applet implements ItemListener, ActionListener { ... } Access Specifiers o private o protected o Also accessible from subclasses and package members. package o Only accessible from within the class (not merely the instance). Accessible from package members. (Friends, not family) public o No restrictions. Accessible from anywhere. Providing Constructors for Your Classes Constructor Defined: Default public Stack() { items = new Vector(10); } Overloaded public Stack(int initialSize) { items = new Vector(initialSize); } Constructor Called: stack MyStack = new Stack(10); stack MyOtherStack = new Stack(); This and Super class AnimationThread extends Thread { int framesPerSecond; int numImages; Image[] images; AnimationThread(int fps, int num) { super("AnimationThread"); this.framesPerSecond = fps; this.numImages = num; this.images = new Image[numImages]; for (int i = 0; i <= numImages; i++) { ... // Load all the images. ... } } ... } public class Rectangle { public int width = 0; public int height = 0; public Point origin; // four constructors public Rectangle() { origin = new Point(0, 0); } public Rectangle(Point p) { origin = p; } public Rectangle(int w, int h) { this(new Point(0, 0), w, h); } public Rectangle(Point p, int w, int h) { origin = p; width = w; height = h; } // a method for moving the rectangle public void move(int x, int y) { origin.x = x; origin.y = y; } // a method for computing the area of the rectangle public int area() { return width * height; } // clean up! protected void finalize() throws Throwable { origin = null; super.finalize(); } } Declaring Member Variables Access Level Public, protected, package, and private. static Declares this is a class variable rather than an instance variable. You also use static to declare class methods. final Indicates that the value of this member cannot change. transient Used in serialization to mark variables that should not be serialized. volatile The volatile keyword is used to prevent the compiler from performing certain optimizations on a member. type Like other variables, a member variable must have a type. You can use primitive type names such as int, float, or boolean. Or you can use reference types, such as array, object, or interface names. name A member variable's name can be any legal Java identifier. You cannot declare more than one member variable with the same name in the same class, but a subclass can hide a member variable of the same name in its superclass. Additionally, a member variable and a method can have the same name. For example, the following code is legal: public class Stack { private Vector items; // a method with same name as a member variable public Vector items() { ... }} Variable Examples public int MyInt = 5; public final int AnotherInt = 10; private final long YetAnother = 76L; float MyDecimal = 30.0; Point myPoint = new Point(); final Point MyOtherPoint = new Point(5,7); Details of a Method Declaration Access Level Public, protected, package, and private static As with member variables, static declares this method as a class method rather than an instance method. abstract An abstract method has no implementation and must be a member of an abstract class. final A final method cannot be overridden by subclasses. native Methods implemented in a language other than Java are called native methods and are declared as such using the native keyword. synchronized Concurrently running threads often invoke methods that operate on the same data. These methods may be declared synchronized to ensure that the threads access information in a thread-safe manner. returnType If your method does not return a value, use the keyword void for the return type. methodName ( paramlist ) You pass information into a method through its arguments [throws exceptions] If your method throws any checked exceptions, your method declaration must indicate the type of those exceptions Returning a Value from a Method public boolean isEmpty() { if (items.size() == 0) return true; else return false; } Returns a primitive. public synchronized Object pop() { int len = items.size(); Object obj = null; if (len == 0) throw new EmptyStackException(); obj = items.elementAt(len - 1); items.removeElementAt(len - 1); return obj; } Returns an object. Remember: When a method returns an object such as pop does, the class of the returned object must be either a subclass of or the exact class of the return type. This Revisited class HSBColor { int hue, saturation, brightness; HSBColor (int hue, int saturation, int brightness) { this.hue = hue; this.saturation = saturation; this.brightness = brightness; } ... } Super Revisited A class: class ASillyClass { boolean aVariable; void aMethod() { aVariable = true; } } and its subclass which hides aVariable and overrides aMethod; class ASillierClass extends ASillyClass { boolean aVariable; void aMethod() { aVariable = false; super.aMethod(); System.out.println(aVariable); System.out.println(super.aVariable); } } overriden method invoked with this statement: super.aMethod(); aMethod displays both versions of aVariable which have different values: false true Access Specification Private Access: class Alpha { private int iamprivate; boolean isEqualTo(Alpha anotherAlpha) { if (this.iamprivate == anotherAlpha.iamprivate) return true; else return false; } } Package Access: package Greek; class Alpha { int iampackage; void packageMethod() { System.out.println("packageMethod"); } } package Greek; class Beta { void accessMethod() { Alpha a = new Alpha(); a.iampackage = 10; // legal a.packageMethod(); // legal } } Protected Access: (Caveat) package Greek; class Alpha { protected int iamprotected; protected void protectedMethod() { System.out.println("protectedMethod"); } } package Greek; class Gamma { void accessMethod() { Alpha a = new Alpha(); a.iamprotected = 10; // legal a.protectedMethod(); // legal } } package Latin; import Greek.*; class Delta extends Alpha { //class Alpha must be public void accessMethod(Alpha a, Delta a.iamprotected = 10; d.iamprotected = 10; a.protectedMethod(); d.protectedMethod(); } d) { // illegal // legal // illegal // legal } Instance Members v. Class Members class AnIntegerNamedX { int x; public int x() { return x; } public void setX(int newX) { x = newX; } } ... AnIntegerNamedX myX = new AnIntegerNamedX(); AnIntegerNamedX anotherX = new AnIntegerNamedX(); myX.setX(1); anotherX.x = 2; System.out.println("myX.x = " + myX.x()); System.out.println("anotherX.x = " + anotherX.x()); ... >myX.x = 1 >anotherX.x = 2 class AnIntegerNamedX { static int x; public int x() { return x; } public void setX(int newX) { x = newX; } } ... //same code as above ... >myX.x = 2 >anotherX.x = 2 Lecture #3 Managing Inheritance Hiding Member Variables class Super { Number aNumber; } class Subbie extends Super { Float aNumber; } The aNumber variable in Subbie hides aNumber in Super. But you can access Super's aNumber from Subbie with super.aNumber Overriding Methods public class Stack { private Vector items; // code for Stack's methods/constructor not shown // overrides Object's toString method public String toString() { StringBuffer result = new StringBuffer(); result.append("["]; for (int i = 0; i < n; i++) { result.append(items.elementAt[i].toString()); if (i == n-1) result.append(")"); else result.append(","); } return result.toString(); } } Calling the Overridden Method protected void finalize() throws Throwable { items = null; super.finalize(); } Methods a Subclass Cannot Override Can’t override static or final: i.e., FinalTest.java:7: Final methods can't be overridden. Method void iamfinal() is final in class ClassWithFinalMethod. void iamfinal() { ^ 1 error Methods a Subclass Must Override Abstract methods. Object Methods possible to override: clone equals finalize toString Methods not possible to override (they are final): getClass notify notifyAll wait The clone Method By default, objects are not cloneable, so Object's implementation of this method throws a CloneNotSupportedException. If you want your class to be cloneable, you must implement the Cloneable interface and override this method. Your version of the clone method must provide for a field-by-field copy of the object being cloned public class Stack implements Cloneable { private Vector items; // code for Stack's methods and // constructor not shown protected Object Clone() { try { Stack s = (Stack)super.clone(); s.items = (Vector)items.clone(); return s; } catch (CloneNotSupportedException e) { // this shouldn't happen //because Stack is Cloneable throw new InternalError(); } } } The equals Method The equals method compares two objects for equality and returns true if they are equal. The equals method provided in the Object class uses the identity function to determine if objects are equal (if the objects compared are the exact same object the method returns true). Integer one = new Integer(1), anotherOne = new Integer(1); if (one.equals(anotherOne)) System.out.println("objects are equal"); The finalize Method Marks an object for the garbage collector. The toString Method Object's toString method returns a String representation of the object. You can use toString along with System.out.println to display a text representation of an object, such as the current thread: System.out.println(Thread.currentThread().toString()); The String representation for an object depends entirely on the object. The String representation of an Integer object is the integer value displayed as text. The String representation of a Thread object contains various attributes about the thread, such as its name and priority. For example, the previous line of code displays the following output: Thread[main,5,main] The toString method is very useful for debugging. You should override this method in all your classes. The getClass Method The getClass method is a final method that returns a runtime representation of the class of this object. This method returns a Class object. You can query the Class object for various information about the class, such as its name, its superclass, and the names of the interfaces that it implements. The following method gets and displays the class name of an object: void PrintClassName(Object obj) { System.out.println("The Object's class is " + obj.getClass().getName()); } One handy use of the getClass method is to create a new instance of a class without knowing what the class is at compile time. The following sample method creates a new instance of the same class as obj, which can be any class that inherits from Object (which means that it could be any class): Object createNewInstanceOf(Object obj) { return obj.getClass().newInstance(); } The notify, notifyAll, and wait Methods Used to ensure that threads are synchronized. Final Classes and Methods Final Classes final class ChessAlgorithm { ... } Final Methods class ChessAlgorithm { ... final void nextMove(ChessPiece pieceMoved, BoardLocation newLocation) { ... } ... } Abstract Classes and Methods Abstract Classes abstract class Number { ... } Abstract Methods abstract class GraphicObject { int x, y; ... void moveTo(int newX, int newY) { ... } abstract void draw(); } class Circle extends GraphicObject { void draw() { ... } } Supplemental Material See the one, two, three and test classes in the supp directory. See also the equality and oldequality classes in the supp directory. Essential Java Classes Using String and StringBuffer String and StringBuffer Example public class ReverseString { public static String reverseIt(String source) { int i, len = source.length(); StringBuffer dest = new StringBuffer(len); for (i = (len - 1); i >= 0; i--) dest.append(source.charAt(i)); return dest.toString(); } } Why Two String Classes? class ReverseString { public static String reverseIt(String source) { int i, len = source.length(); StringBuffer dest = new StringBuffer(len); for (i = (len - 1); i >= 0; i--) { dest.append(source.charAt(i)); } return dest.toString(); } } Creating Strings and StringBuffers Creating a String String s = "Gobbledy gook." String s = new String("Gobbledy gook."); Creating a StringBuffer StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer(20); Accessor/Mutator Methods class ReverseString { public static String reverseIt(String source) { int i, len = source.length(); StringBuffer dest = new StringBuffer(len); for (i = (len - 1); i >= 0; i--) { dest.append(source.charAt(i)); } return dest.toString(); } } int len = source.length(); source.charAt(i) More Accessor Methods public class Filename { private String fullPath; private char pathSeparator, extensionSeparator; public Filename(String str, char sep, char ext) { fullPath = str; pathSeparator = sep; extensionSeparator = ext; } public String extension() { int dot = fullPath.lastIndexOf(extensionSeparator); return fullPath.substring(dot + 1); } } public String filename() { int dot = fullPath.lastIndexOf(extensionSeparator); int sep = fullPath.lastIndexOf(pathSeparator); return fullPath.substring(sep + 1, dot); } public String path() { int sep = fullPath.lastIndexOf(pathSeparator); return fullPath.substring(0, sep); } Here's a small program that constructs a Filename object and calls all of its methods: public class FilenameTest { public static void main(String[] args) { Filename myHomePage = new Filename("/home/mem/index.html", '/', '.'); System.out.println("Extension = " + myHomePage.extension()); System.out.println("Filename = " + myHomePage.filename()); System.out.println("Path = " + myHomePage.path()); } } The output from the program: Extension = html Filename = index Path = /home/mem/public_html Modifying StringBuffers class ReverseString { public static String reverseIt(String source) { int i, len = source.length(); StringBuffer dest = new StringBuffer(len); for (i = (len - 1); i >= 0; i--) { dest.append(source.charAt(i)); } return dest.toString(); } } Capacity: StringBuffer similar to Vector (String similar to Array) Inserting Characters StringBuffer sb = new StringBuffer("Drink Java!"); sb.insert(6, "Hot "); System.out.println(sb.toString()); This code snippet prints: Drink Hot Java! Setting Characters setCharAt(i); Converting Objects to Strings x.toString(); Converting Primitive Data Types to Strings x.valueOf(); i.e., System.out.println(String.valueOf(Math.PI)); Converting Strings to Numbers String piStr = “3.14159”; Float pi = Float.valueOf(piStr); Strings and the Java Compiler System.out.println(“Hello World”); int len = “Hello World”.length(); String s = “Hello World”; String s = new String(“Hello World”); Concatenation and the + Operator String cat = “cat”; System.out.println(”con” + cat + “enation”); ... int n = 50; String s = n; //illegal cast String s = “” + n; //ok System.out.println(“Java is number” + 1); Command-Line Arguments public class Echo { public static void main (String[] args) { for (int i = 0; i < args.length; i++) System.out.println(args[i]); } } i.e., java Echo Drink Hot Java Drink Hot Java or java Echo "Drink Hot Java" Drink Hot Java Converson of command line args to other types: int firstArg; if (args.length > 0) firstArg = Integer.parseInt(args[0]); public class Echo { public static void main (String[] args) { int firstArg; if (args.length > 0) firstArg = Integer.parseInt(args[0]); System.out.println(firstArg); } } i.e., java Echo 12 12 Applet Parameters <APPLET CODE=”MyClass.class” height=400 width=400> <PARAM NAME=”parameter1” VALUE=”500”> <PARAM NAME=”parameter2” VALUE=”Abracadabra”> Get a new Browser! </APPLET> i.e., getParameter(String name); Don’t Forget to check the supp directory for supplemental material Essential Java Classes Using String and StringBuffer String and StringBuffer Example public class ReverseString { public static String reverseIt(String source) { int i, len = source.length(); StringBuffer dest = new StringBuffer(len); for (i = (len - 1); i >= 0; i--) dest.append(source.charAt(i)); return dest.toString(); } } Why Two String Classes? class ReverseString { public static String reverseIt(String source) { int i, len = source.length(); StringBuffer dest = new StringBuffer(len); for (i = (len - 1); i >= 0; i--) { dest.append(source.charAt(i)); } return dest.toString(); } } Creating Strings and StringBuffers Creating a String String s = "Gobbledy gook." String s = new String("Gobbledy gook."); Creating a StringBuffer StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer(20); Lecture #4 PRIMITIVES Keyword Description Size/Format (integers) byte Byte-length integer 8-bit two's complement short Short integer 16-bit two's complement int Integer 32-bit two's complement long Long integer 64-bit two's complement (real numbers) float Single-precision floating point 32-bit IEEE 754 double Double-precision floating point 64-bit IEEE 754 (other types) char A single character 16-bit Unicode character boolean A boolean value (true or false) true or false Arithmetic Operators Operator Use + op1 + op2 Adds op1 and op2 - op1 – op2 Subtracts op2 from op1 * op1 * op2 Multiplies op1 by op2 / op1 / op2 Divides op1 by op2 op1 % op2 Computes the remainder of dividing op1 by op2 % Description Increment/Decrement Operators Operator Use Description ++ op++ Increments op by 1; evaluates to the value of op before it was incremented ++ ++op Increments op by 1; evaluates to the value of op after it was incremented -- op-- Decrements op by 1; evaluates to the value of op before it was decremented -- --op Decrements op by 1; evaluates to the value of op after it was decremented Relational Operators Operator Use Returns true if > op1 > op2 >= Op1 >= op2 < op1 < op2 op1 is less than op2 <= op1 <= op2 op1 is less than or equal to op2 == op1 == op2 op1 and op2 are equal != op1 != op2 op1 and op2 are not equal op1 is greater than op2 op1 is greater than or equal to op2 Conditional Operators Operator Use Returns true if && op1 && op2 || op1 || op2 ! ! op & op1 & op2 op1 and op2 are both true, always evaluates op1 and op2 | op1 | op2 either op1 or op2 is true, always evaluates op1 and op2 ^ op1 ^ op2 op1 and op2 are both true, conditionally evaluates op2 either op1 or op2 is true, conditionally evaluates op2 op is false if op1 and op2 are different--that is if one or the other of the operands is true but not both Shift Operators Operator Use Operation >> op1 >> op2 shift bits of op1 right by distance op2 << op1 << op2 shift bits of op1 left by distance op2 >>> op1 >>> op2 shift bits of op1 right by distance op2 (unsigned) Bitwise Operators Operator Use Operation & Op1 & op2 bitwise and | Op1 | op2 bitwise or ^ Op1 ^ op2 bitwise xor ~ ~op2 bitwise complement Combined Operators Operator Use Equivalent to += op1 += op2 op1 = op1 + op2 -= op1 -= op2 op1 = op1 - op2 *= op1 *= op2 op1 = op1 * op2 /= op1 /= op2 op1 = op1 / op2 %= op1 %= op2 op1 = op1 % op2 &= op1 &= op2 op1 = op1 & op2 |= op1 |= op2 op1 = op1 | op2 ^= op1 ^= op2 op1 = op1 ^ op2 <<= op1 <<= op2 op1 = op1 << op2 >>= op1 >>= op2 op1 = op1 >> op2 >>>= op1 >>>= op2 op1 = op1 >>> op2 Ternary Operator Operator ?: Use Operation op1 ? stmt1 : stmt2 if op1 true returns stmt1 else returns stmt2 Equaivalent to: if (op1) statement1; else statement2; If - Else Statements if (boolean expression) { statements; } if (boolean expression) { statements; } else { statements; } if (boolean expression) { statements; } else if (boolean expression) { statements; } if (boolean expression) { statements; } else if (boolean expression) { statements; } else { statements; } Example: int testscore; char grade; if (testscore >= 90) { grade = 'A'; } else if (testscore >= 80) { grade = 'B'; } else if (testscore >= 70) { grade = 'C'; } else if (testscore >= 60) { grade = 'D'; } else { grade = 'F'; } Switch Statement switch (integer expression) {case integer expression: statements; break; ... default: statements; break; } Example: int month; ... switch (month) { case 1: System.out.println("January"); break; case 2: System.out.println("February"); break; case 3: System.out.println("March"); break; case 4: System.out.println("April"); break; case 5: System.out.println("May"); break; case 6: System.out.println("June"); break; case 7: System.out.println("July"); break; case 8: System.out.println("August"); break; case 9: System.out.println("September"); break; case 10: System.out.println("October"); break; case 11: System.out.println("November"); break; case 12: System.out.println("December"); break; default: System.out.println("Hey, that's not a valid month!"); break; } For Loop for (initialization; termination; increment) { statements; } Example: public class ForDemo { public static void main(String[] args) { int[] arrayOfInts = { 32, 87, 3, 589, 12, 1076, 2000, 8, 622, 127 }; for (int i = 0; i < arrayOfInts.length; i++) { System.out.print(arrayOfInts[i] + " "); } System.out.println(); } } While Loop while (expression) { statements; } Example: public class WhileDemo { public static void main(String[] args) { String copyFromMe = "Copy this string until you encounter the letter 'g'."; StringBuffer copyToMe = new StringBuffer(); int i = 0; char c = copyFromMe.charAt(i); while (c != 'g') { copyToMe.append(c); c = copyFromMe.charAt(++i); } System.out.println(copyToMe); } } Do While Loop do { statement } while (expression); Example: public class DoWhileDemo { public static void main(String[] args) { String copyFromMe = "Copy this string until you encounter the letter 'g'."; StringBuffer copyToMe = new StringBuffer(); int i = 0; char c = copyFromMe.charAt(i); do { copyToMe.append(c); c = copyFromMe.charAt(++i); } while (c != 'g'); System.out.println(copyToMe); } } Exception Handling What is an Exception? Java's Policy: You must Catch or Specify all Checked Exceptions. What is a checked exception? The short answer is that it is an exception which does not descend from RuntimeException. Catching an Exception void myMethod(){ try{ // something dangerous } catch(SomeSpecificException sse){ } catch(SomeGeneralException sge){ } finally{ } } Specifying an Exception void myMethod() throws SomeException{ // something dangerous } Throwing an Exception void myMethod(int x) throws SomeException{ if (x == 0) throw new SomeException(); } The Call Stack (Cannot do it this way!) ... int dangerousMethod(int x) throws SomeException{ int d; if (x == 0) throw new SomeException(); ... return d; } int methodC(int n){ int c = dangerousMethod(n); return c; } int methodB(int n){ int b = methodC(n); return b; } int methodA(int n){ int a = methodB(n); return a; } Exception Handling The Call Stack (Can do it this way!) ... int dangerousMethod(int x) throws SomeException{ int d; if (x == 0) throw new SomeException(); ... return d; } int methodC(int n) throws SomeException{ int c = dangerousMethod(n); return c; } int methodB(int n) throws SomeException{ int b = methodC(n); return b; } int methodA(int n){ try{ int a = methodB(n); } catch(SomeException so){ System.out.println("Loser! You threw " + so); } return a; } ... Classes Defined Within Other Classes: Nested v. Inner Classes An Inner Class ... class Outer{ class Inner{ } } Classes within Classes An Inner Class With Separate Parent (Simulated Multiple Inheritance) ... class Outer extends SomeClass{ class Inner extends SomeOtherClass{ } } Classes within Classes: Individual Parents Classes within Classes: Access A Static Inner Class (Nested) ... class Outer{ static class Inner{ } } Classes within Classes: Nested Nested v. Inner Classes All Inner Classes are Nested. Not All Nested Classes are Inner. (i.e., Static) Lecture #5 Lecture 5 - Creating A Graphical User Interface Interfaces Event Handling AWT Widgets Layout Managers Object Communication Object Communication - Generic Example Object Communication - Generic Problem Object Communication - Solution? Tight Coupling v. Loose Coupling Synchronous v. Asynchronous Object Communication - Solution! o Interfaces o A protocol by which two otherwise unrelated object communicate. o An interface is a named collection of method definitions (without implementations). An interface can also include constant declarations. Object Communication - Solution! o You use an interface to define a protocol of behavior that can be implemented by any class anywhere in the class hierarchy. Interfaces are useful for the following: Capturing similarities between unrelated classes without artificially forcing a class relationship Declaring methods that one or more classes are expected to implement Revealing an object's programming interface without revealing its class. (Objects such as these are called anonymous objects and can be useful when shipping a package of classes to other developers.) Object Communication - Solution = Interface Object Communication - Example public class SimpleAlarmClock { private Sleeper sleeper; private long sleepFor; public SimpleAlarmClock () { sleeper = null; sleepFor = 0; } } public void letMeSleepFor(Sleeper s, long time) { sleeper = s; sleepFor = time; // block for "sleepFor" time then call sleeper.wakeUp(); } Object Communication - Example public class SimpleAlarmClock { private Sleeper sleeper; private long sleepFor; public SimpleAlarmClock () { sleeper = null; sleepFor = 0; } public boolean letMeSleepFor(Sleeper s, long time) { sleeper = s; sleepFor = time; new SimpleAlarmThread().start(); return true; } private void wakeUpSleeper() { sleeper.wakeUp(); } private class SimpleAlarmThread extends Thread { SimpleAlarmThread() { super(); } public void run() { try { sleep(sleepFor); } catch (InterruptedException e) {} wakeUpSleeper(); } } } Object Communication - Example public interface Sleeper { public void wakeUp(); public long ONE_SECOND = 1000; // in milliseconds public long ONE_MINUTE = 60000; // in milliseconds } Object Communication - Example public interface Sleeper { public void wakeUp(); public void beep(); public long ONE_SECOND = 1000; // in milliseconds public long ONE_MINUTE = 60000; // in milliseconds } Interfaces Cannot Grow! Object Communication - Example public class ReallySimpleGUIClock extends Applet implements Sleeper { private SimpleAlarmClock clock; public void init() { clock = new SimpleAlarmClock(); setBackground(Color.white); } public void start() { clock.letMeSleepFor(this, 1000); } public void wakeUp() { repaint(); clock.letMeSleepFor(this, 1000); } public void paint(Graphics g) { String s = ""+Calendar.getInstance().getTime(); g.drawString(s, getWidth()/2, getHeight()/2); } } Object Communication - Example public class ReallySimpleGUIClock extends Applet implements Sleeper { private SimpleAlarmClock clock; public void init() { clock = new SimpleAlarmClock(); setBackground(Color.white); } public void start() { clock.letMeSleepFor(this, 1000); } public void wakeUp() { repaint(); clock.letMeSleepFor(this, 1000); } public void paint(Graphics g) { String s = ""+Calendar.getInstance().getTime(); g.drawString(s, getWidth()/2, getHeight()/2); FontMetrics fm = getFontMetrics(getFont()); int sw = fm.stringWidth(s); g.drawString(s, getWidth()/2 - sw/2, getHeight()/2 +30); DateFormat dateFormatter = DateFormat.getTimeInstance(); String t = dateFormatter.format(Calendar.getInstance().getTime()); } sw = fm.stringWidth(t); g.drawString(t, getWidth()/2 - sw/2, getHeight()/2 + 60); } Object Communication - Example public class ReallySimpleGUIClock extends Applet implements Sleeper { private SimpleAlarmClock clock; public void init() { clock = new SimpleAlarmClock(); setBackground(Color.white); public void start() { clock.letMeSleepFor(this, 1000); } } public void wakeUp() { repaint(); clock.letMeSleepFor(this, 1000); } public void paint(Graphics g) { Calendar cal = Calendar.getInstance(); Date date = cal.getTime(); DateFormat dateFormatter = DateFormat.getTimeInstance(); String s = dateFormatter.format(date); FontMetrics fm = getFontMetrics(getFont()); int sw = fm.stringWidth(s); g.drawString(s, getWidth()/2 - sw/2, getHeight()/2); } Event Handling Event Handling - AWT Listener Interfaces Listener Interface Adapter Class Methods ActionListener none actionPerformed AdjustmentListener none adjustmentValueChanged componentHidden ComponentListener ComponentAdapter componentMoved componentResized componentShown ContainerListener ContainerAdapter FocusListener FocusAdapter ItemListener none componentAdded componentRemoved focusGained focusLost itemStateChanged keyPressed KeyListener KeyAdapter keyReleased keyTyped mouseClicked mouseEntered MouseListener MouseAdapter mouseExited mousePressed mouseReleased MouseMotionListener MouseMotionAdapter TextListener none mouseDragged mouseMoved textValueChanged windowActivated windowClosed windowClosing WindowListener WindowAdapter windowDeactivated windowDeiconified windowIconified windowOpened Event Sources - AWT Widgets Types of Events It Can Generate AWT Component Button action adjustment component container focus item key mouse X mouse motion X X X X X Canvas X X X X X Checkbox X X X X X X X X X text window CheckboxMenuItem Note: This is not a Component * X subclass! Choice X X Component X X X X X Container X X X X X X Dialog X X X X X X X Frame X X X X X X X Label X X X X X X X X X X X X X X X X X X X X X X List X X X MenuItem Note: This is not a Component X subclass! Panel X Scrollbar X X X ScrollPane X TextArea X X X X X X TextComponent X X X X X X X X X X X X X X X X TextField Window X X X X X Event Handling Example - Button (incomplete) import java.awt.*; import java.awt.event.*; import java.applet.*; public class ButtonExample extends Applet{ public void init(){ MyButton = new Button(); MyButton.setLabel("Button One"); add(MyButton); } Button MyButton; } Event Handling Example - Button import java.awt.*; import java.awt.event.*; import java.applet.*; public class WorkingButtonExample extends Applet{ public void init(){ MyButton = new Button(); MyButton.setLabel("Button One"); add(MyButton); MyButton.addActionListener(new ButtonListener()); } } class ButtonListener implements ActionListener{ public void actionPerformed(ActionEvent ae){ setBackground(Color.blue); repaint(); } } Button MyButton; Event Handling Example - Two Buttons import java.awt.*; import java.awt.event.*; import java.applet.*; public class TwoWorkingButtonExample extends Applet{ public void init(){ MyButton = new Button(); MyButton.setLabel("Button One"); add(MyButton); MyButton.addActionListener(new ButtonListener()); MyOtherButton = new Button("Button Two"); add(MyOtherButton); MyOtherButton.addActionListener(new ButtonListener(){ public void actionPerformed(ActionEvent ae){ setBackground(Color.red); repaint(); } }); } } class ButtonListener implements ActionListener{ public void actionPerformed(ActionEvent ae){ setBackground(Color.blue); repaint(); } } Button MyButton, MyOtherButton; Event Handling Example - Two Buttons (One Listener) import java.awt.*; import java.awt.event.*; import java.applet.*; public class TwoWorkingButtonOneListenerExample1 extends Applet{ public void init(){ MyButton = new Button(); MyButton.setLabel("Button One"); add(MyButton); MyListener = new MultipleButtonListener(); MyButton.addActionListener(MyListener); MyOtherButton = new Button("Button Two"); add(MyOtherButton); MyOtherButton.addActionListener(MyListener); } class MultipleButtonListener implements ActionListener{ public void actionPerformed(ActionEvent ae){ if(ae.getSource() == MyButton){ setBackground(Color.blue); repaint(); } else{ setBackground(Color.red); repaint(); } } } } MultipleButtonListener MyListener; Button MyButton, MyOtherButton; Event Handling Example - Two Buttons (One Listener using ActionCommand) import java.awt.*; import java.awt.event.*; import java.applet.*; public class TwoWorkingButtonOneListenerExample2 extends Applet{ public void init(){ MyButton = new Button(); MyButton.setLabel("Button One"); add(MyButton); MyListener = new MultipleButtonListener(); MyButton.addActionListener(MyListener); MyOtherButton = new Button("Button Two"); add(MyOtherButton); MyOtherButton.addActionListener(MyListener); } class MultipleButtonListener implements ActionListener{ public void actionPerformed(ActionEvent ae){ String temp = ae.getActionCommand(); if(temp.equals("Button One")){ setBackground(Color.blue); repaint(); } else{ setBackground(Color.red); repaint(); } } } MultipleButtonListener MyListener; Button MyButton, MyOtherButton; } Event Handling Summary Summary of Steps for Using AWT Components: 1. Create instance of AWT source. 2. Add AWT component to layout manager. 3. Create instance of proper listener (implements interface). 4. Register listener with source. AWT Layout Managers AWT Basic Layout Managers: FlowLayout (Default of Applet) BorderLayout (Default of Frame and Dialog) GridLayout CardLayout GridBagLayout AWT Layout Managers - Flow Layout import java.awt.*; import java.awt.event.*; import java.applet.*; public class FlowLayoutExample extends Applet{ public void init(){ setLayout(new FlowLayout()); add(new Button("First")); add(new Button("Second")); add(new Button("Third")); add(new Button("Fourth")); add(new Button("Fifth")); } } AWT Layout Managers - BorderLayout import java.awt.*; import java.awt.event.*; import java.applet.*; public class BorderLayoutExample extends Applet{ public void init(){ setLayout(new BorderLayout()); add(new Button("North"), BorderLayout.NORTH); add(new Button("East"), BorderLayout.EAST); add(new Button("West"), BorderLayout.WEST); add(new Button("South"), BorderLayout.SOUTH); add(new Button("Center"), BorderLayout.CENTER); } } AWT Layout Managers - BorderLayout import java.awt.*; import java.awt.event.*; import java.applet.*; public class BorderLayoutExample extends Applet{ public void init(){ setLayout(new BorderLayout()); add(new Button("North"), BorderLayout.NORTH); add(new Button("Really Fat East Button"), BorderLayout.EAST); add(new Button("West"), BorderLayout.WEST); add(new Button("South"), BorderLayout.SOUTH); add(new Button("Center"), BorderLayout.CENTER); } } AWT Layout Managers - GridLayout import java.awt.*; import java.awt.event.*; import java.applet.*; public class GridLayoutExample extends Applet{ public void init(){ setLayout(new GridLayout(0,1)); add(new Button("First")); add(new Button("Second")); add(new Button("Third")); add(new Button("Fourth")); add(new Button("Fifth")); } } AWT Layout Managers - GridLayout (unspecified # of columns) import java.awt.*; import java.awt.event.*; import java.applet.*; public class GridLayoutExample2 extends Applet{ public void init(){ setLayout(new GridLayout(1,0)); add(new Button("First")); add(new Button("Second")); add(new Button("Third")); add(new Button("Fourth")); add(new Button("Fifth")); } } AWT Layout Managers - Nested Panels (Layout Managers) import java.applet.*; import java.awt.*; public class Calculator extends Applet { TextField screen; public void init () { this.setLayout(new GridLayout(3, 1, 3, 3)); Panel A1 = new Panel(); this.add(A1); Panel A2 = new Panel(); this.add(A2); Panel A3 = new Panel(); this.add(A3); A1.setLayout(new GridLayout(2, 1)); screen = new TextField(12); A1.add(screen); Panel B1 = new Panel(); B1.setLayout(new GridLayout(1, 4, 3, 3)); B1.add(new Button("C")); B1.add(new Button("=")); B1.add(new Button("/")); B1.add(new Button("*")); A1.add(B1); A2.setLayout(new GridLayout(2, A2.add(new Button("7")); A2.add(new Button("8")); A2.add(new Button("9")); A2.add(new Button("-")); A2.add(new Button("4")); A2.add(new Button("5")); A2.add(new Button("6")); A2.add(new Button("+")); A3.setLayout(new GridLayout(1, // 1, 2 and 0 Panel B2 = new Panel(); B2.setLayout(new GridLayout(2, // 1 and 2 Panel C1 = new Panel(); C1.setLayout(new GridLayout(1, C1.add(new Button("1")); C1.add(new Button("2")); B2.add(C1); B2.add(new Button("0")); // 3, . and = Panel B3 = new Panel(); B3.setLayout(new GridLayout(1, // 3 and . Panel C2 = new Panel(); C2.setLayout(new GridLayout(2, C2.add(new Button("3")); C2.add(new Button(".")); B3.add(C2); B3.add(new Button("=")); A3.add(B2); A3.add(B3); } } 4, 3, 3)); 2, 3, 3)); 1, 3, 3)); 2, 3, 3)); 2, 3, 3)); 1, 3, 3)); Lecture #6 Lecture 6 - More Regarding the AWT Components Interfaces Event Handling AWT Widgets Layout Managers Event Handling Event Handling - AWT Listener Interfaces Listener Interface Adapter Class Methods ActionListener none actionPerformed AdjustmentListener none adjustmentValueChanged componentHidden ComponentListener ComponentAdapter componentMoved componentResized componentShown ContainerListener ContainerAdapter FocusListener FocusAdapter ItemListener none componentAdded componentRemoved focusGained focusLost itemStateChanged keyPressed KeyListener KeyAdapter keyReleased keyTyped mouseClicked mouseEntered MouseListener MouseAdapter mouseExited mousePressed mouseReleased MouseMotionListener MouseMotionAdapter TextListener none mouseDragged mouseMoved textValueChanged windowActivated windowClosed windowClosing WindowListener WindowAdapter windowDeactivated windowDeiconified windowIconified windowOpened Event Sources - AWT Widgets Types of Events It Can Generate AWT Component Button action adjustment component container focus item key mouse X mouse motion X X X X X Canvas X X X X X Checkbox X X X X X X X X X text window CheckboxMenuItem Note: This is not a Component * X subclass! Choice X X Component X X X X X Container X X X X X X Dialog X X X X X X X Frame X X X X X X X Label X X X X X X X X X X X X X X X X X X X X X X List X X X MenuItem Note: This is not a Component X subclass! Panel X Scrollbar X X X ScrollPane X TextArea X X X X X X TextComponent X X X X X X X X X X X X X X X X TextField Window X X X X X AWT Hierarchy Event Handling Summary Summary of Steps for Using AWT Components: 1. Create instance of AWT source. 2. Add AWT component to layout manager. 3. Create instance of proper listener (implements interface). 4. Register listener with source. Button Demo import java.applet.*; import java.awt.*; import java.awt.event.*; public class ButtonDemo extends Applet { public void init() { MyImage = getImage(getCodeBase(), "duke.gif"); tracker = new MediaTracker(this); tracker.addImage(MyImage, 0); try{ tracker.waitForID(0); }catch(InterruptedException e){}; imageWidth = MyImage.getWidth(null); imageHeight = MyImage.getHeight(null); b = new Button("Image"); add(b); l = new Listener(); b.addActionListener(l); } public void paint(Graphics g) { super.paint(g); if(flag){ g.drawImage(MyImage, 200, 80, imageWidth,imageHeight,null); } } private class Listener implements ActionListener{ public void actionPerformed(ActionEvent e) { if (flag){ flag=false; }else{ flag =true; } repaint(); } } Listener l; Button b; boolean flag = false; Image MyImage; int imageWidth, imageHeight; MediaTracker tracker; } Choice Demo import import import import java.awt.*; java.awt.event.ItemListener; java.awt.event.ItemEvent; java.applet.Applet; public class ChoiceDemo extends Applet implements ItemListener { Choice choice; //pop-up list of choices Label label; public void init() { choice = new Choice(); choice.addItem("one"); choice.addItem("two"); choice.addItem("three"); choice.addItem("four"); choice.addItemListener(this); label = new Label(); setLabelText(choice.getSelectedIndex(), choice.getSelectedItem()); } //Add components to the Applet. add(choice); add(label); void setLabelText(int num, String text) { label.setText("Item #" + num + " selected. " + "Text = \"" + text + "\"."); } } public void itemStateChanged(ItemEvent e) { setLabelText(choice.getSelectedIndex(), choice.getSelectedItem()); } List & TextArea Demo import java.awt.*; import java.awt.event.*; import java.applet.Applet; public class ListDemo extends Applet implements ActionListener, ItemListener { TextArea output; List spanish, italian; String newline; public void init() { newline = System.getProperty("line.separator"); //Build first list, which allows multiple selections. spanish = new List(4, true); //prefer 4 items visible spanish.add("uno"); spanish.add("dos"); spanish.add("tres"); spanish.add("cuatro"); spanish.add("cinco"); spanish.add("seis"); spanish.add("siete"); spanish.addActionListener(this); spanish.addItemListener(this); //Build second list, which allows one selection at a time. italian = new List(); //Defaults to none visible, only one selectable italian.add("uno"); italian.add("due"); italian.add("tre"); italian.add("quattro"); italian.add("cinque"); italian.add("sei"); italian.add("sette"); italian.addActionListener(this); italian.addItemListener(this); setLayout(new BorderLayout()); output = new TextArea(10, 40); output.setEditable(false); add(output, BorderLayout.CENTER); add(spanish, BorderLayout.EAST); } add(italian, BorderLayout.WEST); public void actionPerformed(ActionEvent e) { List list = (List)(e.getSource()); String language = (list == spanish) ? "Spanish" : "Italian"; output.append("Action event occurred on \"" + list.getSelectedItem() + "\" in " + language + "." + newline); } public void itemStateChanged(ItemEvent e) { List list = (List)(e.getItemSelectable()); String language = (list == spanish) ? "Spanish" : "Italian"; int index = ((Integer)(e.getItem())).intValue(); if (e.getStateChange() == ItemEvent.SELECTED) { output.append("Select event occurred on item #" + index + " (\"" + list.getItem(index) + "\") in " + language + "." + newline); } else { //the item was deselected output.append("Deselect event occurred on item #" + index + " (\"" + list.getItem(index) + "\") in " + language + "." + newline); } } } TextField & TextArea Demo import java.awt.*; import java.awt.event.*; import java.applet.Applet; public class TextDemo extends Applet implements ActionListener { TextField textField; TextArea textArea; String newline; public void init() { textField = new TextField(20); textArea = new TextArea(5, 20); textArea.setEditable(false); setLayout(new BorderLayout()); add(textField, BorderLayout.NORTH); add(textArea, BorderLayout.CENTER); textField.addActionListener(this); newline = System.getProperty("line.separator"); } public void actionPerformed(ActionEvent evt) { String text = textField.getText(); textArea.append(text + newline); textField.selectAll(); } } Text Event Demo import java.applet.Applet; import java.awt.*; import java.awt.event.*; public class TextEventDemo extends Applet implements ActionListener { TextField textField; TextArea textArea; TextArea displayArea; public void init() { Button button = new Button("Clear"); button.addActionListener(this); textField = new TextField(20); textField.addActionListener(new MyTextActionListener()); textField.addTextListener(new MyTextListener("Text Field")); textArea = new TextArea(5, 20); textArea.addTextListener(new MyTextListener("Text Area")); displayArea = new TextArea(5, 20); displayArea.setEditable(false); setLayout(new BorderLayout()); Panel leftPanel = new Panel(); leftPanel.setLayout(new BorderLayout()); leftPanel.add("North", textField); leftPanel.add("Center", textArea); Panel gridPanel = new Panel(); gridPanel.setLayout(new GridLayout(1,0)); gridPanel.add(leftPanel); gridPanel.add(displayArea); add(gridPanel, BorderLayout.CENTER); add(button, BorderLayout.SOUTH); textField.requestFocus(); } class MyTextListener implements TextListener { String preface; String newline; public MyTextListener(String source) { newline = System.getProperty("line.separator"); preface = source + " text value changed." + newline + " First 10 characters: \""; } public void textValueChanged(TextEvent e) { TextComponent tc = (TextComponent)e.getSource(); String s = tc.getText(); try { s = s.substring(0, 10); } catch (StringIndexOutOfBoundsException ex) { } displayArea.append(preface + s + "\"" + newline); } } //Scroll down, unless the peer still needs to be created. if (displayArea.isValid()) { displayArea.setCaretPosition(java.lang.Integer.MAX_VALUE); } class MyTextActionListener implements ActionListener { /** Handle the text field Return. */ public void actionPerformed(ActionEvent e) { int selStart = textArea.getSelectionStart(); int selEnd = textArea.getSelectionEnd(); textArea.replaceRange(textField.getText(),selStart, selEnd); textField.selectAll(); } } } /** Handle button click. */ public void actionPerformed(ActionEvent e) { displayArea.setText(""); textField.requestFocus(); } ImageScroller Demo import java.awt.*; import java.applet.*; import java.net.URL; class ScrollableCanvas extends Canvas { Image image; public String imageFile = "OHWIR.jpg"; Dimension preferredSize = new Dimension(600, 320); Dimension minimumSize = new Dimension(10, 10); public void setImage(Image img) { image = img; } public Dimension getMinimumSize() { return minimumSize; } public Dimension getPreferredSize() { /* * If we didn't hard code the preferred size, * then we'd have to inform the scrollpane * when we got the real size data. */ return preferredSize; } } public void paint(Graphics g) { g.drawImage(image, 0, 0, getBackground(), this); } public class ImageScroller extends Applet { public void init() { ScrollableCanvas canvas = new ScrollableCanvas(); canvas.setImage(getImage(getCodeBase(),canvas.imageFile)); setLayout(new BorderLayout()); ScrollPane pane = new ScrollPane(); pane.add(canvas); add("Center", pane); } } MouseEvent Demo import import import import java.applet.Applet; java.awt.*; java.awt.event.MouseListener; java.awt.event.MouseEvent; public class MouseEventDemo extends Applet implements MouseListener { BlankArea blankArea; TextArea textArea; static final int maxInt = java.lang.Integer.MAX_VALUE; String newline; public void init() { setLayout(new GridLayout(0,1)); blankArea = new BlankArea(new Color(0.98f, 0.97f, 0.85f)); add(blankArea); textArea = new TextArea(5, 20); textArea.setEditable(false); add(textArea); //Register for mouse events on blankArea and applet (panel). blankArea.addMouseListener(this); addMouseListener(this); newline = System.getProperty("line.separator"); } public void mousePressed(MouseEvent e) { saySomething("Mouse pressed; # of clicks: " + e.getClickCount(), e); } public void mouseReleased(MouseEvent e) { saySomething("Mouse released; # of clicks: " + e.getClickCount(), e); } public void mouseEntered(MouseEvent e) { saySomething("Mouse entered", e); } public void mouseExited(MouseEvent e) { saySomething("Mouse exited", e); } public void mouseClicked(MouseEvent e) { saySomething("Mouse clicked (# of clicks: " + e.getClickCount() + ")", e); } } void saySomething(String eventDescription, MouseEvent e) { textArea.append(eventDescription + " detected on " + e.getComponent().getClass().getName() + newline); textArea.setCaretPosition(maxInt); //hack to scroll to bottom } BlankArea import java.awt.*; public class BlankArea extends Canvas { Dimension minSize = new Dimension(100, 100); public BlankArea(Color color) { setBackground(color); } public Dimension getMinimumSize() { return minSize; } public Dimension getPreferredSize() { return minSize; } public void paint(Graphics g) { Dimension size = getSize(); g.drawRect(0, 0, size.width - 1, size.height - 1); } } MouseMotionEvent Demo import import import import java.applet.Applet; java.awt.*; java.awt.event.MouseMotionListener; java.awt.event.MouseEvent; public class MouseMotionEventDemo extends Applet implements MouseMotionListener { BlankArea blankArea; TextArea textArea; static final int maxInt = java.lang.Integer.MAX_VALUE; String newline; public void init() { setLayout(new GridLayout(0,1)); blankArea = new BlankArea(new Color(0.98f, 0.97f, 0.85f)); add(blankArea); textArea = new TextArea(5, 20); textArea.setEditable(false); add(textArea); //Register for mouse events on blankArea and applet (panel). blankArea.addMouseMotionListener(this); addMouseMotionListener(this); newline = System.getProperty("line.separator"); } public void mouseMoved(MouseEvent e) { saySomething("Mouse moved; # of clicks: " + e.getClickCount(), e); } public void mouseDragged(MouseEvent e) { saySomething("Mouse dragged; # of clicks: " + e.getClickCount(), e); } void saySomething(String eventDescription, MouseEvent e) { textArea.append(eventDescription + " detected on " + e.getComponent().getClass().getName() + newline); textArea.setCaretPosition(maxInt); //hack to scroll to bottom } } MouseMotionEvent Demo (Draw) import java.applet.Applet; import java.awt.*; import java.awt.event.*; public class SimpleDraw extends Applet { protected int lastX=0, lastY=0; private class PositionRecorder extends MouseAdapter { public void mouseEntered(MouseEvent event) { record(event.getX(), event.getY()); } public void mousePressed(MouseEvent event) { record(event.getX(), event.getY()); } } private class LineDrawer extends MouseMotionAdapter { public void mouseDragged(MouseEvent event) { int x = event.getX(); int y = event.getY(); getGraphics().drawLine(lastX, lastY, x, y); record(x, y); } } public void init() { setBackground(Color.white); addMouseListener(new PositionRecorder()); addMouseMotionListener(new LineDrawer()); } protected void record(int x, int y) { lastX = x; lastY = y; } } Lecture 6 - Streams Character Streams - Unicode Byte Streams Source/Sink Streams v. Filter Streams Chaining Streams FileInputStream fin = new FileInputStream("employee.dat"); Chaining Streams File f = new File("employee.dat"); FileInputStream fin = new FileInputStream(f); Chaining Streams File f = new File("employee.dat"); FileInputStream fin = new FileInputStream(f); DataInputStream din = new DataInputStream(fin); double d = din.readDouble(); Chaining Streams DataInputStream din = new DataInputStream( new FileInputSream( new File("employee.dat"))); double d = din.readDouble(); Chaining Streams FileInputStream fin = new FileInputStream("employee.dat"); BufferedInputStream bis = new BufferedInputStream(fin); DataInputStream din = new DataInputStream(bis); double d = din.readDouble(); Chaining Streams DataInputStream din = new DataInputStream( new BufferedInputStream( new FileInputStream("employee.dat"))); double d = din.readDouble(); Chaining Streams PushbackInputStream pbis = new PushbackInputStream( new BufferedInputStream( new FileInputStream("employee.dat"))); byte b = pbis.read(); //gets next byte if (b != '<') pbis.unread(b); //double d = din.readDouble(); ** can't ** Chaining Streams DataInputStream dis = new DataInputStream( pbis = new PushbackInputStream( new BufferedInputStream( new FileInputStream("employee.dat")))); byte b = pbis.read(); //gets next byte if (b != '<') pbis.unread(b); double d = din.readDouble(); ** can do this ** Chaining Streams ZipInputStream zis = new ZipInputStream( new BufferedInputStream( new FileInputStream("employee.zip"))); ZipEntry entry; while((entry = zis.getNextEntry()) != null){ //do something like: entry.getName(); zis.closeEntry(); } double d = din.readDouble(); ** can't do this ** Chaining Streams ZipInputStream zis = new ZipInputStream( new FileInputStream("employee.zip")); BufferedReader br = new BufferedReader( new InputStreamReader(zis)); //switched to Unicode String s; while ((s = br.readLine()) != null){ // do something with s } double d = din.readDouble(); ** can't do this ** Chaining Streams - Text InputStreamReader isr = new InputStreamReader(System.in); ... InputStreamReader fisr = new InputStreamReader( new FileInputStream("somefile.dat")); //assumes ISO Latin-1 //or InputStreamReader fisr = new InputStreamReader( new FileInputStream("somefile.dat"), "8859_5"); //ISO Latin/Cyrillic Chaining Streams - Text FileWriter fw = new FileWriter("somefile.txt"); //equivalent to: OutputStreamWriter osw = new OutputStreamWriter( new FileOutputStream("somefile.txt")); Chaining Streams - Text PrintWriter pw = new PrintWriter( new FileWriter("somefile.txt")); pw.println("This will get written to the file."); // use is similar to System.out.println // println adds correct eol character for target // by System.getProperty("line.separator"); Chaining Streams - Text PrintWriter pw = new PrintWriter( new FileOutputStream("somefile.txt")); //PrintWriter(OutputStream) automatically inserts an OutputStreamWriter pw.println("This will get written to the file."); Chaining Streams - Text PrintWriter pw = new PrintWriter( new FileWriter("somefile.txt")); //PrintWriters are automatically buffered PrintWriter pw = new PrintWriter( new FileWriter("somefile.txt"), true); // autoflush Chaining Streams - Text // no analogous PrintReader BufferedReader br = new BufferedReader( new FileReader("somefile.txt"); String s; while ((s != br.readLine()) != null){ //do something } // readLine() returns null when no more input //FileReader automatically converts bytes to Unicode Chaining Streams - Text // no automatic conversion like FileReader - must use InputStreamReader BufferedReader br = new BufferedReader( new InputStreamReader(System.in)); BufferedReader br2 = new BufferedReader( new InputStreamReader(url.openStream())); String s; while ((s != br.readLine()) != null){ //do something } // readLine() returns null when no more input Chaining Streams - Text // no automatic conversion like FileReader - must use InputStreamReader BufferedReader br = new BufferedReader( new InputStreamReader(System.in)); BufferedReader br2 = new BufferedReader( new InputStreamReader(url.openStream())); String s = br.readLine(); double d = Double.parseDouble(br2); // must convert from String to other types // see StringTokenizer Chaining Streams - Objects! public class DataObject implements Serializable{ String message; public DataObject(){ message = null; } public void setMessage(String m){ message = m; } public String getMessage(){ return message; } } Chaining Streams - Object Serialization ObjectOutputStrea oos = new ObjectOutputStream( new FileOutputStream("somefile.dat")); DataObject dataobject = new DataObject(); dataobject.setMessage("Hello"); oos.writeObject(dataobject); ObjectInputStream ois = new ObjectInputStream( new FileInputStream("somefile.dat"); DataObject inobject = (DataObject)ois.readObject(); Chaining Streams - Object Serialization ObjectOutputStrea oos = new ObjectOutputStream( new FileOutputStream("somefile.dat")); DataObject dataobject = new DataObject(); dataobject.setMessage("Hello"); oos.writeObject(dataobject); ObjectInputStream ois = new ObjectInputStream( new FileInputStream("somefile.dat"); DataObject inobject = (DataObject)ois.readObject(); // in lieu of cast use Object and use getClass() Chaining Streams - Object Serialization ObjectOutputStrea oos = new ObjectOutputStream( new FileOutputStream("somefile.dat")); DataObject dataobject = new DataObject(); dataobject.setMessage("Hello"); oos.writeObject(dataobject); int n = 5; oos.writeInt(n); float f = 50.0; oos.writeFloat(); ObjectInputStream ois = new ObjectInputStream( new FileInputStream("somefile.dat"); DataObject inobject = (DataObject)ois.readObject(); int newN = oos.readInt(); float newf = oos.readFloat(); // ObjectStreams implement the DataInput/DataOutput interfaces // of course, sending a primitive inside an object is preferable String Tokenizer public void readData(BufferedReader in) throws IOException{ String s = in.readLine(); StringTokenizer t = new StringTokenizer(s, ","); String name = t.nextToken(); double salary = Double.parseDouble(t.nextToken()); int month = Integer.parseInt(t.nextToken()); ... } Random Access Streams Used with records all of which are the same size. Use seek(long) to position file pointer within file then read or write from that point. Lecture #7 Streams import java.io.*; class ReadKeys1 { public static void main (String args[]) { StringBuffer s = new StringBuffer(); char c; try { Reader in = new InputStreamReader(System.in); while ((c = (char)in.read()) != '\n') { s.append(c); } } catch (Exception e) { System.out.println("Error: " + e.toString()); } System.out.println(s); } } Streams Why int? Streams import java.io.*; class ReadKeys1b { public static void main (String args[]) { StringBuffer s = new StringBuffer(); int i; char c; try { Reader in = new InputStreamReader(System.in); while ((i = in.read()) != '\n') { System.out.println(""+i); c=(char)i; s.append(c); } } catch (Exception e) { System.out.println("Error: " + e.toString()); } System.out.println(s); } } Streams import java.io.*; class ReadKeys1b2 { public static void main (String args[]) { StringBuffer s = new StringBuffer(); int i; char c; try { Reader in = new InputStreamReader(System.in); while ((i = in.read()) != '\n') { System.out.println(""+ (char)i); c=(char)i; s.append(c); } } catch (Exception e) { System.out.println("Error: " + e.toString()); } System.out.println(s); } } Streams import java.io.*; class ReadKeys2 { public static void main (String args[]) { char buf[] = new char[80]; try { Reader in = new InputStreamReader(System.in); in.read(buf, 0, 80); } catch (Exception e) { System.out.println("Error: " + e.toString()); } String s = new String(buf); System.out.println(s); } } Streams import java.io.*; class ReadKeys3 { public static void main (String args[]) { char buf[] = new char[10]; try { Reader in = new InputStreamReader(System.in); in.read(buf, 0, 10); } catch (Exception e) { System.out.println("Error: " + e.toString()); } String s = new String(buf); System.out.println(s); } } Streams import java.io.*; class ReadFile { public static void main (String args[]) { char buf[] = new char[64]; try { Reader in = new FileReader("Grocery.txt"); in.read(buf, 0, 64); } catch (Exception e) { System.out.println("Error: " + e.toString()); } String s = new String(buf); System.out.println(s); } } Streams import java.io.*; class ReadFile2{ public static void main (String args[]) { StringBuffer buf = new StringBuffer(); FileReader in = null; int i; try { in = new FileReader("Grocery.txt"); while ((i = in.read()) != -1) buf.append((char)i); } catch (Exception e) { System.out.println("Error: " + e.toString()); } System.out.print(buf.toString()); if (in != null) { try{ in.close(); }catch(Exception e){ } } } } Streams import java.io.*; class ReadFile3{ public static void main (String args[]) { StringBuffer buf = new StringBuffer(); BufferedReader in = null; String line; try { in = new BufferedReader(new FileReader("Grocery.txt")); while ((line = in.readLine()) != null) System.out.println(line); } catch (Exception e) { System.out.println("Error: " + e.toString()); } if (in != null) { try{ in.close(); }catch(Exception e){ } } } } Streams import java.io.*; public class FileCopy { public static void main(String[] args) throws IOException { File inputFile = new File("test.txt"); File outputFile = new File("outagain.txt"); FileReader in = new FileReader(inputFile); FileWriter out = new FileWriter(outputFile); int c; while ((c = in.read()) != -1) out.write(c); in.close(); out.close(); } } Streams import java.io.*; public class FileCopy2 { public static void main(String[] args) throws IOException { File inputFile = new File("test.txt"); File outputFile = new File("outagain.txt"); BufferedReader in = new BufferedReader(new FileReader(inputFile)); PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(outputFile))); String line; while ((line = in.readLine()) != null) out.println(line); in.close(); out.close(); } } Streams import java.io.*; class WriteFile { public static void main (String args[]) { // Read the user input char buf[] = new char[64]; try { Reader in = new InputStreamReader(System.in); in.read(buf, 0, 64); } catch (Exception e) { System.out.println("Error: " + e.toString()); } // Output the data to a file try { Writer out = new FileWriter("Output.txt"); out.write(buf, 0, 64); out.flush(); out.close(); } catch (Exception e) { System.out.println("Error: " + e.toString()); } } } Streams import java.io.*; public class DataObject implements Serializable{ protected String message; public DataObject(){ message = null; } public void setMessage(String m){ message = m; } public String getMessage(){ return message; } } Streams import java.io.*; class ObjectFileWriter{ public static void main (String args[]) { ObjectOutputStream out = null; ObjectInputStream in = null; DataObject dataOutObject = new DataObject(); DataObject dataInObject = new DataObject(); dataOutObject.setMessage("This is the first message."); try { out = new ObjectOutputStream(new FileOutputStream("ObjectData.txt")); in = new ObjectInputStream(new FileInputStream("ObjectData.txt")); out.writeObject(dataOutObject); dataInObject = (DataObject)in.readObject(); System.out.println(dataInObject.getMessage()); out.close(); in.close(); } } } catch (Exception e) { System.out.println("Error: " + e.toString()); } Streams import java.io.*; class ObjectFileWriter2{ public static void main (String args[]) { ObjectOutputStream out= null; ObjectInputStream in = null; DataObject dataOutObject = new DataObject(); DataObject dataInObject = new DataObject(); for (int i = 0; i<5; i++) { dataOutObject.setMessage("This is message "+(i+1)); try { out = new ObjectOutputStream(new FileOutputStream("ObjectData.txt")); in = new ObjectInputStream(new FileInputStream("ObjectData.txt")); out.writeObject(dataOutObject); dataInObject = (DataObject)in.readObject(); System.out.println(dataInObject.getMessage()); } catch (Exception e) { System.out.println("Error: " + e.toString()); } } try{ out.close(); in.close(); }catch(Exception e){ } } } Streams import java.io.*; class ObjectFileWriter3{ public static void main (String args[]) { ObjectOutputStream out= null; ObjectInputStream in = null; DataObject dataOutObject = new DataObject(); DataObject dataInObject = new DataObject(); try { out = new ObjectOutputStream(new FileOutputStream("ObjectData.txt")); for (int i = 0; i<5; i++) { dataOutObject.setMessage("This is message "+(i+1)); out.writeObject(dataOutObject); out.reset(); } out.close(); } catch(Exception e){ System.out.println("Error: " + e.toString()); } try{ in = new ObjectInputStream(new FileInputStream("ObjectData.txt")); for (int j = 0; j<5; j++){ dataInObject = (DataObject)in.readObject(); System.out.println(dataInObject.getMessage()); } in.close(); } catch (Exception e) { System.out.println("Error: " + e.toString()); } } } Streams import java.io.*; import java.net.*; public class Reverse { public static void main(String[] args) throws Exception { if (args.length != 1) { System.err.println("Usage: java Reverse " + "string_to_reverse"); System.exit(1); } String stringToReverse = URLEncoder.encode(args[0]); URL url = new URL("http://java.sun.com/cgi-bin/backwards"); URLConnection connection = url.openConnection(); connection.setDoOutput(true); PrintWriter out = new PrintWriter(connection.getOutputStream()); out.println("string=" + stringToReverse); out.close(); BufferedReader in = new BufferedReader( new InputStreamReader( connection.getInputStream())); String inputLine; while ((inputLine = in.readLine()) != null) System.out.println(inputLine); in.close(); } } Swing What Are the JFC and Swing? JFC is short for Java Foundation Classes Swing is a subset of the JFC used to build graphical user interfaces (GUIs). Why is it called "Swing"? Swing Swing Components Include everything from buttons to split panes to tables. Lightweight 100% Java Non-peer based Pluggable Look & Feel Support View-Model-Controller Gives any program that uses Swing components a potentially wide choice of looks and feels, no matter what platform the program is running on. Swing import java.awt.*; import java.awt.event.*; import javax.swing.*; class PlafPanel extends JPanel implements ActionListener { public PlafPanel() { metalButton = new JButton("Metal"); motifButton = new JButton("Motif"); windowsButton = new JButton("Windows"); add(metalButton); add(motifButton); add(windowsButton); metalButton.addActionListener(this); motifButton.addActionListener(this); windowsButton.addActionListener(this); } public void actionPerformed(ActionEvent evt) { Object source = evt.getSource(); String plaf = ""; if (source == metalButton) plaf = "javax.swing.plaf.metal.MetalLookAndFeel"; else if (source == motifButton) plaf = "com.sun.java.swing.plaf.motif.MotifLookAndFeel"; else if (source == windowsButton) plaf = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel"; try { UIManager.setLookAndFeel(plaf); SwingUtilities.updateComponentTreeUI(this); } catch(Exception e) {} } private JButton metalButton; private JButton motifButton; private JButton windowsButton; } // End of PlafPanel class PlafFrame extends Jframe { public PlafFrame(){ setTitle("PlafTest"); setSize(300, 200); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } } ); Container contentPane = getContentPane(); contentPane.add(new PlafPanel()); } } public class PlafTest { public static void main(String[] args) { JFrame frame = new PlafFrame(); frame.show(); } } Swing Swing components have capabilities far beyond what the AWT components offer. For example: Swing buttons and labels can display images instead of or in addition to text. You can easily add or change the borders drawn around most Swing components. For example, it's easy to put a box around the outside of a container or label. You can easily change the behavior or appearance of a Swing component by either invoking methods on it or creating a subclass of it. Swing components don't have to be rectangular. For example, buttons can be round. Assistive technologies such as screen readers can easily get information from Swing components. For example, a tool can easily get the text that's displayed on a button or label. Swing Converting from AWT to Swing involves basically two steps: import javax.swing.*; prepend J's to AWT component names Hoever, when you convert AWT programs to Swing, you need to be aware of a few gotchas: Swing Caveats Don't mix Heavyweight and LightWeight components. Programs should not, as a rule, use "heavyweight" components alongside Swing components. Heavyweight components include all the ready-to-use AWT components (such as Menu and ScrollPane) and all components that inherit from the AWT Canvas and Panel classes. This restriction exists because when Swing components (and all other "lightweight" components) overlap with heavyweight components, the heavyweight component is always drawn on top. Swing Caveats Modify Swing components only in event handlers. Swing components aren't thread safe. If you modify a visible Swing component -- invoking its setText method, for example -- from anywhere but an event handler, then you need to take special steps to make the modification execute on the event dispatching thread. This isn't an issue for many Swing programs, since component-modifying code is typically in event handlers. Swing Caveats Swing component go in swing containers. The containment hierarchy for any window or applet that contains Swing components must have a Swing top-level container at the root of the hierarchy. For example, a main window should be implemented as a JFrame instance instead of as a Frame instance. Swing Caveats Add components to the layout manager of the content pane of the top level container. You don't add components directly to a top-level container such as a JFrame. Instead, you add components to a container (called the content pane) that is itself contained by the JFrame. Swing Although there are many packages in Swing, two are commonly used: javax.swing javax.swing.event Swing Importing Swing Packages The following line imports the main Swing package: import javax.swing.*; Most Swing programs also need to import the two main AWT packages: import java.awt.*; import java.awt.event.*; Swing Choosing the Look and Feel Swing allows you to specify which look and feel your program uses -- Java Look and Feel, Windows, CDE/Motif, and so on. SwingApplication specifies the look and feel with the following code: public static void main(String[] args) { try { UIManager.setLookAndFeel( UIManager.getCrossPlatformLookAndFeelClassName()); } catch (Exception e) { } new SwingApplication(); //Create and show the GUI. } Swing Setting Up the Top-Level Container Here is the code that sets up and shows a frame: public class SwingApplication ... { ... public SwingApplication() { //Create the top-level container. JFrame frame = new JFrame("SwingApplication"); //...create a JButton and a JLabel... //...add them to a JPanel... //Add the JPanel to the frame. frame.getContentPane().add(pane, BorderLayout.CENTER); //Finish setting up the frame, and show it. frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { em.exit(0); } }); frame.pack(); frame.setVisible(true); } ... } Swing Setting Up Buttons and Labels JButton button = new JButton("I'm a Swing button!"); button.setMnemonic('i'); button.addActionListener(this); ... private JLabel label; private static String labelPrefix = "Number of button clicks: "; private int numClicks = 0; ... label = new JLabel(labelPrefix + "0 "); ... label.setText(labelPrefix + numClicks); Swing Adding Components to Containers JPanel pane = new JPanel(); pane.setBorder(BorderFactory.createEmptyBorder(30, 30, 10, 30)); pane.setLayout(new GridLayout(0, 1)); pane.add(button); pane.add(label); Swing Adding Borders Around Components pane.setBorder(BorderFactory.createEmptyBorder(30, 30, 10, 30)); This border simply provides some empty space around the panel's contents -- 30 extra pixels on the top, left, and right, and 10 extra pixels on the bottom. Borders are a feature that JPanel inherits from the JComponent class. Swing import javax.swing.*; //This is the final package name. //import com.sun.java.swing.*; //Used by JDK 1.2 Beta 4 and all //Swing releases before Swing 1.1 Beta 3. import java.awt.*; public class HelloSwingApplet extends JApplet { // This is a hack to avoid an ugly error message in 1.1. public HelloSwingApplet() { getRootPane().putClientProperty("defeatSystemEventQueueCheck", Boolean.TRUE); } public void init() { JLabel label = new JLabel("You are successfully running a Swing applet!"); label.setHorizontalAlignment(JLabel.CENTER); } } //Add border. Should use createLineBorder, but then the bottom //and left lines don't appear -- seems to be an off-by-one error. label.setBorder(BorderFactory.createMatteBorder(1,1,2,2,Color.black)); getContentPane().add(label, BorderLayout.CENTER); Swing import import import import javax.swing.*; java.awt.*; java.awt.event.*; java.net.URL; public class AppletDemo extends Japplet implements ActionListener { protected JButton b1, b2, b3; protected static final String DISABLE = "disable"; protected static final String ENABLE = "enable"; protected String leftButtonFilename = "images/right.gif"; protected String middleButtonFilename = "images/middle.gif"; protected String rightButtonFilename = "images/left.gif"; private boolean inAnApplet = true; URL codeBase; //used for applet version only //Hack to avoid ugly message about system event access check. public AppletDemo() { this(true); } public AppletDemo(boolean inAnApplet) { this.inAnApplet = inAnApplet; if (inAnApplet) { getRootPane().putClientProperty("defeatSystemEventQueueCheck", Boolean.TRUE); } } public void init() { setContentPane(makeContentPane()); } public Container makeContentPane() { ImageIcon leftButtonIcon; ImageIcon middleButtonIcon; ImageIcon rightButtonIcon; if (inAnApplet) { URL leftButtonURL = getURL(leftButtonFilename); URL middleButtonURL = getURL(middleButtonFilename); URL rightButtonURL = getURL(rightButtonFilename); leftButtonIcon = new ImageIcon(leftButtonURL); middleButtonIcon = new ImageIcon(middleButtonURL); rightButtonIcon = new ImageIcon(rightButtonURL); } else { leftButtonIcon = new ImageIcon(leftButtonFilename); middleButtonIcon = new ImageIcon(middleButtonFilename); rightButtonIcon = new ImageIcon(rightButtonFilename); } b1 = new JButton("Disable middle button", leftButtonIcon); b1.setVerticalTextPosition(AbstractButton.CENTER); b1.setHorizontalTextPosition(AbstractButton.LEFT); b1.setMnemonic(KeyEvent.VK_D); b1.setActionCommand(DISABLE); b2 = new JButton("Middle button", middleButtonIcon); b2.setVerticalTextPosition(AbstractButton.BOTTOM); b2.setHorizontalTextPosition(AbstractButton.CENTER); b2.setMnemonic(KeyEvent.VK_M); b3 = new JButton("Enable middle button", rightButtonIcon); //Use the default text position of CENTER, RIGHT. b3.setMnemonic(KeyEvent.VK_E); b3.setActionCommand(ENABLE); b3.setEnabled(false); //Listen for actions on buttons 1 and 3. b1.addActionListener(this); b3.addActionListener(this); b1.setToolTipText("Click this button to disable the middle button."); b2.setToolTipText("This middle button does nothing when you click it."); b3.setToolTipText("Click this button to enable the middle button."); //Add Components to a JPanel, using the default FlowLayout. JPanel pane = new JPanel(); pane.add(b1); pane.add(b2); pane.add(b3); pane.setBackground(new Color(255,255,204)); pane.setBorder(BorderFactory.createMatteBorder(1,1,2,2,Color.black)); return pane; } public void actionPerformed(ActionEvent e) { if (e.getActionCommand().equals(DISABLE)) { b2.setEnabled(false); b1.setEnabled(false); b3.setEnabled(true); } else { b2.setEnabled(true); b1.setEnabled(true); b3.setEnabled(false); } } /* One day, JApplet will make this method obsolete. */ protected URL getURL(String filename) { URL url = null; if (codeBase == null) { codeBase = getCodeBase(); } try { url = new URL(codeBase, filename); } catch (java.net.MalformedURLException e) { System.out.println("Couldn't create image: badly specified URL"); return null; } } return url; public static void main(String[] args) { JFrame frame = new JFrame("Application version: AppletDemo"); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); } AppletDemo applet = new AppletDemo(false); frame.setContentPane(applet.makeContentPane()); frame.pack(); frame.setVisible(true); } Swing import javax.swing.*; import import import import import java.awt.GridBagLayout; java.awt.GridBagConstraints; java.awt.Insets; java.awt.Dimension; java.awt.Color; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; public class MultiListener extends JApplet implements ActionListener { JTextArea topTextArea; JTextArea bottomTextArea; JButton button1, button2; final static String newline = "\n"; public void init() { JLabel l = null; GridBagLayout gridbag = new GridBagLayout(); GridBagConstraints c = new GridBagConstraints(); JPanel contentPane = new JPanel(); contentPane.setLayout(gridbag); contentPane.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createMatteBorder( 1,1,2,2,Color.black), BorderFactory.createEmptyBorder(5,5,5,5))); c.fill = GridBagConstraints.BOTH; c.gridwidth = GridBagConstraints.REMAINDER; l = new JLabel("What MultiListener hears:"); gridbag.setConstraints(l, c); contentPane.add(l); c.weighty = 1.0; topTextArea = new JTextArea(); topTextArea.setEditable(false); JScrollPane topScrollPane = new JScrollPane(topTextArea); Dimension preferredSize = new Dimension(200, 75); topScrollPane.setPreferredSize(preferredSize); gridbag.setConstraints(topScrollPane, c); contentPane.add(topScrollPane); c.weightx = 0.0; c.weighty = 0.0; l = new JLabel("What Eavesdropper hears:"); gridbag.setConstraints(l, c); contentPane.add(l); c.weighty = 1.0; bottomTextArea = new JTextArea(); bottomTextArea.setEditable(false); JScrollPane bottomScrollPane = new JScrollPane(bottomTextArea); bottomScrollPane.setPreferredSize(preferredSize); gridbag.setConstraints(bottomScrollPane, c); contentPane.add(bottomScrollPane); c.weightx = 1.0; c.weighty = 0.0; c.gridwidth = 1; c.insets = new Insets(10, 10, 0, 10); button1 = new JButton("Blah blah blah"); gridbag.setConstraints(button1, c); contentPane.add(button1); c.gridwidth = GridBagConstraints.REMAINDER; button2 = new JButton("You don't say!"); gridbag.setConstraints(button2, c); contentPane.add(button2); button1.addActionListener(this); button2.addActionListener(this); button2.addActionListener(new Eavesdropper(bottomTextArea)); setContentPane(contentPane); } } public void actionPerformed(ActionEvent e) { topTextArea.append(e.getActionCommand() + newline); } class Eavesdropper implements ActionListener { JTextArea myTextArea; public Eavesdropper(JTextArea ta) { myTextArea = ta; } public void actionPerformed(ActionEvent e) { myTextArea.append(e.getActionCommand()+ MultiListener.newline); } } Swing import javax.swing.*; import import import import import java.awt.GridBagLayout; java.awt.GridBagConstraints; java.awt.Insets; java.awt.Color; java.awt.Dimension; import java.awt.event.MouseListener; import java.awt.event.MouseEvent; public class MouseEventDemo extends JApplet implements MouseListener { BlankArea blankArea; JTextArea textArea; final static String newline = "\n"; public void init() { GridBagLayout gridbag = new GridBagLayout(); GridBagConstraints c = new GridBagConstraints(); JPanel contentPane = new JPanel(); contentPane.setLayout(gridbag); c.fill = GridBagConstraints.BOTH; c.gridwidth = GridBagConstraints.REMAINDER; c.weightx = 1.0; c.weighty = 1.0; c.insets = new Insets(1, 1, 1, 1); blankArea = new BlankArea(new Color(0.98f, 0.97f, 0.85f)); gridbag.setConstraints(blankArea, c); contentPane.add(blankArea); c.insets = new Insets(0, 0, 0, 0); textArea = new JTextArea(); textArea.setEditable(false); JScrollPane scrollPane = new JScrollPane(textArea); scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); scrollPane.setPreferredSize(new Dimension(200, 75)); gridbag.setConstraints(scrollPane, c); contentPane.add(scrollPane); //Register for mouse events on blankArea and applet. blankArea.addMouseListener(this); addMouseListener(this); setContentPane(contentPane); } public void mousePressed(MouseEvent e) { saySomething("Mouse pressed (# of clicks: " + e.getClickCount() + ")", e); } public void mouseReleased(MouseEvent e) { saySomething("Mouse released (# of clicks: " + e.getClickCount() + ")", e); } public void mouseEntered(MouseEvent e) { saySomething("Mouse entered", e); } public void mouseExited(MouseEvent e) { saySomething("Mouse exited", e); } public void mouseClicked(MouseEvent e) { saySomething("Mouse clicked (# of clicks: " + e.getClickCount() + ")", e); } void saySomething(String eventDescription, MouseEvent e) { textArea.append(eventDescription + " detected on " + e.getComponent().getClass().getName() + "." + newline); } } Lecture #8 Threads Thread of execution = forked process at sub-process level (forked sub-process) shared data segment = less overhead certain real time applications o but beware garbage collection CGI v. Servlets Threads Threads Threads are created in one of two ways: 1. extend the Thread class i.e., class MyThread class extends Thread 2. implement the Runnable interface i.e., class MyThread extends SomeOtherClass implements Runnable Threads Run is the "main" of a thread void run() { . . . . } Threads Run is invoked by calling the start() method of the thread t.start(); Threads 1. adjusting priority MIN_PRIORITY NORM_PRIORITY MAX_PRIORITY 2. putting them to sleep Threads Preemptive Multithreading v. Cooperative Multithreading Threads Example Extending Thread class MyThreadClass extends Thread { public MyThreadClass(String NameOfThread) { super(NameOfThread) //typically, thread would be started from outside } } public void run() { // do something (while (t !=null)) try{ sleep(50); }catch(InterruptedException ie){ System.out.println("Problem: " + ie); } } //some Listener would set (t =null;) public class MyThreadTest { public static void main(String[] args) { t = new MyThreadClass("Test"); t.start(); } MyThreadClass t; } Threads Example Implementing Runnable class MyThreadClass extends Applet implements Runnable { public void init() { t = new Thread(this, "Test"); } public void start() { t.start(); } void run() { // do something (while (t !=null)) try{ Thread.sleep(50); }catch(InterruptedException ie){ System.out.println("Problem: " + ie); } } public void stop() { t = null; } } Thread t; Threads Monitor o Synchronized o Queue o wait-notify o wait-notifyAll Threads Threads Threads Threads Threads Threads Threads Threads Threads Threads class MainIsRunInAThread { public static void main(String[] args) { // main() is run in a single thread System.out.println(Thread.currentThread()); for (int i=0; i<10; i++) { System.out.println("i == " + i); } } } Threads public class SimpleThread extends Thread { public SimpleThread(String str) { super(str); } public void run() { for (int i = 0; i < 10; i++) { System.out.println(i + " " + getName()); try { sleep((int)(Math.random() * 1000)); } catch (InterruptedException e) {} } System.out.println("DONE! " + getName()); } } Threads public class SimpleThread extends Thread { public SimpleThread(String str) { super(str); } public void run() { for (int i = 0; i < 10; i++) { System.out.println(i + " " + getName()); try { sleep((int)(Math.random() * 1000)); } catch (InterruptedException e) {} } System.out.println("DONE! " + getName()); } } public class TwoThreadsTest { public static void main (String[] args) { new SimpleThread("Jamaica").start(); new SimpleThread("Fiji").start(); } } Threads public class SimpleThread extends Thread { public SimpleThread(String str) { super(str); } public void run() { for (int i = 0; i < 10; i++) { System.out.println(i + " " + getName()); try { sleep((int)(Math.random() * 1000)); } catch (InterruptedException e) {} } System.out.println("DONE! " + getName()); } } public class ThreeThreadsTest { public static void main (String[] args) { new SimpleThread("Jamaica").start(); new SimpleThread("Fiji").start(); new SimpleThread("Bora Bora").start(); } } Threads import java.awt.Graphics; import java.util.*; import java.text.DateFormat; public class Clock extends java.applet.Applet implements Runnable { private Thread clockThread = null; public void start() { if (clockThread == null) { clockThread = new Thread(this, "Clock"); clockThread.start(); } } public void run() { Thread myThread = Thread.currentThread(); while (clockThread == myThread) { repaint(); try { Thread.sleep(1000); } catch (InterruptedException e){ } } } public void paint(Graphics g) { Calendar cal = Calendar.getInstance(); Date date = cal.getTime(); DateFormat dateFormatter = DateFormat.getTimeInstance(); g.drawString(dateFormatter.format(date), 5, 10); } } public void stop() { clockThread = null;} Threads import java.awt.*; import java.awt.event.*; import java.applet.*; public class BounceApplet extends Applet { public void init() { setLayout(new BorderLayout()); canvas = new Canvas(); add(canvas, "Center"); Panel p = new Panel(); addButton(p, "Start", new ActionListener() { public void actionPerformed(ActionEvent evt){ canvas.setVisible(true); Ball b = new Ball(canvas); b.bounce(); } }); } addButton(p, "Stop", new ActionListener() { public void actionPerformed(ActionEvent evt) { canvas.setVisible(false); } }); add(p, "South"); public void addButton(Container c, String title, ActionListener a) { Button b = new Button(title); c.add(b); b.addActionListener(a); } private Canvas canvas; } class Ball { public Ball(Canvas c) { box = c; } public void draw() { Graphics g = box.getGraphics(); g.fillOval(x, y, XSIZE, YSIZE); g.dispose(); } public void move() { Graphics g = box.getGraphics(); g.setXORMode(box.getBackground()); g.fillOval(x, y, XSIZE, YSIZE); x += dx; y += dy; Dimension d = box.getSize(); if (x < 0) { x = 0; dx = -dx; } if (x + XSIZE >= d.width) { x = d.width - XSIZE; dx = -dx; } if (y < 0) { y = 0; dy = -dy; } if (y + YSIZE >= d.height) { y = d.height - YSIZE; dy = -dy; } g.fillOval(x, y, XSIZE, YSIZE); g.dispose(); } public void bounce() { draw(); for (int i = 1; i <= 1000; i++) { if(!box.isVisible()) i=1000; move(); try { Thread.sleep(5); } catch(InterruptedException e) {} } } private private private private private private private Canvas box; static final int XSIZE = 10; static final int YSIZE = 10; int x = 0; int y = 0; int dx = 2; int dy = 2; } Threads import java.awt.*; import java.awt.event.*; import java.applet.*; public class BounceThreadApplet extends Applet { public void init() { setLayout(new BorderLayout()); canvas = new Canvas(); add(canvas, "Center"); Panel p = new Panel(); addButton(p, "Start", new ActionListener() { public void actionPerformed(ActionEvent evt) { canvas.setVisible(true); Ball b = new Ball(canvas); b.start(); } }); } addButton(p, "Stop", new ActionListener(){ public void actionPerformed(ActionEvent evt) { canvas.setVisible(false); //System.exit(0); //repaint(); } }); add(p, "South"); public void addButton(Container c, String title, ActionListener a) { Button b = new Button(title); c.add(b); b.addActionListener(a); } private Canvas canvas; } class Ball extends Thread { public Ball(Canvas c) { box = c; } public void draw() { Graphics g = box.getGraphics(); g.fillOval(x, y, XSIZE, YSIZE); g.dispose(); } public void move() { if (!box.isVisible()) return; Graphics g = box.getGraphics(); g.setXORMode(box.getBackground()); g.fillOval(x, y, XSIZE, YSIZE); x += dx; y += dy; Dimension d = box.getSize(); if (x < 0) { x = 0; dx = -dx; } if (x + XSIZE >= d.width) { x = d.width - XSIZE; dx = -dx; } if (y < 0) { y = 0; dy = -dy; } if (y + YSIZE >= d.height) { y = d.height - YSIZE; dy = -dy; } g.fillOval(x, y, XSIZE, YSIZE); g.dispose(); } public void run() { draw(); for (int i = 1; i <= 1000; i++) { if(!box.isVisible()) i=1000; move(); try { Thread.sleep(5); } catch(InterruptedException e) {} } } private private private private private private private Canvas box; static final int XSIZE = 10; static final int YSIZE = 10; int x = 0; int y = 0; int dx = 2; int dy = 2; } Threads import java.awt.*; import java.awt.event.*; import java.applet.*; public class BounceExpressApplet extends Applet { public void init() { setLayout(new BorderLayout()); canvas = new Canvas(); add(canvas, "Center"); Panel p = new Panel(); addButton(p, "Start", new ActionListener() { public void actionPerformed(ActionEvent evt) { canvas.setVisible(true); Ball b = new Ball(canvas, Color.black); b.setPriority(Thread.MIN_PRIORITY); b.start(); } }); addButton(p, "Express", new ActionListener() { public void actionPerformed(ActionEvent evt) { canvas.setVisible(true); Ball b = new Ball(canvas, Color.red); b.setPriority(Thread.MAX_PRIORITY); b.start(); } }); addButton(p, "Stop", new ActionListener() { public void actionPerformed(ActionEvent evt) { canvas.setVisible(false); //System.exit(0); } } }); add(p, "South"); public void addButton(Container c, String title, ActionListener a) { Button b = new Button(title); c.add(b); b.addActionListener(a); } private Canvas canvas; } class Ball extends Thread { public Ball(Canvas c, Color co) { box = c; color = co; } public void draw() { Graphics g = box.getGraphics(); g.setColor(color); g.fillOval(x, y, XSIZE, YSIZE); g.dispose(); } public void move() { if (!box.isVisible()) return; Graphics g = box.getGraphics(); g.setColor(color); g.setXORMode(box.getBackground()); g.fillOval(x, y, XSIZE, YSIZE); x += dx; y += dy; Dimension d = box.getSize(); if (x < 0) { x = 0; dx = -dx; } if (x + XSIZE >= d.width) { x = d.width - XSIZE; dx = -dx; } if (y < 0) { y = 0; dy = -dy; } if (y + YSIZE >= d.height) { y = d.height - YSIZE; dy = -dy; } g.fillOval(x, y, XSIZE, YSIZE); g.dispose(); } public void run() { draw(); for (int i = 1; i <= 1000; i++) { if(!box.isVisible()) i=1000; move(); try { Thread.sleep(5); } catch(InterruptedException e) {} } } private private private private private private private private Canvas box; static final int XSIZE = 10; static final int YSIZE = 10; int x = 0; int y = 0; int dx = 2; int dy = 2; Color color; } Threads import import import import java.awt.*; java.awt.event.*; java.util.*; java.applet.*; public class BounceSelfishApplet extends Applet { public void init() { setLayout(new BorderLayout()); canvas = new Canvas(); add(canvas, "Center"); Panel p = new Panel(); addButton(p, "Normal", new ActionListener() { public void actionPerformed(ActionEvent evt) { canvas.setVisible(true); Ball b = new Ball(canvas, Color.black); b.setPriority(Thread.MIN_PRIORITY); b.start(); } }); addButton(p, "Express", new ActionListener() { public void actionPerformed(ActionEvent evt) { canvas.setVisible(true); Ball b = new Ball(canvas, Color.red); b.setPriority(Thread.MAX_PRIORITY); b.start(); } }); addButton(p, "Selfish", new ActionListener() { public void actionPerformed(ActionEvent evt) { canvas.setVisible(true); Ball b = new SelfishBall(canvas, Color.blue); b.setPriority(Thread.MAX_PRIORITY); b.start(); } }); addButton(p, "Stop", new ActionListener(){ public void actionPerformed(ActionEvent evt) { canvas.setVisible(false); //System.exit(0); } }); add(p, "South"); } public void addButton(Container c, String title, ActionListener a) { Button b = new Button(title); c.add(b); b.addActionListener(a); } } protected Canvas canvas; class Ball extends Thread { public Ball(Canvas c, Color co) { box = c; color = co; } public void draw() { Graphics g = box.getGraphics(); g.setColor(color); g.fillOval(x, y, XSIZE, YSIZE); g.dispose(); } public void move() { if (!box.isVisible()) return; Graphics g = box.getGraphics(); g.setColor(color); g.setXORMode(box.getBackground()); g.fillOval(x, y, XSIZE, YSIZE); x += dx; y += dy; Dimension d = box.getSize(); if (x < 0) { x = 0; dx = -dx; } if (x + XSIZE >= d.width) { x = d.width - XSIZE; dx = -dx; } if (y < 0) { y = 0; dy = -dy; } if (y + YSIZE >= d.height) { y = d.height - YSIZE; dy = -dy; } g.fillOval(x, y, XSIZE, YSIZE); g.dispose(); } public void run() { draw(); for (int i = 1; i <= 1000; i++) { if(!box.isVisible()) i=1000; move(); try { Thread.sleep(5); } catch(InterruptedException e) {} } } } private private private private private private private private Canvas box; static final int XSIZE = 10; static final int YSIZE = 10; int x = 0; int y = 0; int dx = 2; int dy = 2; Color color; class SelfishBall extends Ball { public SelfishBall(Canvas c, Color co) { super(c, co); box=c; } } public void run() { draw(); for (int i = 1; i <= 1000; i++) { if(!box.isVisible()) i=1000; move(); long t = System.currentTimeMillis(); while (System.currentTimeMillis() < t + 5); } } Canvas box; Threads class UnsynchBankTest { public static void main(String[] args) { Bank b = new Bank(); int i; for (i = 1; i <= Bank.NACCOUNTS; i++) new TransactionSource(b, i).start(); } } class Bank { public Bank() { accounts = new long[NACCOUNTS]; int i; for (i = 0; i < NACCOUNTS; i++) accounts[i] = INITIAL_BALANCE; ntransacts = 0; test(); } public void transfer(int from, int to, int amount) { while (accounts[from] < amount) { try { Thread.sleep(5); } catch(InterruptedException e) {} } } accounts[from] -= amount; accounts[to] += amount; ntransacts++; if (ntransacts % 5000 == 0) test(); public void test() { int i; long sum = 0; for (i = 0; i < NACCOUNTS; i++) sum += accounts[i]; System.out.println("Transactions:" + ntransacts + " Sum: " + sum); } } public static final int INITIAL_BALANCE = 10000; public static final int NACCOUNTS = 10; private long[] accounts; private int ntransacts; class TransactionSource extends Thread { public TransactionSource(Bank b, int i) { from = i - 1; bank = b; } public void run() { while (true) { int to = (int)(Bank.NACCOUNTS * Math.random()); if (to == from) to = (to + 1) % Bank.NACCOUNTS; int amount = (int)(Bank.INITIAL_BALANCE * Math.random()); bank.transfer(from, to, amount); try { sleep(1); } catch(InterruptedException e) {} } } private Bank bank; private int from; } Threads class SynchBankTest { public static void main(String[] args) { Bank b = new Bank(); int i; for (i = 1; i <= Bank.NACCOUNTS; i++) new TransactionSource(b, i).start(); } } class Bank { public Bank() { accounts = new long[NACCOUNTS]; int i; for (i = 0; i < NACCOUNTS; i++) accounts[i] = INITIAL_BALANCE; ntransacts = 0; test(); } public synchronized void transfer(int from, int to, int amount) { while (accounts[from] < amount) { try { wait(); } catch(InterruptedException e) {} } accounts[from] -= amount; accounts[to] += amount; ntransacts++; if (ntransacts % 5000 == 0) test(); notifyAll(); } public void test() { int i; long sum = 0; for (i = 0; i < NACCOUNTS; i++) sum += accounts[i]; System.out.println("Transactions:" + ntransacts + " Sum: " + sum); } public static final int INITIAL_BALANCE = 10000; public static final int NACCOUNTS = 10; private long[] accounts; private int ntransacts; } class TransactionSource extends Thread { public TransactionSource(Bank b, int i) { from = i - 1; bank = b; } public void run() { while (true) { int to = (int)(Bank.NACCOUNTS * Math.random()); if (to == from) to = (to + 1) % Bank.NACCOUNTS; int amount = (int)(Bank.INITIAL_BALANCE * Math.random()); bank.transfer(from, to, amount); try { sleep(1); } catch(InterruptedException e) {} } } private Bank bank; private int from; } Threads import java.awt.*; import java.util.*; import java.applet.*; public class TimerTestApplet extends Applet { public void init() { setLayout(new GridLayout(2, 3)); } add(new add(new add(new add(new add(new add(new ClockCanvas("San Jose", 16)); ClockCanvas("Taipei", 8)); ClockCanvas("Berlin", 1)); ClockCanvas("New York", 19)); ClockCanvas("Cairo", 2)); ClockCanvas("Bombay", 5)); } interface Timed { public void tick(Timer t); } class Timer extends Thread { public Timer(Timed t, int i) { target = t; interval = i; setDaemon(true); } public void run() { while (true) { try { sleep(interval); } catch(InterruptedException e) {} target.tick(this); } } private Timed target; private int interval; } class ClockCanvas extends Canvas implements Timed { public ClockCanvas(String c, int off) { city = c; offset = off; new Timer(this, 1000).start(); setSize(150, 150); } public void paint(Graphics g) { g.drawOval(20, 10, 100, 100); double hourAngle = 2 * Math.PI * (seconds - 3 * 60 * 60) / (12 * 60 * 60); double minuteAngle = 2 * Math.PI * (seconds - 15 * 60) / (60 * 60); double secondAngle = 2 * Math.PI * (seconds - 15) / 60; g.drawLine(70, 60, 70 + (int)(30 * Math.cos(hourAngle)), 60 + (int)(30 * Math.sin(hourAngle))); g.drawLine(70, 60, 70 + (int)(40 * Math.cos(minuteAngle)), 60 + (int)(40 * Math.sin(minuteAngle))); g.drawLine(70, 60, 70 + (int)(45 * Math.cos(secondAngle)), 60 + (int)(45 * Math.sin(secondAngle))); g.drawString(city, 0, 115); } public void tick(Timer t) { GregorianCalendar d = new GregorianCalendar(); seconds = (d.get(Calendar.HOUR) - LOCAL + offset) * 60 * 60 + d.get(Calendar.MINUTE) * 60 + d.get(Calendar.SECOND); repaint(); } } private private private private int seconds = 0; String city; int offset; final int LOCAL = 16; Threads import java.awt.*; import java.awt.image.*; import java.awt.event.*; import java.applet.*; import java.net.*; public class Animation extends Applet implements Runnable { public void start() { if (runner == null) { runner = new Thread(this); runner.start(); } } public void stop() { if (runner != null && runner.isAlive()) runner.stop(); runner = null; } public void init() { addMouseListener(new MouseAdapter(){ public void mouseClicked(MouseEvent evt) { toggleAnimation(); } }); try { imageName = getParameter("imagename"); if (imageName == null) imageName = ""; imageCount = 1; String param = getParameter("imagecount"); if (param != null) imageCount = Integer.parseInt(param); } } catch (Exception e) { showStatus("Error: " + e); } public synchronized void loadImage() { if (loaded) return; try { URL url = new URL(getDocumentBase(), imageName); showStatus("Loading " + imageName); image = getImage(url); prepareImage(image, this); } catch(Exception e) { showStatus("Error: " + e); } while (!loaded) } try { wait(); } catch (InterruptedException e) {} resize(imageWidth, imageHeight / imageCount); public void run() { loadImage(); while (runner != null) { repaint(); try { Thread.sleep(200); } catch (InterruptedException e) {} current = (current + 1) % imageCount; } } public void paint(Graphics g) { if (!loaded) return; } g.drawImage(image, 0, - (imageHeight / imageCount) * current, null); public void update(Graphics g) { paint(g); } public void toggleAnimation() { if (loaded) { if (runner != null && runner.isAlive()) { if (stopped) { showStatus("Click to stop"); runner.resume(); } else { showStatus("Click to restart"); runner.suspend(); } stopped = !stopped; } else { stopped = false; current = 0; runner = new Thread(this); runner.start(); } } } public synchronized boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) { if ((infoflags & ImageObserver.ALLBITS) != 0) { // image is complete imageWidth = image.getWidth(null); imageHeight = image.getHeight(null); showStatus("Click to stop"); loaded = true; notify(); return false; } return true; // want more info } } private private private private private private private private private Image image; int imageCount; int imageWidth = 0; int imageHeight = 0; String imageName; Thread runner = null; int current = 0; boolean loaded = false; boolean stopped = false; Threads import java.awt.*; import java.awt.event.*; import java.applet.*; public class BallsApplet extends Applet { public void init() { setLayout(new BorderLayout()); BallsCanvas bc = new BallsCanvas(this); add("Center",bc); } class BallsCanvas extends Canvas implements Runnable { private int pause = 15; private Color backgroundColor = Color.white; private int ballCount = 15; private Color[] ballColor; private boolean ready = false; private Image image; private Thread looper; private Rectangle rectangle; private double a[] = new double[ballCount]; private double b[] = new double[ballCount]; private double sine[] = new double[ballCount]; private private private private private double cosine[] = new double[ballCount]; double angle[] = new double[ballCount]; int colorIndex[] = new int[ballCount]; int xCenter; int yCenter; BallsCanvas(BallsApplet p) { setSize(p.getSize().width,p.getSize().height); ballColor = new Color[4]; ballColor[0] = Color.blue; ballColor[1] = Color.cyan; ballColor[2] = Color.magenta; ballColor[3] = Color.red; rectangle = new Rectangle(); setBackground(backgroundColor); looper = new Thread(this); looper.start(); } // Constructor public void run() { try { while(true) { repaint(); try { Thread.sleep(pause); }catch(InterruptedException e) {} } // End of while } finally { return;} } Threads (Continue) public void update(Graphics g) { if(looper.isAlive()) { if(!rectangle.equals(getBounds()) || (image == null)) { rectangle = getBounds(); image = createImage(rectangle.width,rectangle.height); firstFrame(); } if(nextFrame()) { paint(image.getGraphics()); g.drawImage(image,0,0,null); } } } public void paint(Graphics g) { g.setColor(backgroundColor); g.fillRect(0,0,getSize().width,getSize().height); for(int i=0; i= ballColor.length) index = 0; } } // End of class BallsCanvas extends Canvas private boolean nextFrame() { } for(int i=0; i < ballCount; i++) { angle[i] += 5.0 / (a[i] + b[i]); cosine[i] = Math.cos(angle[i]); sine[i] = Math.sin(angle[i]); } return(true); }// End of boolean nextFrame() Lecture #9 Networking import java.net.*; import java.io.*; public class ParseURL { public static void main(String[] args) throws Exception { URL aURL = new URL("http://java.sun.com:80/docs/books/" + "tutorial/index.html#DOWNLOADING"); System.out.println("protocol = " + aURL.getProtocol()); System.out.println("host = " + aURL.getHost()); System.out.println("filename = " + aURL.getFile()); System.out.println("port = " + aURL.getPort()); System.out.println("ref = " + aURL.getRef()); } } output: protocol = http host = java.sun.com filename = /docs/books/tutorial/index.html port = 80 ref = DOWNLOADING Networking import java.net.*; import java.io.*; public class URLConnectionReader { public static void main(String[] args) throws Exception { URL yahoo = new URL("http://www.yahoo.com/"); URLConnection yc = yahoo.openConnection(); BufferedReader in = new BufferedReader( new InputStreamReader(yc.getInputStream())); String inputLine; while ((inputLine = in.readLine()) != null) System.out.println(inputLine); in.close(); } } Networking import import import import import import import java.awt.*; java.io.InputStreamReader; java.io.BufferedReader; java.io.IOException; java.net.URL; java.net.URLConnection; java.net.MalformedURLException; public class GetTest extends java.applet.Applet implements Runnable { URL theURL; Thread runner; TextArea ta; public void init() { setLayout(new GridLayout(1,1)); String url = getCodeBase() + "test.txt"; try { this.theURL = new URL(url); } catch ( MalformedURLException e) { System.out.println("Bad URL: " + theURL); } ta = new TextArea("Getting text..."); add(ta); } public Insets getInsets() { return new Insets(10,10,10,10); } public void start() { if (runner == null) { runner = new Thread(this); runner.start(); } } public void stop() { runner = null; } public void run() { URLConnection conn = null; BufferedReader data = null; String line; StringBuffer buf = new StringBuffer(); try { conn = this.theURL.openConnection(); conn.connect(); ta.setText("Connection opened..."); data = new BufferedReader(new InputStreamReader( conn.getInputStream())); ta.setText("Reading data..."); while ((line = data.readLine()) != null) { buf.append(line + "\n"); } ta.setText(buf.toString()); } catch (IOException e) { System.out.println("IO Error:" + e.getMessage()); } } } Networking import java.io.*; import java.net.*; public class Reverse { public static void main(String[] args) throws Exception { if (args.length != 1) { System.err.println("Usage: java Reverse " + "string_to_reverse"); System.exit(1); } String stringToReverse = URLEncoder.encode(args[0]); URL url = new URL("http://java.sun.com/cgi-bin/backwards"); URLConnection connection = url.openConnection(); connection.setDoOutput(true); PrintWriter out = new PrintWriter( connection.getOutputStream()); out.println("string=" + stringToReverse); out.close(); BufferedReader in = new BufferedReader( new InputStreamReader( connection.getInputStream())); String inputLine; while ((inputLine = in.readLine()) != null) System.out.println(inputLine); in.close(); } } Networking Networking Definition: TCP (Transmission Control Protocol) is a connection-based protocol that provides a reliable flow of data between two computers. Definition: UDP (User Datagram Protocol) is a protocol that sends independent packets of data, called datagrams, from one computer to another with no guarantees about arrival. UDP is not connection-based like TCP. Networking Definition: The TCP and UDP protocols use ports to map incoming data to a particular process running on a computer. In datagram-based communication such as UDP, the datagram packet contains the port number of its destination and UDP routes the packet to the appropriate application, as illustrated in this figure: Port numbers range from 0 to 65,535 because ports are represented by 16-bit numbers. The port numbers ranging from 0 - 1023 are restricted; they are reserved for use by well-known services such as HTTP and FTP and other system services. These ports are called well-known ports. Your applications should not attempt to bind to them. Networking Service Port Number FTP 21 Telnet 23 SMTP Mail 25 HTTP (Web) 80 POP3 Mail 110 News 119 Networking Host Port Protocol http://www.cis.njit.edu:80/~nichol/courses/cis786/ Networking Networking Click here to run a CGI program. Networking Hello.cpp source Networking Networking Welcome.java source Networking #!/bin/sh echo "Content-Type: text/plain" echo "" echo "" echo "Hello, world." Run a shell script as CGI Networking #!/bin/sh /opt/local/WWW/jdk1.2beta3/bin/java Welcome Run a shell script to launch a Java program Networking #!/bin/sh /opt/local/WWW/jdk1.2beta3/bin/java -DQUERY_STRING=$QUERY_STRING WelcomeV Run a shell script to launch a Java program with passed data Networking Sending GET Data to a Java CGI Program Enter some data: Enter some more: Send It Networking From Core Web Programming source code archive Your company name: Password (for later access): Usefulness Architecture Application (Choose One or More) (Choose One or More) (Choose One) Revolutionary Flexible Integrated Robust Object Oriented Modern Open Standards-Based Software Product (Choose One) Paradigm Start Toward Success Networking import java.io.*; import java.net.*; public class smtpClient { public static void main(String[] args) { // // // // declaration section: smtpClient: our client socket os: output stream is: input stream Socket smtpSocket = null; DataOutputStream os = null; //DataInputStream is = null; BufferedReader is = null; // Initialization section: // Try to open a socket on port 25 // Try to open input and output streams try { // smtpSocket = new Socket("homer.njit.edu", 25); os = new DataOutputStream(smtpSocket.getOutputStream()); is = new DataInputStream(smtpSocket.getInputStream()); is = new BufferedReader( new InputStreamReader(smtpSocket.getInputStream())); } catch (UnknownHostException e) { System.err.println("Don't know about host: hostname"); } catch (IOException e) { System.err.println("Couldn't get I/O for the connection to: hostname"); } // If everything has been initialized then we want to write some data // to the socket we have opened a connection to on port 25 if (smtpSocket != null && os != null && is != null) { try { // The capital string before each colon has a special meaning to SMTP // you may want to read the SMTP specification, RFC1822/3 os.writeBytes("HELO\n"); os.writeBytes("MAIL From: [email protected]\n"); os.writeBytes("RCPT To: [email protected]\n"); os.writeBytes("RCPT To: [email protected]\n"); os.writeBytes("DATA\n"); os.writeBytes("From: [email protected]\n"); os.writeBytes("Date: Today\n"); os.writeBytes("To: [email protected]\n"); os.writeBytes("Subject: testing\n"); os.writeBytes("Hi there.\n"); // message body os.writeBytes("From Homer using smtpClient.java\n"); os.writeBytes("\n.\n"); os.writeBytes("QUIT"); String responseLine; if((responseLine = is.readLine()) != null) System.out.println("Mailed: "+responseLine); // // // // clean up: close the output stream close the input stream close the socket os.close(); is.close(); smtpSocket.close(); } catch (UnknownHostException e) { System.err.println("Trying to connect to unknown host: " + e); } catch (IOException e) { System.err.println("IOException: " + e); }// End of try/catch } // End of if } // End of public static void main() } Networking import java.io.*; import java.net.*; public class EchoServer { public static void main(String[] args ) { try { ServerSocket s = new ServerSocket(8189); Socket incoming = s.accept( ); BufferedReader in = new BufferedReader (new InputStreamReader(incoming.getInputStream())); PrintWriter out = new PrintWriter (incoming.getOutputStream(), true /* autoFlush */); out.println( "Hello! Enter BYE to exit." ); boolean done = false; while (!done) { String str = in.readLine(); if (str == null) done = true; else { out.println("Echo: " + str); if (str.trim().equals("BYE")) done = true; } } incoming.close(); } catch (Exception e) { System.out.println(e);} } } Networking import java.io.*; import java.util.*; public class DataObject implements Serializable{ protected String message; DataObject(){ message = ""; } public String getMessage(){ return message; } public void setMessage(String inMessage){ message = inMessage; } } Networking import java.io.*; import java.net.*; public class Server{ public static void main(String[] arg){ DataObject myObject = null; try{ ServerSocket myServerSocket = new ServerSocket(3000); Socket incoming = myServerSocket.accept(); ObjectOutputStream myOutputStream = new ObjectOutputStream(incoming.getOutputStream()); ObjectInputStream myInputStream = new ObjectInputStream(incoming.getInputStream()); myObject = (DataObject)myInputStream.readObject(); System.out.println("Message received : " + myObject.getMessage()); myObject.setMessage("Got it!"); System.out.println("Message sent : " + myObject.getMessage()); myOutputStream.writeObject(myObject); myOutputStream.close(); myInputStream.close(); myServerSocket.close(); } catch(Exception e){ System.out.println(e); } } } Networking import java.io.*; import java.net.*; public class Client{ public static void main(String[] arg){ try{ DataObject myObject = new DataObject(); myObject.setMessage("Did you get this?"); System.out.println("Message sent : " + myObject.getMessage()); Socket socketToServer = new Socket("127.0.0.1", 3000); ObjectOutputStream myOutputStream = new ObjectOutputStream(socketToServer.getOutputStream()); ObjectInputStream myInputStream = new ObjectInputStream(socketToServer.getInputStream()); myOutputStream.writeObject(myObject); myObject = (DataObject)myInputStream.readObject(); System.out.println("Messaged received : " + myObject.getMessage()); myOutputStream.close(); myInputStream.close(); socketToServer.close(); } catch(Exception e){ System.out.println(e); } } } Networking import java.io.*; import java.net.*; public class ThreadedDataObjectServer { public static void main(String[] args ) { try { ServerSocket s = new ServerSocket(3000); for (;;) { Socket incoming = s.accept( ); new ThreadedDataObjectHandler(incoming).start(); } } } catch (Exception e) { System.out.println(e); } } class ThreadedDataObjectHandler extends Thread { public ThreadedDataObjectHandler(Socket i) { incoming = i; } public void run() { try { ObjectInputStream in = new ObjectInputStream(incoming.getInputStream()); ObjectOutputStream out = new ObjectOutputStream(incoming.getOutputStream()); myObject = (DataObject)in.readObject(); System.out.println("Message read: " + myObject.getMessage()); myObject.setMessage("Got it!"); System.out.println("Message written: " + myObject.getMessage()); out.writeObject(myObject); in.close(); out.close(); incoming.close(); } catch (Exception e) { System.out.println(e); } } } DataObject myObject = null; private Socket incoming; Networking import java.io.*; import java.util.*; public class DataObject implements Serializable{ private int number; DataObject(){ number = 2; } public int getNumber(){ return number; } public void setNumber(int inNumber){ number = inNumber; } } Networking import java.io.*; import java.util.*; public class AliveCounter{ private int number; AliveCounter(){ number = 0; } public synchronized int getNumber(){ return number; } public synchronized void setNumber(int inNumber){ number = inNumber; } } Networking import java.io.*; import java.net.*; public class Client{ public static void main(String[] arg){ try{ DataObject myObject = new DataObject(); myObject.setNumber(1); System.out.println("Number : " + myObject.getNumber()); Socket socketToServer = new Socket("127.0.0.1", 3000); ObjectOutputStream myOutputStream = new ObjectOutputStream(socketToServer.getOutputStream()); ObjectInputStream myInputStream = new ObjectInputStream(socketToServer.getInputStream()); myOutputStream.writeObject(myObject); myObject = (DataObject)myInputStream.readObject(); System.out.println("Number : " + myObject.getNumber()); myOutputStream.close(); myInputStream.close(); socketToServer.close(); } catch(Exception e){ System.out.println(e); } } } Networking import java.io.*; import java.net.*; public class ThreadedDataObjectServer { public static void main(String[] args ) { int i = 1; AliveCounter t = new AliveCounter(); try { ServerSocket s = new ServerSocket(3000); for (;;) { Socket incoming = s.accept( ); System.out.println("Spawning " + i); t.setNumber(t.getNumber()+ 1); System.out.println("Total Alive " + t.getNumber()); new ThreadedDataObjectHandler(incoming, i, t).start(); i++; } } catch (Exception e) {System.out.println(e);} } } class ThreadedDataObjectHandler extends Thread { public ThreadedDataObjectHandler(Socket i, int c, AliveCounter a) { incoming = i; counter = c; Alive = a;} public void run() { try { ObjectInputStream in = new ObjectInputStream(incoming.getInputStream()); ObjectOutputStream out = new ObjectOutputStream(incoming.getOutputStream()); myObject = (DataObject)in.readObject(); System.out.println("Number read: " + myObject.getNumber()); myObject.setNumber(counter); System.out.println("Number written: " + myObject.getNumber()); out.writeObject(myObject); in.close(); out.close(); incoming.close(); Alive.setNumber(Alive.getNumber()-1); System.out.println("Total Alive " + Alive.getNumber()); } catch (Exception e) { System.out.println(e); } } DataObject myObject = null; AliveCounter Alive; private Socket incoming; private int counter; } Lecture # 10 Remote Method Invocation (RMI) Remote Method Invocation Remote Method Invocation Remote Method Invocation Remote Method Invocation Remote Method Invocation import java.rmi.*; public interface Product extends Remote { String getDescription() throws RemoteException; } Remote Method Invocation import java.rmi.*; import java.rmi.server.*; public class ProductImpl extends UnicastRemoteObject implements Product { public ProductImpl(String n) throws RemoteException { name = n; } public String getDescription() throws RemoteException { return "I am a " + name + ". Buy me!"; } } private String name; Remote Method Invocation To generate a stub (and skeleton for JDK1.1) for the server class: Use the remote method invocation compiler - rmic >rmic ProductImpl.class You will then have: ProductImpl_Stub.class ProductImpl_Skel.class (JDK1.1) Remote Method Invocation To start the bootstrap registry on the default port (1099): >rmiregistry To start the bootstrap registry on another port: >rmiregistry 2001 Remote Method Invocation import java.rmi.*; import java.rmi.server.*; import sun.applet.*; public class ProductServer { public static void main(String args[]){ System.setSecurityManager(new RMISecurityManager()); try { ProductImpl p1 = new ProductImpl("Blackwell Toaster"); ProductImpl p2 = new ProductImpl("ZapXpress Microwave Oven"); Naming.rebind("//127.0.0.1:2001/toaster", p1); Naming.rebind("//127.0.0.1:2001/microwave", p2); } catch(Exception e) { System.out.println("Error: " + e); } } // End of main(); } Remote Method Invocation Create a file named java.policy which has the following permissions: grant { permission java.net.SocketPermission "*:1024-65535","connect,accept"; permission java.net.SocketPermission "*:80", "connect"; }; Remote Method Invocation Run the program which creates the remote objects and registers them with the rmiregistry. On the Java2 platform you must specify the security policy. >java -Djava.security.policy=java.policy ProductServer Remote Method Invocation To confirm that everything is running properly you may run the following program: import java.rmi.*; import java.rmi.server.*; public class ShowBindings { public static void main(String[] args) { System.setSecurityManager(new RMISecurityManager()); try { String[] bindings = Naming.list("//127.0.0.1:2001"); for (int i = 0; i < bindings.length; i++) System.out.println(bindings[i]); } catch(Exception e) { System.out.println("Error: " + e); } } } Remote Method Invocation To run the ShowBindings program: >java -Djava.security.policy=java.policy ShowBindings You will see the following: rmi://127.0.0.1/toaster rmi://127.0.0.1/microwave Remote Method Invocation The client program: import java.rmi.*; import java.rmi.server.*; public class ProductClient { public static void main(String[] args) { System.setSecurityManager(new RMISecurityManager()); String url = "rmi://127.0.0.1:2001/"; // change to "rmi://www.yourserver.com/" // when server runs on remote machine // www.yourserver.com try { Product c1 = (Product)Naming.lookup(url + "toaster"); Product c2 = (Product)Naming.lookup(url + "microwave"); System.out.println(c1.getDescription()); System.out.println(c2.getDescription()); } catch(Exception e) { System.out.println("Error " + e); } System.exit(0); } } Remote Method Invocation Before you run the client program you must copy the interface Product and the ProductImpl_Stub to the client. You must also create a policy file such as the following: grant { permission java.net.SocketPermission "*:1024-65535","connect,accept"; permission java.net.SocketPermission "*:80", "connect"; }; And invoke the client program: >java -Djava.security.policy=java.policy ProductClient Remote Method Invocation In summary, you must perform the following steps: 1. Compile the interface, implementation, server and client classes javac Product*.java 2. Run rmic on the implementation class rmic -v1.2 PorductImpl 3. Start the RMI registry start rmiregistry 4. Start the server java -Djava.security.policy=java.policy ProductServer 5. Start the client java -Djava.security.policy=java.policy Product Client Remote Method Invocation If everything worked, you will see: I am a Blackwell Toaster. Buy me! I am a ZapXpress Microwave Oven. Buy me! Remote Method Invocation The code for this example is in the Product directory under the supp direcory. Remote Method Invocation import java.rmi.*; public interface Product extends Remote{ String getDescription() throws RemoteException; static final int MALE = 1; static final int FEMALE = 2; static final int BOTH = MALE + FEMALE; } Remote Method Invocation import java.rmi.*; import java.util.*; public interface Warehouse extends Remote { public Vector find(Customer c) throws RemoteException; } Remote Method Invocation import java.io.*; public class Customer implements Serializable { public Customer(int theAge, int theSex, String[] theHobbies) { age = theAge; sex = theSex; hobbies = theHobbies; } public int getAge() { return age; } public int getSex() { return sex; } public boolean hasHobby(String aHobby) { if (aHobby == "") return true; for (int i = 0; i < hobbies.length; i++) if (hobbies[i].equals(aHobby)) return true; return false; } public void reset() { age = 0; sex = 0; hobbies = null; } public String toString(){ String result = "Age: " + age + " Sex: "; if (sex == Product.MALE) result += "Male"; if (sex == Product.FEMALE) result += "Female"; result += " Hobbies: "; for (int i = 0; i < hobbies.length; i++) result += hobbies[i] + " "; return result; } private int age; private int sex; private String[] hobbies; } Remote Method Invocation import java.rmi.*; import java.rmi.server.*; public class ProductImpl extends UnicastRemoteObject implements Product { public ProductImpl(String n, int s, int age1, int age2, String h) throws RemoteException { name = n; ageLow = age1; ageHigh = age2; sex = s; hobby = h; } public boolean match(Customer c) // local method { if (c.getAge() < ageLow || c.getAge() > ageHigh) return false; if (!c.hasHobby(hobby)) return false; if ((sex & c.getSex()) == 0) return false; return true; } public String getDescription() throws RemoteException { return "I am a " + name + ". Buy me!"; } private private private private private String name; int ageLow; int ageHigh; int sex; String hobby; } Remote Method Invocation import java.rmi.*; import java.util.*; import java.rmi.server.*; public class WarehouseImpl extends UnicastRemoteObject implements Warehouse { public WarehouseImpl() throws RemoteException { products = new Vector(); } public synchronized void add(ProductImpl p) // local method { products.addElement(p); } public synchronized Vector find(Customer c) throws RemoteException { Vector result = new Vector(); for (int i = 0; i < products.size(); i++) { ProductImpl p = (ProductImpl)products.elementAt(i); if (p.match(c)) result.addElement(p); } result.addElement( new ProductImpl("Core Java Book", 0, 200, Product.BOTH, "")); c.reset(); return result; } } private Vector products; Remote Method Invocation import java.rmi.*; import java.rmi.server.*; public class WarehouseServer { public static void main(String args[]) { //System.setSecurityManager(new RMISecurityManager()); try { WarehouseImpl w = new WarehouseImpl(); fillWarehouse(w); Naming.rebind("//127.0.0.1:2001/central_warehouse", w); } catch(Exception e) { System.out.println("Error: " + e); } } public static void fillWarehouse(WarehouseImpl w) throws RemoteException { w.add(new ProductImpl("Blackwell Toaster", Product.BOTH, 18, 200, "Household")); w.add(new ProductImpl("ZapXpress Microwave Oven", Product.BOTH, 18, 200, "Household")); w.add(new ProductImpl("Jimbo After Shave", Product.MALE, 18, 200, "Beauty")); w.add(new ProductImpl("Handy Hand Grenade", Product.MALE, 20, 60, "Gardening")); w.add(new ProductImpl("DirtDigger Steam Shovel", Product.MALE, 20, 60, "Gardening")); w.add(new ProductImpl("U238 Weed Killer", Product.BOTH, 20, 200, "Gardening")); w.add(new ProductImpl("Van Hope Cosmetic Set", Product.FEMALE, 15, 45, "Beauty")); w.add(new ProductImpl("Persistent Java Fragrance", Product.FEMALE, 15, 45, "Beauty")); w.add(new ProductImpl("Rabid Rodent Computer Mouse", Product.BOTH, 6, 40, "Computers")); w.add(new ProductImpl("Learn Bad Java Habits in 21 Days Book", Product.BOTH, 20, 200, "Computers")); w.add(new ProductImpl("My first Espresso Maker", Product.FEMALE, 6, 10, "Household")); w.add(new ProductImpl("JavaJungle Eau de Cologne", Product.FEMALE, 20, 200, "Beauty")); w.add(new ProductImpl("Fast/Wide SCSI Coffee Maker", Product.MALE, 20, 50, "Computers")); w.add(new ProductImpl("ClueLess Network Computer", Product.BOTH,6, 200, "Computers")); } } Remote Method Invocation import java.awt.*; import java.awt.event.*; import java.rmi.*; import java.rmi.server.*; import java.util.*; //import corejava.*; public class WarehouseClient extends CloseableFrame implements ActionListener { public WarehouseClient() { setLayout(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.fill = GridBagConstraints.NONE; gbc.weightx = 100; gbc.weighty = 100; add(new Label("Age:"), gbc, 0, 0, 1, 1); add(age = new IntTextField(0, 4), gbc, 1, 0, 1, 1); CheckboxGroup cbg = new CheckboxGroup(); add(male = new Checkbox("Male", cbg, true), gbc, 0, 1, 1, 1); add(female = new Checkbox("Female", cbg, true), gbc, 1, 1, 1, 1); add(new Label("Hobbies"), gbc, 0, 2, 1, 1); hobbies = new java.awt.List(4, true); hobbies.addItem("Gardening"); hobbies.addItem("Beauty"); hobbies.addItem("Computers"); hobbies.addItem("Household"); hobbies.addItem("Sports"); add(hobbies, gbc, 1, 2, 1, 1); Button submitButton = new Button("Submit"); add(submitButton, gbc, 0, 3, 2, 1); submitButton.addActionListener(this); result = new TextArea(4, 40); result.setEditable(false); add(result, gbc, 0, 4, 2, 1); System.setSecurityManager(new RMISecurityManager()); String url = "rmi://127.0.0.1:2001/"; // change to "rmi://www.yourserver.com/" // when server runs on remote machine www.yourserver.com try { centralWarehouse = (Warehouse)Naming.lookup(url + "central_warehouse"); } catch(Exception e) { System.out.println("Error: Can't connect to warehouse. " + e);} } private void add(Component c, GridBagConstraints gbc, int x, int y, int w, int h) { gbc.gridx = x; gbc.gridy = y; gbc.gridwidth = w; gbc.gridheight = h; add(c, gbc); } public void actionPerformed(ActionEvent evt) { String arg = evt.getActionCommand(); if (arg.equals("Submit")) { if (age.isValid()) { Customer c = new Customer(age.getValue(), (male.getState() ? Product.MALE : 0) + (female.getState() ? Product.FEMALE : 0), hobbies.getSelectedItems()); String t = c + "\n"; try { Vector result = centralWarehouse.find(c); for (int i = 0; i < result.size(); i++) { Product p = (Product)result.elementAt(i); t += p.getDescription() + "\n"; } } catch(Exception e) { t = "Error: " + e; } result.setText(t); } // End of if(age.isValid()) } // End of if(arg.equals()) } // End of actionPerformed public static void main(String[] args) { Frame f = new WarehouseClient(); f.setSize(300, 300); f.show(); } private private private private private private Warehouse centralWarehouse; IntTextField age; Checkbox male; Checkbox female; java.awt.List hobbies; TextArea result; } Remote Method Invocation import java.awt.*; import java.awt.event.*; public class CloseableFrame extends Frame { public CloseableFrame(){ addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } } ); setSize(300, 200); setTitle(getClass().getName()); } // End of Constructor } // End of class Remote Method Invocation The Warehouse and WarehouseApplet examples may be found in the supp directory. Lecture #11 Java Database Connectivity (JDBC) Use Java to interact with a database. Java Database Connectivity (JDBC) The JDBC 1.0 API enables you to do the following: Use Java to connect to a database. Issue Java-wrapped SQL commands to the database. Java Database Connectivity (JDBC) Java Database Connectivity (JDBC) The basic steps are as follows: 1. Load the appropriate driver. 2. Connect to the database. 3. Issue java-wrapped SQL commands (JDBC1.0) or simply call java Methods(JDBC 2.0). Java Database Connectivity (JDBC) The JDBC 2.0 API enables you to do the following: Scroll forward and backward in a result set or move to a specific row. Make updates to database tables, using methods in the Java programming language instead of using SQL commands. Send multiple SQL statements to the database as a unit, or a batch. Java Database Connectivity (JDBC) To set up your environment to access Oracle on "logic": 1. Remote login to "logic". 2. Make sure /opt/bin is in your path. 3. Execute the following C shell command: >source /opt/bin/coraenv 4. Start an Oracle application: >sqlplus 5. Enter user name and password 6. Issue SQL Commands Java Database Connectivity (JDBC) Structured Query Language (SQL) Create a table: CREATE TABLE Books ( Title CHAR(60), ISBN CHAR(13), Publisher_Id CHAR(5), URL CHAR(80), Price DECIMAL(6,2) ) Java Database Connectivity (JDBC) Structured Query Language (SQL) Insert values into a table: INSERT INTO Books VALUES ( 'Beyond HTML', '0-07-882198-3', '00788', '', '27.95 ) Java Database Connectivity (JDBC) Structured Query Language (SQL) Update values in a table: UPDATE Books SET Price = Price - 5.00 WHERE Title NOT LIKE '%HTML 3%' Java Database Connectivity (JDBC) Structured Query Language (SQL) Make queries: SELECT * FROM Books Java Database Connectivity (JDBC) Structured Query Language (SQL) Make queries: SELECT ISBN, Price, Title FROM Books Java Database Connectivity (JDBC) Structured Query Language (SQL) Make queries: SELECT ISBN, Price, Title FROM Books WHERE Price <= 29.95 Java Database Connectivity (JDBC) Structured Query Language (SQL) Make queries: SELECT ISBN, Price, Title FROM Books WHERE Title NOT LIKE '%H_M%' Java Database Connectivity (JDBC) Structured Query Language (SQL) Make queries: SELECT ISBN, Price, Title FROM Books WHERE Title LIKE '%''%' Java Database Connectivity (JDBC) Structured Query Language (SQL) Make queries: SELECT * FROM Books, Publishers Java Database Connectivity (JDBC) Structured Query Language (SQL) Make queries: SELECT * FROM Books, Publishers WHERE Books.Publisher_Id = Publishers.Publisher_Id Java Database Connectivity (JDBC) Structured Query Language (SQL) Make queries: SELECT Books.ISBN, Books.Price, Books.Title, Books.Publisher_Id, Publishers.Name, Publishers.URL FROM Books, Publishers WHERE Books.Publisher_Id = Publishers.Publisher_Id Java Database Connectivity (JDBC) Some Common SQL Data Types: INTEGER or INT usually a 32-bit integer SMALLINT usually a 16-bit integer NUMERIC(m,n) fixed point with m digits and n digits after decimal point DECIMAL(m,n) DEC(m,n) FLOAT(n) floating point with n bits of precision REAL usually a 32-bit floating point DOUBLE usually a 64-bit floating point CHARACTER(n) fixed length string of n characters CHAR(n) VARCHAR(n) variable length string of max n characters Java Database Connectivity (JDBC) Java Database Connectivity (JDBC) import java.net.*; import java.sql.*; import java.io.*; import java.util.*; class MakeDB { public static void main (String args[]) { try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); // force loading of driver String url = "jdbc:odbc:corejava"; String user = "Cay"; String password = "password"; Connection con = DriverManager.getConnection(url, user, password); Statement stmt = con.createStatement(); String fileName = ""; if (args.length > 0) fileName = args[0]; else { System.out.println("Enter filename: "); fileName = new BufferedReader (new InputStreamReader(System.in)).readLine(); } // End of if(args.length…) int i = 0; while (i < fileName.length() && (Character.isLowerCase(fileName.charAt(i)) || Character.isUpperCase(fileName.charAt(i)))) i++; String tableName = fileName.substring(0, i); BufferedReader in = new BufferedReader(new FileReader(fileName)); String[] columnNames = readLine(in); String[] columnTypes = readLine(in); createTable(stmt, tableName, columnNames, columnTypes); boolean done = false; while (!done) { String[] values = readLine(in); if (values.length == 0) done = true; else insertInto(stmt, tableName, columnTypes, values); } // End of while() showTable(stmt, tableName, columnNames.length); stmt.close(); con.close(); } // End of try catch (SQLException ex) { System.out.println ("SQLException:"); while (ex != null) { System.out.println ("SQLState: " + ex.getSQLState()); System.out.println ("Message: " + ex.getMessage()); System.out.println ("Vendor: " + ex.getErrorCode()); ex = ex.getNextException(); System.out.println (""); } } // End of 1st catch -- SQLException catch (java.lang.Exception ex) { System.out.println("Exception: " + ex); ex.printStackTrace (); } // End of 2nd catch -- Exception } End of void main() private static String[] readLine(BufferedReader in) throws IOException { String line = in.readLine(); Vector result = new Vector(); if (line != null) { StringTokenizer t = new StringTokenizer(line, "|"); while (t.hasMoreTokens()) result.addElement(t.nextToken().trim()); } String[] retval = new String[result.size()]; result.copyInto(retval); return retval; } private static void createTable(Statement stmt, String tableName, String[] columnNames, String[] columnTypes) throws SQLException { String command = "CREATE TABLE " + tableName + "(\n"; String primary = ""; for (int i = 0; i < columnNames.length; i++) { if (i > 0) command += ",\n"; String columnName = columnNames[i]; if (columnName.charAt(0) == '*') { if (primary.length() > 0) primary += ", "; columnName = columnName.substring(1,columnName.length()); primary += columnName; } // End of if(columnName…) command += columnName + " " + columnTypes[i]; } // End of for() if (primary.length() > 0) command += "\nPRIMARY KEY (" + primary + ")"; command += ")\n"; stmt.executeUpdate(command); } // End of void createTable() private static void insertInto(Statement stmt, String tableName, String[] columnTypes, String[] values) throws SQLException { String command = "INSERT INTO " + tableName + " VALUES ("; for (int i = 0; i < columnTypes.length; i++) { if (i > 0) command += ", "; String columnType = columnTypes[i].toUpperCase(); String value = ""; if (i < values.length) value = values[i]; if (columnType.startsWith("CHAR") || columnType.startsWith("VARCHAR")) { int from = 0; int to = 0; command += "'"; while ((to = value.indexOf('\'', from)) >= 0) { command += value.substring(from, to) + "''"; from = to + 1; } // End of while() command += value.substring(from) + "'"; } // End of if(columnType.start…) else command += value; } // End of for() command += ")"; stmt.executeUpdate(command); } // End of void insertInto(); private static void showTable(Statement stmt, String tableName, int numCols) throws SQLException { String query = "SELECT * FROM " + tableName; ResultSet rs = stmt.executeQuery(query); while (rs.next()){ for (int i = 1; i <= numCols; i++) { if (i > 1) System.out.print("|"); System.out.print(rs.getString(i)); } // End of for() System.out.println(""); }// End of while(rs.next()) rs.close(); } // End of void showTable } Java Database Connectivity (JDBC) Load the Driver: ... Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); // force loading of driver ... Connect to the Database: ... String url = "jdbc:odbc:corejava"; String user = "Cay"; String password = "password"; Connection con = DriverManager.getConnection(url, user, password); ... Issue Java-wrapped SQL statements: ... Statement stmt = con.createStatement(); ... String command = "CREATE TABLE " + tableName + "(\n"; ... command += ")\n"; stmt.executeUpdate(command); ... String command = "INSERT INTO " + tableName + " VALUES ("; ... command += ")"; stmt.executeUpdate(command); Java Database Connectivity (JDBC) Example Oracle Driver (in classes111.zip): oracle.jdbc.driver.OracleDriver Use the DriverManager to make the connection: Connection conn = DriverManager.getConnection ("jdbc:oracle:thin:@logic.njit.edu:1521:logic40", "ted", "tln2880"); Java Database Connectivity (JDBC) Simple Oracle Query: import java.sql.*; class Employee { public static void main (String args []) throws SQLException, ClassNotFoundException { // Load the Oracle JDBC driver Class.forName ("oracle.jdbc.driver.OracleDriver"); // Connect to the database // You must put a database name after the @ sign in the connection URL. // You can use either the fully specified SQL*net syntax or a short cut // syntax as ::. The example uses the short cut syntax. Connection conn = DriverManager.getConnection ("jdbc:oracle:thin:@logic.njit.edu:1521:logic40", "ted", "tln2880"); // Create a Statement Statement stmt = conn.createStatement (); // Select all columns from the "test" table ResultSet rset = stmt.executeQuery ("select * from test"); } // Iterate through the result and print the employee names while (rset.next ()) System.out.println (rset.getString ("c")); } Java Database Connectivity (JDBC) ResultSet executeQuery(String sql) Executes a SQL statement that returns a single ResultSet. rset.next() moves cursor to next row (must be done initially) rset.getString(1) or rset.getString("column name") int executeUpdate(String sql) Executes an SQL INSERT, UPDATE or DELETE statement. Java Database Connectivity (JDBC) import import import import import import java.net.*; java.sql.*; java.awt.*; java.awt.event.*; java.util.*; corejava.*; public class QueryDB extends CloseableFrame implements ActionListener { public QueryDB() { setLayout(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); authors = new Choice(); authors.addItem("Any"); publishers = new Choice(); publishers.addItem("Any"); result = new TextArea(4, 50); result.setEditable(false); priceChange = new TextField(8); priceChange.setText("-5.00"); try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); // force loading of driver String url = "jdbc:odbc:corejava"; String user = "Cay"; String password = "password"; con = DriverManager.getConnection(url, user, password); stmt = con.createStatement(); String query = "SELECT Name FROM Authors"; ResultSet rs = stmt.executeQuery(query); while (rs.next()) authors.addItem(rs.getString(1)); query = "SELECT Name FROM Publishers"; rs = stmt.executeQuery(query); while (rs.next()) publishers.addItem(rs.getString(1)); } catch(Exception e) { result.setText("Error " + e);} gbc.fill = GridBagConstraints.NONE; gbc.weightx = 100; gbc.weighty = 100; add(authors, gbc, 0, 0, 2, 1); add(publishers, gbc, 2, 0, 2, 1); gbc.fill = GridBagConstraints.NONE; Button queryButton = new Button("Query"); add(queryButton, gbc, 0, 1, 1, 1); queryButton.addActionListener(this); Button changeButton = new Button("Change prices"); add(changeButton, gbc, 2, 1, 1, 1); changeButton.addActionListener(this); add(priceChange, gbc, 3, 1, 1, 1); gbc.fill = GridBagConstraints.BOTH; add(result, gbc, 0, 2, 4, 1); } // End of Constructor private void add(Component c, GridBagConstraints gbc, int x, int y, int w, int h) { gbc.gridx = x; gbc.gridy = y; gbc.gridwidth = w; gbc.gridheight = h; add(c, gbc); } // End of void add() public void actionPerformed(ActionEvent evt) { String arg = evt.getActionCommand(); if (arg.equals("Query")) { ResultSet rs = null; try { String author = authors.getSelectedItem(); String publisher = publishers.getSelectedItem(); if (!author.equals("Any") && !publisher.equals("Any")) { if (authorPublisherQueryStmt == null) { String authorPublisherQuery = "SELECT Books.Price, Books.Title " + "FROM Books, BooksAuthors, Authors, Publishers " + "WHERE Authors.Author_Id = BooksAuthors.Author_Id AND " + "BooksAuthors.ISBN = Books.ISBN AND " + "Books.Publisher_Id = Publishers.Publisher_Id AND " + "Authors.Name = ? AND " + "Publishers.Name = ?"; authorPublisherQueryStmt = con.prepareStatement(authorPublisherQuery); } // End of if(authorPublichserQueryStmt…) authorPublisherQueryStmt.setString(1, author); authorPublisherQueryStmt.setString(2, publisher); rs = authorPublisherQueryStmt.executeQuery(); } // End of if(!author.equals) else if (!author.equals("Any") && publisher.equals("Any")) { if (authorQueryStmt == null) { String authorQuery = "SELECT Books.Price, Books.Title " + "FROM Books, BooksAuthors, Authors " + "WHERE Authors.Author_Id = BooksAuthors.Author_Id AND " + "BooksAuthors.ISBN = Books.ISBN AND " + "Authors.Name = ?"; authorQueryStmt = con.prepareStatement(authorQuery); } // End of if(authorQueryStmt…) authorQueryStmt.setString(1, author); rs = authorQueryStmt.executeQuery(); } // End of else if(!author.equals()) else if (author.equals("Any") && !publisher.equals("Any")) { if (publisherQueryStmt == null) { String publisherQuery = "SELECT Books.Price, Books.Title " + "FROM Books, Publishers " + "WHERE Books.Publisher_Id = Publishers.Publisher_Id AND " + "Publishers.Name = ?"; publisherQueryStmt = con.prepareStatement(publisherQuery); } // End of if(publisherQueryStmt…) publisherQueryStmt.setString(1, publisher); rs = publisherQueryStmt.executeQuery(); } // End of else if (!author.equals()) else { if (allQueryStmt == null) { String allQuery = "SELECT Books.Price, Books.Title FROM Books"; allQueryStmt = con.prepareStatement(allQuery); } rs = allQueryStmt.executeQuery(); } // End of else result.setText(""); while (rs.next()) result.append(rs.getString(1) + " | " + rs.getString(2) + "\n"); rs.close(); } // End of try catch(Exception e) { result.setText("Error " + e);} } // End of if(arg.equals(“Query”) else if (arg.equals("Change prices")) { String publisher = publishers.getSelectedItem(); if (publisher.equals("Any")) result.setText ("I am sorry, but I cannot do that."); else try { String updateStatement = "UPDATE Books " + "SET Price = Price + " + priceChange.getText() + " WHERE Books.Publisher_Id = " + "(SELECT Publisher_Id FROM Publishers WHERE Name = '" + publisher + "')"; int r = stmt.executeUpdate(updateStatement); result.setText(r + " records updated."); } // End of try catch(Exception e) { result.setText("Error " + e);} } // End of else if(arg.equals(“Ch…”) } // End of void actionPerformed() public void dispose() { try { stmt.close(); con.close(); } catch(SQLException e) {} } public static void main (String args[]){ Frame f = new QueryDB(); f.setSize(400, 300); f.show(); } } private private private private private private private private private private Choice authors; Choice publishers; TextField priceChange; TextArea result; Connection con; Statement stmt; PreparedStatement authorQueryStmt; PreparedStatement authorPublisherQueryStmt; PreparedStatement publisherQueryStmt; PreparedStatement allQueryStmt; Java Database Connectivity (JDBC) Load the Driver: ... Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); ... Connect to the Database: ... String url = "jdbc:odbc:corejava"; String user = "Cay"; String password = "password"; Connection con = DriverManager.getConnection(url, user, password); ... Issue Java-wrapped SQL statements: ... Statement stmt = con.createStatement(); ... String query = "SELECT Name FROM Authors"; ResultSet rs = stmt.executeQuery(query); while (rs.next()) authors.addItem(rs.getString(1)); query = "SELECT Name FROM Publishers"; rs = stmt.executeQuery(query); while (rs.next()) publishers.addItem(rs.getString(1)); Java Database Connectivity (JDBC) import import import import import import java.net.*; java.sql.*; java.awt.*; java.awt.event.*; java.util.*; corejava.*; public class ViewDB extends CloseableFrame implements ActionListener, ItemListener { public ViewDB() { tableNames = new Choice(); tableNames.addItemListener(this); dataPanel = new Panel(); add(dataPanel, "Center"); Panel p = new Panel(); Button nextButton = new Button("Next"); p.add(nextButton); nextButton.addActionListener(this); add(p, "South"); fields = new Vector(); try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); // force loading of driver String url = "jdbc:odbc:corejava"; String user = "Cay"; String password = "password"; con = DriverManager.getConnection(url, user, password); stmt = con.createStatement(); md = con.getMetaData(); ResultSet mrs = md.getTables(null, null, null, new String[] { "TABLE" }); while (mrs.next()) tableNames.addItem(mrs.getString(3)); mrs.close(); } catch(Exception e) { System.out.println("Error " + e);} add(tableNames, "North"); } // End of ViewDB private void add(Container p, Component c, GridBagConstraints gbc, int x, int y, int w, int h) { gbc.gridx = x; gbc.gridy = y; gbc.gridwidth = w; gbc.gridheight = h; p.add(c, gbc); } public void itemStateChanged(ItemEvent evt) { if (evt.getStateChange() == ItemEvent.SELECTED) { remove(dataPanel); dataPanel = new Panel(); fields.removeAllElements(); dataPanel.setLayout(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.fill = GridBagConstraints.NONE; gbc.anchor = GridBagConstraints.WEST; gbc.weightx = 100; gbc.weighty = 100; try { String tableName = (String)evt.getItem(); if (rs != null) rs.close(); rs = stmt.executeQuery("SELECT * FROM " + tableName); ResultSetMetaData rsmd = rs.getMetaData(); for (int i = 1; i <= rsmd.getColumnCount(); i++) { String columnName = rsmd.getColumnLabel(i); int columnWidth = rsmd.getColumnDisplaySize(i); TextField tb = new TextField(columnWidth); fields.addElement(tb); add(dataPanel, new Label(columnName), gbc, 0, i - 1, 1, 1); add(dataPanel, tb, gbc, 1, i - 1, 1, 1); } // End of for() } catch(Exception e) { System.out.println("Error " + e);} add(dataPanel, "Center"); doLayout(); pack(); showNextRow(); } // End of if(evt.getStateChange()) } // End of void itemStateChanged() public void actionPerformed(ActionEvent evt) { if (evt.getActionCommand().equals("Next")) { showNextRow(); } } public void showNextRow(){ if (rs == null) return; { try { if (rs.next()) { for (int i = 1; i <= fields.size(); i++) { String field = rs.getString(i); TextField tb = (TextField)fields.elementAt(i - 1); tb.setText(field); } // End of for } // End of if(rs.next()) else { rs.close(); rs = null; } } catch(Exception e) { System.out.println("Error " + e);} } } // End of void showNextRow(); public static void main (String args[]) { Frame f = new ViewDB(); f.show(); } private Panel dataPanel; private Choice tableNames; private Vector fields; private private private private Connection con; Statement stmt; DatabaseMetaData md; ResultSet rs; } Java Database Connectivity (JDBC) Load the Driver: ... Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); ... Connect to the Database: ... String url = "jdbc:odbc:corejava"; String user = "Cay"; String password = "password"; Connection con = DriverManager.getConnection(url, user, password); ... Obtain Meta-Data: ... Statement stmt = con.createStatement(); ... md = con.getMetaData(); ResultSet mrs = md.getTables(null, null, null, new String[] { "TABLE" }); while (mrs.next()) tableNames.addItem(mrs.getString(3)); mrs.close(); ... private DatabaseMetaData md; //i.e., schema pattern Java Database Connectivity (JDBC) import import import import java.net.*; java.sql.*; java.io.*; java.util.*; class MakeDB { public static void main (String args[]){ try { Connection con = getConnection(); Statement stmt = con.createStatement(); String tableName = ""; if (args.length > 0) tableName = args[0]; else { System.out.println("Usage: MakeDB TableName"); System.exit(0); } BufferedReader in = new BufferedReader(new FileReader(tableName + ".dat")); createTable(tableName, in, stmt); showTable(tableName, stmt); in.close(); stmt.close(); con.close(); } catch (SQLException ex) { System.out.println ("SQLException:"); while (ex != null) { System.out.println ("SQLState: " + ex.getSQLState()); System.out.println ("Message: " + ex.getMessage()); System.out.println ("Vendor: " + ex.getErrorCode()); ex = ex.getNextException(); System.out.println (""); } } catch (IOException ex) { System.out.println("Exception: " + ex); ex.printStackTrace (); } } public static Connection getConnection() throws SQLException, IOException { Properties props = new Properties(); String fileName = "MakeDB.properties"; FileInputStream in = new FileInputStream(fileName); props.load(in); String drivers = props.getProperty("jdbc.drivers"); if (drivers != null) System.setProperty("jdbc.drivers", drivers); String url = props.getProperty("jdbc.url"); String username = props.getProperty("jdbc.username"); String password = props.getProperty("jdbc.password"); return DriverManager.getConnection(url, username, password); } public static void createTable(String tableName, BufferedReader in, Statement stmt) throws SQLException, IOException { String line = in.readLine(); String command = "CREATE TABLE " + tableName + "(" + line + ")"; stmt.executeUpdate(command); while ((line = in.readLine()) != null) { command = "INSERT INTO " + tableName + " VALUES (" + line + ")"; stmt.executeUpdate(command); } } } public static void showTable(String tableName, Statement stmt) throws SQLException { String query = "SELECT * FROM " + tableName; ResultSet rs = stmt.executeQuery(query); ResultSetMetaData rsmd = rs.getMetaData(); int columnCount = rsmd.getColumnCount(); while (rs.next()){ for (int i = 1; i <= columnCount; i++) { if (i > 1) System.out.print(", "); System.out.print(rs.getString(i)); } System.out.println(); } rs.close(); } Java Database Connectivity (JDBC) Property file: jdbc.drivers=com.pointbase.jdbc.jdbcDriver jdbc.url=jdbc:pointbase:corejava jdbc.username=PUBLIC jdbc.password=PUBLIC Java Database Connectivity (JDBC) Batch file: java -classpath c:\pointbase\classes\pointbasemobile228r.jar;c:\pointbase\classes\pointbasetools228r.jar;c:\poin tbase\classes\swingall.jar;. MakeDB Books Java Database Connectivity (JDBC) On logic (Unix) use this syntax to set the classpath: java -classpath ./:./classes111.zip Employee Java Database Connectivity (JDBC) import import import import import import import java.net.*; java.sql.*; java.awt.*; java.awt.event.*; java.io.*; java.util.*; javax.swing.*; public class QueryDB { public static void main(String[] args) { JFrame frame = new QueryDBFrame(); frame.show(); } } class QueryDBFrame extends JFrame implements ActionListener { public QueryDBFrame(){ setTitle("QueryDB"); setSize(400, 300); addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent e) { System.exit(0);} } ); // addWindowListener() getContentPane().setLayout(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); authors = new JComboBox(); authors.setEditable(false); authors.addItem("Any"); publishers = new JComboBox(); publishers.setEditable(false); publishers.addItem("Any"); result = new JTextArea(4, 50); result.setEditable(false); priceChange = new JTextField(8); priceChange.setText("-5.00"); try { con = getConnection(); stmt = con.createStatement(); String query = "SELECT Name FROM Authors"; ResultSet rs = stmt.executeQuery(query); while (rs.next()) authors.addItem(rs.getString(1)); query = "SELECT Name FROM Publishers"; rs = stmt.executeQuery(query); while (rs.next()) publishers.addItem(rs.getString(1)); } catch(Exception e) { result.setText("Error " + e);} gbc.fill = GridBagConstraints.NONE; gbc.weightx = 100; gbc.weighty = 100; add(authors, gbc, 0, 0, 2, 1); add(publishers, gbc, 2, 0, 2, 1); gbc.fill = GridBagConstraints.NONE; JButton queryButton = new JButton("Query"); queryButton.addActionListener(this); add(queryButton, gbc, 0, 1, 1, 1); JButton changeButton = new JButton("Change prices"); changeButton.addActionListener(this); add(changeButton, gbc, 2, 1, 1, 1); gbc.fill = GridBagConstraints.HORIZONTAL; add(priceChange, gbc, 3, 1, 1, 1); gbc.fill = GridBagConstraints.BOTH; add(result, gbc, 0, 2, 4, 1); } // End of QueryDBFrame() - Constructor public static Connection getConnection()throws SQLException, IOException { Properties props = new Properties(); String fileName = "QueryDB.properties"; FileInputStream in = new FileInputStream(fileName); props.load(in); String drivers = props.getProperty("jdbc.drivers"); if (drivers != null) System.setProperty("jdbc.drivers", drivers); String url = props.getProperty("jdbc.url"); String username = props.getProperty("jdbc.username"); String password = props.getProperty("jdbc.password"); return DriverManager.getConnection(url, username, password); } private void add(Component c, GridBagConstraints gbc, int x, int y, int w, int h) { gbc.gridx = x; gbc.gridy = y; gbc.gridwidth = w; gbc.gridheight = h; getContentPane().add(c, gbc); } public void actionPerformed(ActionEvent evt) { String arg = evt.getActionCommand(); if (arg.equals("Query")) { ResultSet rs = null; try { String author = (String)authors.getSelectedItem(); String publisher = (String)publishers.getSelectedItem(); if (!author.equals("Any") && !publisher.equals("Any")) { if (authorPublisherQueryStmt == null) { String authorPublisherQuery = "SELECT Books.Price, Books.Title " + "FROM Books, BooksAuthors, Authors, Publishers " + "WHERE Authors.Author_Id = BooksAuthors.Author_Id AND " + "BooksAuthors.ISBN = Books.ISBN AND " + "Books.Publisher_Id = Publishers.Publisher_Id AND " + "Authors.Name = ? AND " + "Publishers.Name = ?"; authorPublisherQueryStmt = con.prepareStatement(authorPublisherQuery); } // End of if(authorPublisherQueryStmt …) authorPublisherQueryStmt.setString(1, author); authorPublisherQueryStmt.setString(2, publisher); rs = authorPublisherQueryStmt.executeQuery(); } else if (!author.equals("Any") && publisher.equals("Any")) { if (authorQueryStmt == null) { String authorQuery = "SELECT Books.Price, Books.Title " + "FROM Books, BooksAuthors, Authors " + "WHERE Authors.Author_Id = BooksAuthors.Author_Id AND " + "BooksAuthors.ISBN = Books.ISBN AND " + "Authors.Name = ?"; authorQueryStmt = con.prepareStatement(authorQuery); } authorQueryStmt.setString(1, author); rs = authorQueryStmt.executeQuery(); } else if (author.equals("Any") && !publisher.equals("Any")){ if (publisherQueryStmt == null) { String publisherQuery = "SELECT Books.Price, Books.Title " + "FROM Books, Publishers " + "WHERE Books.Publisher_Id = Publishers.Publisher_Id AND " + "Publishers.Name = ?"; publisherQueryStmt = con.prepareStatement(publisherQuery); } publisherQueryStmt.setString(1, publisher); rs = publisherQueryStmt.executeQuery(); } else { if (allQueryStmt == null) { String allQuery = "SELECT Books.Price, Books.Title FROM Books"; allQueryStmt = con.prepareStatement(allQuery); } rs = allQueryStmt.executeQuery(); } // End of if(!author.equals(…)) result.setText(""); while (rs.next()) result.append(rs.getString(1) + " | " + rs.getString(2) + "\n"); rs.close(); } // End of try{} catch(Exception e) { result.setText("Error " + e);} } // End of if(arg.equals(“Query”))… else if (arg.equals("Change prices")) { String publisher = (String)publishers.getSelectedItem(); if (publisher.equals("Any")) result.setText("I am sorry, but I cannot do that."); else try { String updateStatement = "UPDATE Books " + "SET Price = Price + " + priceChange.getText() + " WHERE Books.Publisher_Id = " + "(SELECT Publisher_Id FROM Publishers WHERE Name = '" + publisher + "')"; int r = stmt.executeUpdate(updateStatement); result.setText(r + " records updated."); } catch(Exception e) { result.setText("Error " + e);} } // End of else if (arg.equals(“Change prices”)) } // End of actionPerformed() public void dispose(){ try { stmt.close(); con.close(); } catch(SQLException e) {} } } private private private private private private private private private private JComboBox authors; JComboBox publishers; JTextField priceChange; JTextArea result; Connection con; Statement stmt; PreparedStatement authorQueryStmt; PreparedStatement authorPublisherQueryStmt; PreparedStatement publisherQueryStmt; PreparedStatement allQueryStmt; Java Database Connectivity (JDBC) Property file: jdbc.drivers=com.pointbase.jdbc.jdbcDriver jdbc.url=jdbc:pointbase:corejava jdbc.username=PUBLIC jdbc.password=PUBLIC Java Database Connectivity (JDBC) Batch File: java -classpath c:\pointbase\classes\pointbasemobile228r.jar;c:\pointbase\classes\pointbasetools228r.jar;c:\poin tbase\classes\swingall.jar;. QueryDB Java Database Connectivity (JDBC) import import import import import import import java.net.*; java.sql.*; java.awt.*; java.awt.event.*; java.io.*; java.util.*; javax.swing.*; public class ViewDB { public static void main(String[] args) { JFrame frame = new ViewDBFrame(); frame.show(); } } class ViewDBFrame extends Jframe implements ActionListener { public ViewDBFrame(){ setTitle("ViewDB"); setSize(300, 200); addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent e) { System.exit(0); } } ); Container contentPane = getContentPane(); tableNames = new JComboBox(); tableNames.addActionListener(this); dataPanel = new JPanel(); contentPane.add(dataPanel, "Center"); nextButton = new JButton("Next"); nextButton.addActionListener(this); JPanel p = new JPanel(); p.add(nextButton); contentPane.add(p, "South"); fields = new ArrayList(); try { con = getConnection(); stmt = con.createStatement(); md = con.getMetaData(); ResultSet mrs = md.getTables(null, null, null, new String[] { "TABLE" }); while (mrs.next())tableNames.addItem(mrs.getString(3)); mrs.close(); } catch(Exception e) {JOptionPane.showMessageDialog(this, e);} contentPane.add(tableNames, "North"); } // End of ViewDBFrame() - Constructor public static Connection getConnection()throws SQLException, IOException { Properties props = new Properties(); String fileName = "ViewDB.properties"; FileInputStream in = new FileInputStream(fileName); props.load(in); String drivers = props.getProperty("jdbc.drivers"); if (drivers != null) System.setProperty("jdbc.drivers", drivers); String url = props.getProperty("jdbc.url"); String username = props.getProperty("jdbc.username"); String password = props.getProperty("jdbc.password"); return DriverManager.getConnection(url, username, password); } private void add(Container p, Component c, GridBagConstraints gbc, int x, int y, int w, int h) { gbc.gridx = x; gbc.gridy = y; gbc.gridwidth = w; gbc.gridheight = h; p.add(c, gbc); } public void actionPerformed(ActionEvent evt) { if (evt.getSource() == nextButton) { showNextRow();} else if (evt.getSource() == tableNames) { remove(dataPanel); dataPanel = new JPanel(); fields.clear(); dataPanel.setLayout(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.weighty = 100; try { String tableName = (String)tableNames.getSelectedItem(); if (rs != null) rs.close(); rs = stmt.executeQuery("SELECT * FROM " + tableName); ResultSetMetaData rsmd = rs.getMetaData(); for (int i = 1; i <= rsmd.getColumnCount(); i++) { String columnName = rsmd.getColumnLabel(i); int columnWidth = rsmd.getColumnDisplaySize(i); JTextField tb = new JTextField(columnWidth); fields.add(tb); gbc.weightx = 0; gbc.anchor = GridBagConstraints.EAST; gbc.fill = GridBagConstraints.NONE; add(dataPanel, new JLabel(columnName), gbc, 0, i - 1, 1, 1); gbc.weightx = 100; gbc.anchor = GridBagConstraints.WEST; gbc.fill = GridBagConstraints.HORIZONTAL; add(dataPanel, tb, gbc, 1, i - 1, 1, 1); } // End of for() } catch(Exception e) { JOptionPane.showMessageDialog(this, e);} getContentPane().add(dataPanel, "Center"); doLayout(); pack(); showNextRow(); } // End of else if() } public void showNextRow(){ if (rs == null) return; { try { if (rs.next()) { for (int i = 1; i <= fields.size(); i++) { String field = rs.getString(i); JTextField tb = (JTextField)fields.get(i - 1); tb.setText(field); } } else { rs.close(); rs = null;} } catch(Exception e) { System.out.println("Error " + e);} } } // End of void showNextRow() private private private private JButton nextButton; JPanel dataPanel; JComboBox tableNames; ArrayList fields; } private private private private Connection con; Statement stmt; DatabaseMetaData md; ResultSet rs; Java Database Connectivity (JDBC) Property file: jdbc.drivers=com.pointbase.jdbc.jdbcDriver jdbc.url=jdbc:pointbase:corejava jdbc.username=PUBLIC jdbc.password=PUBLIC Java Database Connectivity (JDBC) java -classpath c:\pointbase\classes\pointbasemobile228r.jar;c:\pointbase\classes\pointbasetools228r.jar;c:\pointbase\cl asses\swingall.jar;. ViewDB Java Database Connectivity (JDBC) Prepared Statements: ... String publisherQuery = "SELECT Books.Price, Books.Title " + "FROM Books, Publishers " + "WHERE Books.Publisher_Id = Publishers.Publisher_Id AND " + "Publishers.Name = ?"; publisherQueryStmt = con.prepareStatement(publisherQuery); ... publisherQueryStmt.setString(1, publisher); rs = publisherQueryStmt.executeQuery(); Java Database Connectivity (JDBC) Prepared Statements: String authorPublisherQuery = "SELECT Books.Price, Books.Title " + "FROM Books, BooksAuthors, Authors, Publishers " + "WHERE Authors.Author_Id = BooksAuthors.Author_Id AND " + "BooksAuthors.ISBN = Books.ISBN AND " + "Books.Publisher_Id = Publishers.Publisher_Id AND " + "Authors.Name = ? AND " + "Publishers.Name = ?"; authorPublisherQueryStmt = con.prepareStatement(authorPublisherQuery); ... authorPublisherQueryStmt.setString(1, author); authorPublisherQueryStmt.setString(2, publisher); rs = authorPublisherQueryStmt.executeQuery(); Java Database Connectivity (JDBC) Scrollable Result Sets (JDBC 2.0): Statement stmt = con.createStatement(type, concurrency); PreparedStatement stmt = con.prepareStatement(command, type, concurrency); Types: TYPE_FORWARD_ONLY TYPE_SCROLL_INSENSITIVE TYPE_SCROLL_SENSITIVE Concurrency Values: CONCUR_READ_ONLY CONCUR_UPDATABLE Example: Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); ... ResultSet rs = stmt.executeQuery(query); rs.next(); rs.previous(); rs.relative(5); rs.absolute(5); rs.getRow(); Java Database Connectivity (JDBC) Updatable Result Sets (JDBC 2.0): Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE); ... String query = "SELECT * FROM Books"; ResultSet rs = stmt.executeQuery(query); while(rs.next()) { if(. . . ) { double increase = . . . double price = rs.getDouble("Price"); rs.updateDouble("Price", price + increase); rs.updateRow(); } } Java Database Connectivity (JDBC) Updatable Result Sets (JDBC 2.0): Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE); ... String query = "SELECT * FROM Books"; ResultSet rs = stmt.executeQuery(query); ... rs.moveToInsertRow(); rs.updateString("Title", title); rs.updateString("ISBN", isbn); rs.updateString("Publisher_Id", pubid); rs.updateString("URL", url); rs.updateDouble("Price", price); rs.insertRow(); rs.moveToCurrentRow(); ... rs.deleteRow(); ... Java Database Connectivity (JDBC) An Applet front end may be used to send DataObjects to a multi-threaded server which, in turn, uses JDBC to access a database. Lecture #12 Java Beans What are they? BDK and the BeanBox Reflection and Introspection Design Patterns Bean Properties o Simple o Indexed o Bound o Constrained BeanInfo Property Editors Customizers Java Beans What are Beans? o Comprehensive Software Component Technology Goal - reusable software components Java Beans Immediate Practical Applications o Application Builder Support (VB Example) o Distributed Computing Support o Java Beans o Note: All AWT components (and Swing components) are Beans. Java Beans BDK and the BeanBox o Bean Development Kit o BeanBox Installation Starting Batch (Shell script) Toolkit BeanBox PropertySheet Hooking Up Beans Java Beans Reflection and Introspection The Reflection API allows Java code to examine classes and objects at run time and to dynamically access another class's methods and instance fields. o java.lang.reflect i.e., The Field Class getfields(); getfield(); set(); etc. i.e., The Method Class getMethods(); getMethod(); invoke(); etc. Java Beans Design Patterns Accessor + Mutator + Variable = Property Java Beans Design Patterns General: o void setPropertyName(X x); o X getPropertyName(); o i.e., public void setFileName(String f); public String getFileName(); Java Beans Design Patterns Boolean: o public boolean isPropertyName(); o public void setPropertyName(boolean b); o i.e., public boolean isRunning(); public void setRunning(boolean b); Java Beans Design Patterns Events: o public void addEventNameListener(EventNameListener e); o public void removeEventNameListener(EventNameListener e) o i.e., public void addTimerListener(TimerListener e); public void removeTimerListener(TimerListener e); Java Beans Bean Properties o Simple o Indexed o Bound o Constrained Java Beans Bean Properties - Simple public void setFileName(String f) { filename = f; image = Toolkit.getDeafaultToolkit().getImage(filename); setSize(getPreferredSize()); repaint(); } public String getFileName() { return fileName; } Java Beans Bean Properties - Indexed o An indexed property is one that gets or sets an array. o Two pairs of methods are used: X[] getPropertyName(); void setPropertyName(X[] x); X getPropertyName(int i); void setPropertyName(int i, X x); e.g., public double[] getValues() {return values;} public void setValues(double[] v) {values = v;} public double getValues(int i ) {return values[i];} public void setValues(int i. double v) {values[i] = v;} ... private double[] values; public void setFileName(String f) { filename = f; image = Toolkit.getDeafaultToolkit().getImage(filename); setSize(getPreferredSize()); repaint(); } public String getFileName() { return fileName; } Java Beans Bean Properties - Bound o The listener must implement the PropertyChangeListener interface. o This interface requires one method: void propertyChange(PropertyChangeEvent evt); o Register with a source: void addPropertyChangeListener(PropertyChangeListener l); void removePropertyChangeListener(PropertyChangeListener l); o Use support class PropertyChangeSupport: private PropertyChangeSupport pcs = new PropertyChangeSupport(this); o then, public void addPropertyChangeListener(PropertyChangeListener l) { pcs.addPropertyChangeListener(l); } public void removePropertyChangeListener(PropertyChangeListener l) { pcs.removePropertyChangeListener(l); } o Use support class PropertyChangeSupport: pcs.firePropertyChange("PropertyName", oldvalue, newvalue); i.e., pcs.firePropertyChange("running", new Boolean(false), Boolean(true)); Object oldVal = evt.getOldVal(); Object newVal = evt.getNewVal(); Java Beans Bean Properties - Constrained o Allows listener to "veto" change. o The listener must implement the VetoableChangeListener interface in addition to the PropertyChangeListener interface. o One additional method is required: void vetoableChange(PropertyChangeEvent evt) throws PropertyVetoException; Register with a source: void addVetoableChangeListener(VetoableChangeListener l); void removeVetoableChangeListener(VetoableChangeListener l); Use support class PropertyChangeSupport: private VetoableChangeSupport vcs = new VetoableChangeSupport(this); then, public void addVetoableChangeListener(VetoableChangeListener l) { vcs.addVetoableChangeListener(l); } public void removeVetoableChangeListener(VetoableChangeListener l) { vcs.removeVetoableChangeListener(l); } Java Beans import java.beans.*; public class ChartBeanBeanInfo extends SimpleBeanInfo { public PropertyDescriptor[] getPropertyDescriptors(){ try { PropertyDescriptor titlePositionDescriptor = new PropertyDescriptor("titlePosition", ChartBean.class); titlePositionDescriptor.setPropertyEditorClass (TitlePositionEditor.class); PropertyDescriptor inverseDescriptor = new PropertyDescriptor("inverse",ChartBean.class); inverseDescriptor.setPropertyEditorClass(InverseEditor.class); return new PropertyDescriptor[]{ new PropertyDescriptor("title",ChartBean.class), titlePositionDescriptor, new PropertyDescriptor("values", ChartBean.class), new PropertyDescriptor("graphColor", ChartBean.class), inverseDescriptor }; } catch(IntrospectionException e) { System.out.println("Error: " + e); return null; } } static { PropertyEditorManager.registerEditor(double[].class, DoubleArrayEditor.class); } } Applets v. Applications Run Applications as Applets Run Applets as Applications Run as both Applets and Applications Applets v. Applications Converting Applications to Applets o Create an HTML page with a proper APPLET tag o Move code in the main() method to either the init() or start() methods o Replace the Frame or JFrame with Applet or JApplet o Modify display features delete call to setSize() and instead set the width and height in the applet tag o delete call to addWindowListener() delete call to setTitle() and instead set the title using HTML tags Move any code in the constructor to the init() method Applets v. Applications import java.awt.event.*; import java.awt.*; public class ButtonApplication { public static void main(String[] args) { Frame frame = new ButtonFrame(); frame.show(); } } class ButtonFrame extends Frame { public ButtonFrame() { addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } } ); setSize(300, 200); setTitle(getClass().getName()); MyImage = Toolkit.getDefaultToolkit().getImage("duke.gif"); tracker = new MediaTracker(this); tracker.addImage(MyImage, 0); try{ tracker.waitForID(0); }catch(InterruptedException e){}; b = new Button("Image"); add(b, BorderLayout.NORTH); l = new Listener(); b.addActionListener(l); } public void paint(Graphics g) { if(flag){ g.drawImage(MyImage, 100, 80,null);} } private class Listener implements ActionListener { public void actionPerformed(ActionEvent e) { if (flag){ flag=false; }else{ flag =true; } repaint(); } } Listener l; } Button b; boolean flag = false; Image MyImage; MediaTracker tracker; Applets v. Applications import java.applet.*; import java.awt.*; import java.awt.event.*; public class ButtonApplet extends Applet { public void init() { MyImage = getImage(getCodeBase(), "duke.gif"); tracker = new MediaTracker(this); tracker.addImage(MyImage, 0); try{ tracker.waitForID(0); }catch(InterruptedException e){}; imageWidth = MyImage.getWidth(null); imageHeight = MyImage.getHeight(null); b = new Button("Image"); add(b); l = new Listener(); b.addActionListener(l); } public void paint(Graphics g) { if(flag){ g.drawImage(MyImage, 100, 80, imageWidth,imageHeight,null); } } private class Listener implements ActionListener{ public void actionPerformed(ActionEvent e){ if (flag){ flag=false; }else{ flag =true; } repaint(); } } Listener l; Button b; boolean flag = false; Image MyImage; int imageWidth, imageHeight; MediaTracker tracker; } Applets v. Applications import java.awt.*; import java.awt.event.*; import javax.swing.*; class CalculatorPanel extends JPanel implements ActionListener{ public CalculatorPanel(){ setLayout(new BorderLayout()); display = new JTextField("0"); display.setEditable(false); add(display, "North"); } JPanel p = new JPanel(); p.setLayout(new GridLayout(4, 4)); String buttons = "789/456*123-0.=+"; for (int i = 0; i < buttons.length(); i++) addButton(p, buttons.substring(i, i + 1)); add(p, "Center"); private void addButton(Container c, String s) { JButton b = new JButton(s); c.add(b); b.addActionListener(this); } public void actionPerformed(ActionEvent evt) { String s = evt.getActionCommand(); if ('0' <= s.charAt(0) && s.charAt(0) <= '9' || s.equals(".")) { if (start) display.setText(s); else display.setText(display.getText() + s); start = false; } else { if (start) { if (s.equals("-")){ display.setText(s); start = false; } else op = s; } else { calculate(Double.parseDouble(display.getText())); op = s; start = true; } // End of if(start) } // End of if(‘0’…) } public void calculate(double n) { if (op.equals("+")) arg += n; else if (op.equals("-")) arg -= n; else if (op.equals("*")) arg *= n; else if (op.equals("/")) arg /= n; else if (op.equals("=")) arg = n; display.setText("" + arg); } private JTextField display; private double arg = 0; private String op = "="; private boolean start = true; } public class CalculatorApplet extends JApplet{ public void init(){ Container contentPane = getContentPane(); contentPane.add(new CalculatorPanel()); } } Applets v. Applications class MyAppletApplication extends JApplet { public void init(){ ... } ... public static void main(String[] args){ ... } } Applets v. Applications public class AppletFrame extends JFrame { AppletFrame(Applet a, int x, int y) { setTitle(a.getClass().getName()); setSize(x, y); addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent e) { System.exit(0); } } ); Container contentPane = getContentPane(); contentPane.add(a); a.setStub(this); a.init(); show(); a.start(); } ... } Applets v. Applications public class AppletFrame extends JFrame { AppletFrame(Applet a, int x, int y) { ... } public static void main(String[] args) { new AppletFrame(new MyAppletApplication(), 620, 400); } } Applets v. Applications public class AppletFrame extends JFrame { AppletFrame(Applet a, int x, int y) { setTitle(a.getClass().getName()); setSize(x, y); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } } ); Container contentPane = getContentPane(); contentPane.add(a); a.setStub(this); a.init(); show(); a.start(); } public static void main(String[] args) { new AppletFrame(new MyAppletApplication(), 620, 400); } ... } Applets v. Applications public class AppletFrame extends JFrame implements AppletStub, AppletContext { // AppletStub methods public boolean isActive() { return true; } public URL getDocumentBase() { return null; } public URL getCodeBase() { return null; } public String getParameter(String name) { return ""; } public AppletContext getAppletContext() { return this; } public void appletResize(int width, int height) {} } // AppletContext methods public AudioClip getAudioClip(URL url) { return null; } public Image getImage(URL url) { return null; } public Applet getApplet(String name) { return null; } public Enumeration getApplets() { return null; } public void showDocument(URL url) {} public void showDocument(URL url, String target) {} public void showStatus(String status) {} Applets v. Applications import import import import import import java.awt.*; java.awt.event.*; java.applet.*; java.net.*; java.util.*; javax.swing.*; public class AppletFrame extends JFrame implements AppletStub, AppletContext { AppletFrame(Applet a, int x, int y) { setTitle(a.getClass().getName()); setSize(x, y); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } } ); Container contentPane = getContentPane(); contentPane.add(a); a.setStub(this); a.init(); show(); a.start(); } // AppletStub methods public boolean isActive() { return true; } public URL getDocumentBase() { return null; } public URL getCodeBase() { return null; } public String getParameter(String name) { return ""; } public AppletContext getAppletContext() { return this; } public void appletResize(int width, int height) {} // AppletContext methods public AudioClip getAudioClip(URL url) { return null; } public Image getImage(URL url) { return null; } public public public public public Applet getApplet(String name) { return null; } Enumeration getApplets() { return null; } void showDocument(URL url) {} void showDocument(URL url, String target) {} void showStatus(String status) {} } Applets v. Applications public class CalculatorAppletApplication extends CalculatorApplet // It's an applet. It's an application. It's BOTH! { public static void main(String[] args) { new AppletFrame(new CalculatorApplet(), 180, 180); } } Applets v. Applications This won't work. Why not? public class ButtonAppletApplication extends ButtonApplet // It's an applet. It's an application. It's BOTH! { public static void main(String[] args){ new AppletFrame(new ButtonApplet(), 180, 180); } } Which Browser? (And other Properties - from JavaWorld JavaTip 53) import import import import import import java.io.* ; java.lang.* ; java.net.* ; java.util.* ; java.applet.* ; java.awt.* ; public class PropertyLister extends Applet { private TextArea textArea = new TextArea (20, 70); private String key = null; private String value = null; public void init(){ add ("Center", textArea); try { // Alas, rather than doing something intelligent when trying // to foil crackers and other nefarious folks, the following // will likely trigger a security exception if your applet // is running in a restricted environment (like a browser). try { Properties props = System.getProperties(); Enumeration e = props.propertyNames(); while (e.hasMoreElements()) { key = (String) e.nextElement(); value = props.getProperty (key); textArea.appendText ("Key :" + key + ": = :" + value + ":\n"); } } catch (SecurityException se) { // Oh well, no access to everything. // The following list of properties are generally // available in any context. String keys [] = { "java.vendor", "java.vendor.url", "java.version", "java.class.version", "os.name", "os.arch", "os.version", "file.separator", "path.separator", "line.separator", "browser", "browser.vendor", "browser.version" }; } for (int i = 0; i < keys.length; i++){ try { key = keys[i]; value = System.getProperty (key); textArea.appendText ("Key :" + key + ": = :" + value + ":\n"); } catch (SecurityException see) { ; } } } // End of try~catch } catch (Exception exception) { exception.printStackTrace(); } } // End of public void init() Applets v. Applications (Revisited) public class PropertyAppletApplication extends PropertyLister // It's an applet. It's an application. It's BOTH! { public static void main(String[] args) { new AppletFrame(new PropertyLister(), 600, 350); } } Controlling the Browser from an Application (JavaWorld JavaTip 66) import java.io.IOException; public class BrowserControl { public static void displayURL(String url) { boolean windows = isWindowsPlatform(); String cmd = null; try { if (windows) { // cmd = 'rundll32 url.dll,FileProtocolHandler http://...' cmd = WIN_PATH + " " + WIN_FLAG + " " + url; Process p = Runtime.getRuntime().exec(cmd); } else { // Under Unix, Netscape has to be running for the "-remote" // command to work. So, we try sending the command and // check for an exit value. If the exit command is 0, // it worked, otherwise we need to start the browser. // cmd = 'netscape -remote openURL(http://www.javaworld.com)' cmd = UNIX_PATH + " " + UNIX_FLAG + "(" + url + ")"; Process p = Runtime.getRuntime().exec(cmd); try { // wait for exit code -- if it's 0, command worked, // otherwise we need to start the browser up. int exitCode = p.waitFor(); if (exitCode != 0) { // Command failed, start up the browser // cmd = 'netscape http://www.javaworld.com' cmd = UNIX_PATH + " " + url; p = Runtime.getRuntime().exec(cmd); } // End of if(exitCode) } catch(InterruptedException x) { System.err.println("Error bringing up browser, cmd='" + cmd + "'"); System.err.println("Caught: " + x); } } // End of if(windows)~else } catch(IOException x) { // couldn't exec browser System.err.println("Could not invoke browser, command=" + cmd); System.err.println("Caught: " + x); } } // End of static void displayURL() /** * Try to determine whether this application is running under Windows * or some other platform by examing the "os.name" property. * * @return true if this application is running under a Windows OS */ public static boolean isWindowsPlatform(){ String os = System.getProperty("os.name"); if ( os != null && os.startsWith(WIN_ID)) return true; else return false; } /** * Simple example. */ public static void main(String[] args) { displayURL("http://www.javaworld.com"); } // Used to identify the windows platform. private static final String WIN_ID = "Windows"; // The default system browser under windows. private static final String WIN_PATH = "rundll32"; // The flag to display a url. private static final String WIN_FLAG = "url.dll,FileProtocolHandler"; // The default browser under unix. private static final String UNIX_PATH = "netscape"; } // The flag to display a url. private static final String UNIX_FLAG = "-remote openURL"; Controlling the Browser from an Application (JavaTip 66) public class ControlBrowser { public static void main(String[] args) { BrowserControl.displayURL("http://www.cis.njit.edu/~nichol"); } } Sending the Browser to a New Page from within an Applet import import import import java.applet.*; java.awt.*; java.awt.event.*; java.net.*; public class NewPage extends Applet { public void init(){ } b = new Button("New Page"); add(b); l = new Listener(); b.addActionListener(l); private class Listener implements ActionListener{ public void actionPerformed(ActionEvent e) { try{ url = new URL("http://www.cis.njit.edu"); }catch(MalformedURLException mue){ } getAppletContext().showDocument(url); } } Listener l; Button b; URL url; } Lecture #13 Security Here's an applet that tries to write to a local file named "writetest". Security import import import import java.awt.*; java.io.*; java.lang.*; java.applet.*; public class WriteFile extends Applet { String myFile = "writetest"; File f = new File(myFile); PrintWriter pw; public void init() { String osname = System.getProperty("os.name"); } public void paint(Graphics g) { try { pw = new PrintWriter(new FileWriter(f)); pw.println("Stuff should go here."); pw.close(); g.drawString("Successfully wrote to the file named " + myFile + " -- go take a look at it!", 10, 10); } catch (SecurityException e) { g.drawString("writeFile: caught security exception: " + e, 10, 10); } catch (IOException ioe) { g.drawString("writeFile: caught i/o exception", 10, 10); } } } Security Execute runlocal.bat: (won't work) appletviewer WriteFile.html Security Example policy file saved as "ted.policy": grant codeBase "http://www.cis.njit.edu/~nichol/courses/cis786/security/" { permission java.io.FilePermission "<>", "read, write, delete, execute"; }; Security policytool Security Execute runlocalwpolicy.bat: (won't work) appletviewer -J-Djava.security.policy=ted.policy WriteFile.html Security Execute runwpolicy.bat: appletviewer -J-Djava.security.policy=ted.policy http://www.cis.njit.edu/~nichol/courses/cis786/security/WriteFile.html Security The file writetest will contain: Stuff should go here. Security Here's an applet that tries to read from the local file named "writetest". Security import java.awt.*; import java.io.*; import java.lang.*; import java.applet.*; public class CountChars extends Applet { String myFile = "writetest"; File f = new File(myFile); BufferedReader br; public void init() { } String osname = System.getProperty("os.name"); public void paint(Graphics g) { try { br = new BufferedReader(new FileReader(f)); int count = 0; while (br.read() != -1) count++; br.close(); g.drawString("Successfully counted " + count + " chars from the file!", 10, 10); } catch (SecurityException e) { g.drawString("readFile: caught security exception: " + e, 10, 10); } catch (IOException ioe) { g.drawString("readFile: caught i/o exception", 10, 10); } } } Security Execute runcountwpolicy.bat: appletviewer -J-Djava.security.policy=ted.policy http://www.cis.njit.edu/~nichol/courses/cis786/security/CountChars.html Security Example policy file saved as "ted.policy": grant codeBase "http://www.cis.njit.edu/~nichol/courses/cis786/security/" { permission java.io.FilePermission "<>", "read, write, delete, execute"; }; Security Example policy file saved as "ted.policy": grant codeBase "http://www.cis.njit.edu/~nichol/courses/cis786/security/" { permission java.io.FilePermission "<>", "read, write, delete, execute"; }; Example policy file saved as "student.policy": keystore "file:/C:/temp/cis786/security/studentstore"; grant signedBy "ted" { permission java.security.AllPermission; }; Security Steps for the Code Signer Create a JAR file containing the class file Generate Keys Sign the JAR file Export the Public Key Certificate Security Create a JAR file containing the class file >jar cvf CountChars.jar CountChars.class Security Generate Keys >keytool -genkey -alias signFiles -keypass password -keystore tedstore -storepass password Where: -genkey = flag to keytool to generate keys -alias signFiles = alias to refer to keystore entry containing the generated keys -keypass = password for private key -keystore = name of keystore -storepass = password for keystore Security Distinguished Name Information What is your first and last name? What is the name of your organizational unit? What is the name of your organizaiton? What is the name of you City or Locality? What is the name of your State or Province? What is the two-letter country code for this unit? A self-signed certificate will be created based upon the public key and distinguished name information. By default the certificate will be valid for 90 days (-validity). It will be saved in a file called tedstore. Security Sign the JAR file >jarsigner -keystore tedstore -signedjar sCountChars.jar CountChars.jar signfiles Jarsigner extracts the certificate from the keystore entry whose alias is signFiles and attaches it to the signature of the signed JAR file. Security Export the Public Key Certificate >keytool -export -keystore tedstore -alias signFiles -file Nicholson.cer You will be prompted for the store password. Security Steps for the Code Receiver (after receiving the signed JAR file and Certificate) Import the Certificate as a Trusted Certificate Set Up a Policy File Run the applet with reference to the Policy File Security Import the Certificate as a Trusted Certificate >keytool -import -alias ted -file Nicholson.cer -keystore studentstore To confirm fingerprint: >keytool -printcert -file Nicholson.cer Security Set Up a Policy File Example policy file saved as "student.policy": keystore "file:/C:/temp/cis786/security/studentstore"; grant signedBy "ted" { permission java.security.AllPermission; }; Security policytool Specify keystore (Edit menu - Change Keystore) i.e., "file:c:/ . . . /student.policy Add Policy Entry with signed by Alias ("ted") Add Permissions Save as the policy file ("student.policy") Security Run the applet with reference to the Policy File. For example (runcountcharsjar.bat): appletviewer -J-Djava.security.policy=student.policy http://www.cis.njit.edu/~nichol/courses/cis786/security/CountCharsJar.html Security Output: Successfully counted 23 characters from the file! Security Here's a non plugin applet that tries to read from the local file named "writetest". Security Set the main keystore: >keytool -import -alias ted -file Nicholson.cer Security policytool Security Here's a plugin applet that tries to read from a local file named "writetest". Parsing an HTML page import import import import java.io.*; java.net.*; javax.swing.text.*; javax.swing.text.html.*; class GetLinks { public static void main(String[] args) { EditorKit kit = new HTMLEditorKit(); Document doc = kit.createDefaultDocument(); // The Document class does not yet // handle charset's properly. doc.putProperty("IgnoreCharsetDirective", Boolean.TRUE); try { // Create a reader on the HTML content. Reader rd = getReader(args[0]); // Parse the HTML. kit.read(rd, doc, 0); // Iterate through the elements // of the HTML document. ElementIterator it = new ElementIterator(doc); javax.swing.text.Element elem; while ((elem = it.next()) != null) { SimpleAttributeSet s = (SimpleAttributeSet) elem.getAttributes().getAttribute(HTML.Tag.A); if (s != null) { System.out.println(s.getAttribute(HTML.Attribute.HREF)); } } } catch (Exception e) {e.printStackTrace();} System.exit(1); } // Returns a reader on the HTML data. If 'uri' begins // with "http:", it's treated as a URL; otherwise, // it's assumed to be a local filename. static Reader getReader(String uri) throws IOException { if (uri.startsWith("http:")) { // Retrieve from Internet. URLConnection conn = new URL(uri).openConnection(); return new InputStreamReader(conn.getInputStream()); } else { // Retrieve from file. return new FileReader(uri); } } }