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
Internet Addressing with Java Each device that has an Internet connection is identified either by its IP address or by its hostname. Under the Internet Protocol version 4 (IPv4), an IP address is a 32-bit number which consists of four octets (a series of 8 bits). The dotted decimal Notation of an IP address is the representation of each of the four octets in decimal separated by decimal point. For example 10000000 10000001 11111111 00000000 is represented by 128.129.255.0. IP has reserved some addresses known as loopback or localhost IP addresses for testing network applications. The most popular localhost IP address is 127.0.0.1. Two applications that are intended to communicate across a network are tested by running them on the same computer and instructing them to use the same localhost IP address when communicating. The Domain Name System (DNS) provides a service that maps human-readable symbolic names to IP addresses. For example, cs.wpunj.edu. The Domain Name System does specify values for the most significant segment of a domain name which is the segment to the far right. Examples: edu, com, org, net, uk, fr, aero, biz, and asia. An organization applies for a name under one of the existing top-level domains and then chooses how many additional levels to add and the meaning of each. Example 1: Name applied under edu top-domain: wpunj Additional levels: none Hostname of a computer: cs.wpunj.edu Example 2: Name applied under com top-domain: cookies Additional levels: east-coast.cookies.com, west-coast.cookies.com Hostnames (domain names) of computers: computer1.east-coast.cookies.com, computer2.east-coast.cookies.com, computer1.west-coast.cookies.com In Java, dotted decimal notations of IP addresses and hostnames are represented and manipulated by using the class java.net.InetAddress. © 2011 Gilbert Ndjatou Page 1 The InetAddress Class The InetAddress (package java.net) class is used to represent IP addresses within a Java networking application. Unlike most other classes, the class InetAddress has no public constructors. Instead, there are two static methods that return an InetAddress instance. These methods and the other major methods of this class are covered in the list that follows. These methods are public unless otherwise noted. 1. boolean equals(Object obj) Compares this object against the specified object. The result is true if and only if the argument is not null and it represents the same IP address as this object. Two instances of InetAddress represent the same IP address if the length of the byte arrays returned by getAddress is the same for both, and each of the array components is the same for the byte arrays. 2. byte[ ] getAddress( ) Returns the IP address in byte format (as opposed to dotted decimal notation) of this InetAddress object. The bytes are returned in network byte order, with the highest byte as bytearray[0]. 3. static InetAddress[ ] getAllByName ( String hostname ) throws java.net.UnknownHostException, java.lang.SecurityException returns an array of InetAddress instances that represent the specified hostname. Note: While most machines will have a unique IP address, there are situations in which one hostname can be mapped to many machines and/or a hostname can be mapped to many addresses on one machine (virtual addresses). If the host cannot be resolved, or if resolving the host conflicts with the security manager, an exception will be thrown. 4. static InetAddress getByName ( String hostname ) throws java.net.UnknownHostException, java.lang.SecurityException returns an InetAddress instance that represents the specified hostname Note 1: The hostname may be specified either as a text hostname (e.g., davidreilly.com) or as an IP address in dotted decimal format. Note 2: If the host cannot be resolved, or resolving the host conflicts with the security manager, an exception will be thrown. 5. String getHostAddress( ) returns the IP address of the InetAddress instance in dotted decimal format. © 2011 Gilbert Ndjatou Page 2 6. static InetAddress getLocalHost( ) throws java.net.UnknownHostException, java.lang.SecurityException returns an InetAddress instance that represents the localhost machine. Note: If the IP address cannot be determined, or doing so conflicts with the security manager, then an exception will be thrown. 7. String getHostName( ) throws java.lang.SecurityManager Returns the hostname of the InetAddress instance. 8. boolean isMulticastAddress( ) returns "true" if the InetAddress instance is a multicast address, also known as a class D address. 9. String toString( ) Converts this InetAddress instance to a String. The string returned is of the form: hostname / literal IP address. If the host name is unresolved, no reverse name service lookup is performed. The hostname part will be represented by an empty string.. How to Determine the IP Address of the Localhost? You determine the IP address of the localhost (current computer) as follows: 1. Use the static method InetAddress.getLocalHost( ) to obtain an InetAddress object that represents its IP address. Example: InetAddress localAddress = InetAddress.getLocalHost(); 2. Call the instance method getHostAddress( ) on the object in step 1: it returns the IP address in dotted decimal notation. Example: String ipAddress = localAddress.getHostAddress(); Notes: 1. If you want to determine the IP address in byte format, call the instance method getAddress( ) in step 2 above instead of the method getHostAddress( ). Example: Byte [ ] ipAddress = localAddress.getAddress(); 2. This networking operation must be enclosed within a try/catch block, because there is a possibility that an IP address cannot be found which will cause an exception to be thrown. © 2011 Gilbert Ndjatou Page 3 3. If a direct connection to the Internet exists, a meaningful result will be obtained, but dial-up users and those without any Internet connection (such as in an intranet environment) may get the loopback address of 127.0.0.1. Example IA1 The following program finds out the IP address in dotted decimal notation of the computer on which it is executed. You run it by typing the command: java LocalHostDemo Code for LocalHostDemo import java.net.*; public class LocalHostDemo { public static void main(String args[]) { System.out.println ("Looking up local host address"); try { // Get the local host InetAddress localAddress = InetAddress.getLocalHost(); System.out.println("IP address :" + localAddress.getHostAddress()); } catch (UnknownHostException uhe) { System.out.println ("Error - unable to resolve localhost"); } } } Hands-On Exercise IA1 1. Type and execute the program LocalHostDemo. 2. Modify the program LocalHostDemo so that it determines and displays the IP address in byte format as follows: A[0] A[1] A[2] A[3]. For example: 127 45 9 2. How to Determine the IP Address/Hostname of another Computer? You determine the IP address of another computer as follows: 1. Use the static method InetAddress.getByName( ) to obtain an InetAddress object that represents its IP address. Example: InetAddress addr = InetAddress.getByName( “cs.wpunj.edu” ); © 2011 Gilbert Ndjatou Page 4 2. Call the instance method getHostAddress( ) on the object in step 1: it returns the IP address in dotted decimal notation. Example: String ipAddress = addr.getHostAddress(); Notes: a. If you want to determine the IP address in byte format, call the instance method getAddress( ) in step 2 above instead of the method getHostAddress( ). Example: Byte [ ] ipAddress = addr.getAddress(); b. If you want to determine the hostname of a computer, call the instance method getHostName() in step 2 above instead of the method getHostAddress( ). Example: String hostName = addr.getHostName(); Example IA2 The program in this example receives either the hostname or the IP address (in dotted decimal notation) of a computer as a command line argument, and then determines and outputs its IP addresses and hostname. Code for NetworkResolverDemo import java.net.*; public class NetworkResolverDemo { public static void main(String args[]) { if (args.length != 1) { System.err.println ("Syntax - NetworkResolverDemo host"); System.exit(0); } System.out.println ("Resolving " + args[0]); try { // Resolve host and get InetAddress InetAddress addr = InetAddress.getByName( args[0] ); System.out.println ("IP address : " + addr.getHostAddress() ); System.out.println ("Hostname : " + addr.getHostName() ); } catch (UnknownHostException uhe) { System.out.println ("Error - unable to resolve hostname" ); } } } © 2011 Gilbert Ndjatou Page 5 Hands-On Exercise IA2 1. Type and execute the program NetworkResolverDemo as follows: java NetworkResolverDemo cs.wpunj.edu 2. Execute that program again with the command line java NetworkResolverDemo hostAddress (where hostAddress is the IP address of the computer cs.wpunj.edu that is displayed in question 1. © 2011 Gilbert Ndjatou Page 6 TCP Sockets The term network programming refers to writing programs that execute across multiple devices (computers) that are all connected to each other using a network. The java.net package contains a collection of classes and interfaces that provide the low-level communication details. The java.net package provides support for the two most common network protocols: TCP (Transmission Control Protocol) and UDP (User Datagram Protocol) TCP is a stream-based method of network communication. It is typically used over the Internet Protocol, which is referred to as TCP/IP. UDP is a connection-less protocol that allows for packets of data to be transmitted between applications. TCP: Transmission Control Protocol TCP uses the Internet Protocol (IP), a low-level communication protocol, to establish a connection between two machines. This connection provides an interface that does the following: Allows streams of bytes (represented as an InputStream and an OutputStream) to be sent and received between applications on both machines. Convert the streams of bytes into IP datagram packets. A TCP connection between two machines uses the client/server paradigm, and is represented by sockets. The client/server pardigm divides applications into two categories: clients and servers. A TCP client application is an application o that initiates a connection and o sends requests to the server A TCP server application is an application o That listens for and accepts connections. o It also processes the requests from the clients, and o Sends the response back to the client. © 2011 Gilbert Ndjatou Page 7 TCP uses a number in the range 1-65535, called communication port, to distinguish TCP server/client applications on a machine. Ports below 1024 are restricted for use by well-known services such as HTTP, FTP, SMTP, POP3, and telnet. Some well-known services and their associated ports numbers are listed in the following table. Services Port Number FTP 21 SSH / SFTP 22 Telnet 23 Simple Mail Transfer Protocol (SMTP) 25 HyperText Transfer Protocol (HTTP) 80 Post Office Protocol 3 (POP3) 110 IMAP 143 Socket Programming: Sockets provide the communication mechanism between two computers using TCP as follows: The server application uses a special type of socket to do the following: Bind the server application to a Port number Accept an incoming connection from a client application (on a possible remote host), and create a socket (server socket) that will be used for communication with the client socket. It then unbinds the server application from the port number when the communication is done. You use the class ServerSocket (package java.net) to create this special type of sockets. A client application does the following: Creates a socket on its end of the communication and Attempts to connect that socket to the server application (by using the port number of that server application and the IP address of the computer hosting the server application). You use the class Socket (package java.net) to create a client socket. Each client/server socket has an associated input stream which is an instance of the class InputStream, and ouput stream which is an instance of the class OutputStream. © 2011 Gilbert Ndjatou Page 8 You access the input stream of a socket by using the instance method InputStream getInputStream( ) of the Socket class. For example, the input stream of the Socket instance socket is obtained as follows: InputStream socketInput = socket.getInputStream( ) You access the output stream of a socket by using the instance method OutputStream getOutputStream( ) of the Socket class. For example, the output stream of the Socket instance socket is obtained as follows: OutputStream socketOutput = socket.getOutputStream( ) In general, filter streams are connected to a socket’s input/output stream in order to provide more flexible input/output operations. For example, a DataInputStream filter stream is connected to the input stream of the Socket instance socket as follows: DataInputStream sinput = new DataInputStream( socket.getInputStream( )); And a DataOutputStream filter stream is connected to the output stream of the Socket instance socket as follows: DataOutputStream soutput = new DataOutputStream( socket.getOutputStream( )); Note: a. The client's OutputStream (coutput) is connected to the server's InputStream (sinput) and b. The client's InputStream (cinput) is connected to the server's OutputStream (soutput). What the client writes to coutput --------------------> goes to the server’s sinput What the server writes to soutput --------------------> goes to the client’s cinput c. TCP is a two-way communication protocol: data can be sent across both streams at the same time. Input/Output Blocking Input/output operations on sockets are blocking: An attempt to read from an InputStream will wait indefinitely until some data arrive, and If the data does not arrive, the application may block for an indefinite amount of time: This time varies from system to system and depends on factors such as the operating system running on a system and the default network timeout. © 2011 Gilbert Ndjatou Page 9 Filters that may be connected to a Socket’s I/O Streams Character-based input/output operations can be performed on sockets by using the classes BufferReader/BufferWriter. Byte-based input/output operations can be performed on sockets by using the classes DataInputStream/DataOutputStream or ObjectInputStream/ObjectOutputStream. ServerSocket Class Methods The ServerSocket (package java.net) class is used to bind a TCP server application to a port number and to listen for client requests. The ServerSocket class has the following four constructors: Methods with Description public ServerSocket(int port) throws IOException Attempts to create a server socket bound to the specified port. An exception occurs if the port is already bound by another application. public ServerSocket(int port, int backlog) throws IOException Similar to the previous constructor, the backlog parameter specifies how many incoming clients to store in a wait queue. public ServerSocket(int port, int backlog, InetAddress address) throws IOException Similar to the previous constructor, the InetAddress parameter specifies the local IP address to bind to. The InetAddress is used for servers that may have multiple IP addresses, allowing the server to specify which of its IP addresses to accept client requests on. public ServerSocket( ) throws IOException Creates an unbound server socket. When using this constructor, use the bind( ) method when you are ready to bind the server socket. If the ServerSocket constructor does not throw an exception, it means that your application has successfully bound to the specified port and is ready for client requests. © 2011 Gilbert Ndjatou Page 10 Here are some of the most commonly used methods of the ServerSocket class: Methods with Description public int getLocalPort( ) Returns the port that the server socket is listening on. This method is useful if you passed in 0 as the port number in a constructor and let the server find a port for you. public Socket accept( ) throws IOException Waits for an incoming client. This method blocks until either a client connects to the server on the specified port or the socket times out, assuming that the time-out value has been set using the setSoTimeout( ) method. Otherwise, this method blocks indefinitely. public void setSoTimeout(int timeout) Sets the time-out value for how long the server socket waits for a client during the accept( ). public void bind(SocketAddress host, int backlog) Binds the socket to the specified server and port in the SocketAddress object. Use this method if you instantiated the ServerSocket using the no-argument constructor. When you invoke the accept( ) instance method on a SocketAddress object, this method does not return until a client connects to the object. After a client does connect, the accept( ) method creates and returns the reference of a new Socket instance with an unspecified port number. A TCP connection now exists between the client socket and the server socket, and Communication can take place between them. © 2011 Gilbert Ndjatou Page 11 Socket Class Methods The Socket (package java.net) class represents the socket that both the client and server use to communicate with each other. The client obtains a Socket object by instantiating one (while connecting to a server application), Whereas the server obtains a Socket object as the return value of the accept( ) method. The Socket class has the following five constructors that a TCP client application can use to connect to a TCP server application: Methods with Description public Socket(String host, int port) throws UnknownHostException, IOException. This method attempts to connect to the specified server at the specified port. If this constructor does not throw an exception, the connection is successful and the client is connected to the server. public Socket(InetAddress host, int port) throws IOException This method is identical to the previous constructor, except that the host is denoted by an InetAddress object. public Socket(String host, int port, InetAddress localAddress, int localPort) throws IOException. Connects to the specified host and port, creating a socket on the local host at the specified address and port. public Socket(InetAddress host, int port, InetAddress localAddress, int localPort) throws IOException. This method is identical to the previous constructor, except that the host is denoted by an InetAddress object instead of a String public Socket( ) Creates an unconnected socket. Use the connect( ) method to connect this socket to a server. When the Socket constructor returns, it does not simply instantiate a Socket object but it actually attempts to connect to the specified server application on the specified host. Some methods of interest of the Socket class are listed below. © 2011 Gilbert Ndjatou Page 12 Methods with Description public void connect(SocketAddress host, int timeout) throws IOException This method connects the socket to the specified host. This method is needed only when you instantiated the Socket using the no-argument constructor. public InetAddress getInetAddress( ) This method returns the address of the other computer that this socket is connected to. public int getPort( ) Returns the port the socket is bound to on the remote machine. public int getLocalPort( ) Returns the port the socket is bound to on the local machine. public SocketAddress getRemoteSocketAddress( ) Returns the address of the remote socket. public InputStream getInputStream() throws IOException Returns the input stream of the socket. The input stream is connected to the output stream of the remote socket. public OutputStream getOutputStream() throws IOException Returns the output stream of the socket. The output stream is connected to the input stream of the remote socket. public void close() throws IOException Closes the socket, which makes this Socket object no longer capable of connecting again to any server © 2011 Gilbert Ndjatou Page 13 Creating a TCP Client Application Follow these steps to create a TCP client application: Step 1: Use one of the constructors to define an instance of the Socket class by specifying the hostname and the port number of the server application that you want to connect to. Socket client = new Socket( “cs.wpunj.edu”, 80); Example: The constructor of the Socket class attempts to connect the client application to the specified server application. If there is no problem with the network, the constructor will return as soon as a connection is established. But if a connection cannot be established, the constructor may block for an indefinite amount of time: This time varies from system to system and depends on factors such as the operating system running on a system and the default network timeout. Step 2: a. Get a reference of the client application socket’s input stream (that you will use to read messages from the server aplication’s socket). You may also connect an input filter to it as follows: Example: InputStream inFromServer = client.getInputStream( ); DataInputStream cinput = new DataInputStream( inFromServer ); Or DataInputStream cinput = new DataInputStream( client.getInputStream( )); b. Get a reference of the client application socket’s output stream (that you will use to send messages to the server application’s socket). You may also connect an output filter to it as follows: Example: OutputStream outToServer = client.getOutputStream( ); DataOutputStream coutput = new DataOutputStream( outToServer ); Or DataOutputStream coutput = new DataOutputStream( client.getOutputStream( )); © 2011 Gilbert Ndjatou Page 14 Example of TCP Client Application: The following application in the class GreetingClient is a TCP client program that does the following: 1. Get the hostname of a computer and the port number of a TCP server application on that computer as command line arguments 2. Connect to the server application using a socket. 3. Send a greeting to the server application, and 4. Then read the response from the server application that it outputs to the screen. The program should be executed in a command prompt window with the following command line argument (you may use 6066 as the server application port number): Java GreetingClient localhost <port # of the server application> // File Name GreetingClient.java import java.net.*; import java.io.*; public class GreetingClient { public static void main(String [] args) { String serverName = args[0]; // get the hostname of the computer int port = Integer.parseInt(args[1]); // get the port number of the application try { /*-----------------------------Define an instance of the Socket class -----------------------------------*/ System.out.println("Connecting to " + serverName + " on port " + port); Socket client = new Socket(serverName, port); // connect to the server System.out.println("Just connected to " + client.getRemoteSocketAddress( )); /*---------Get a reference of the client socket’s output stream and connect a filter to it --------*/ OutputStream outToServer = client.getOutputStream( ); DataOutputStream coutput = new DataOutputStream( outToServer ); /*------------------------------- Send the message to the server application----------------------------*/ coutput.writeUTF("Hello from " + client.getLocalSocketAddress( )); /*-------- Get a reference of the client socket’s input stream and connect a filter to it------------*/ InputStream inFromServer = client.getInputStream( ); DataInputStream cinput = new DataInputStream( inFromServer ); /*----------------- read the message from the server application and display it --------------------*/ System.out.println("Server says:\t " + cinput.readUTF( )); client.close( ); } catch(IOException e) { e.printStackTrace( ); } } } © 2011 Gilbert Ndjatou Page 15 Creating a TCP Server Step1: Define an instance of the ServerSocket class and connect it to the port number that you want to bind to the TCP server application. Example: ServerSocket serverSocket = new ServerSocket( 6066 ); Step 2: Invoke the instance method accept( ) on the ServerSocket object defined in step 1. Example: Socket server = serverSocket.accept( ); This method waits until a client connects to the server application (using its port number). It then returns a socket that will be used to communicate with the client application’s socket. Step 3: a. Get a reference of the server socket’s input stream (that you will use to read messages from the client’s socket). You may also connect an input filter to it as follows: Example: InputStream inFromClient = server.getInputStream( ); DataInputStream sinput = new DataInputStream( inFromClient ); Or DataInputStream sinput = new DataInputStream( server.getInputStream( )); b. Get a reference of the server socket’s output stream (that you will use to send messages to the client’s socket). You may also connect an output filter to it as follows: Example: OutputStream outToClient server.getOutputStream( ); DataOutputStream soutput = new DataOutputStream( outToClient ); Or DataOutputStream soutput = new DataOutputStream( server.getOutputStream( )); Example of TCP Server Application: The following program in the class GreetingServer is a TCP server application that does the following: 1. Get the the port number for binding as a command line argument. 2. Bing itself to the port number. 3. Wait for a client connection and after a connection is established it does the following: a. Get a message from the client application and print it. b. Send a message to the client application. The program should be executed in a command prompt window with the following command line argument (you may use 6066 as the server application port number): © 2011 Gilbert Ndjatou Page 16 Java GreetingServer <port # of the server application> // File Name GreetingServer.java import java.net.*; import java.io.*; public class GreetingServer { public static void main(String [] args) { int port = Integer.parseInt(args[0]); // get the port number try { /*-----------------------------Define an instance of the ServerSocket class ---------------------------*/ ServerSocket serverSocket = new ServerSocket( port ); /*-------waits until a client connects with the server application (using its port number)-------*/ System.out.println("Waiting for client on port " + serverSocket.getLocalPort( ) + "..."); Socket server = serverSocket.accept( ); // accept client’s connection System.out.println("Just connected to " + server.getRemoteSocketAddress( )); /*-------- Get a reference of the server socket’s input stream and connect a filter to it------------*/ DataInputStream sinput = new DataInputStream( server.getInputStream( ) ); // get a message from the client and print it String st = sinput.readUTF( ); System.out.println( "Client says:\t" + st ); /*-------- Get a reference of the server socket’s output stream and connect a filter to it------------*/ DataOutputStream coutput = new DataOutputStream( server.getOutputStream( ) ); /*--------------------------------------- send the following message to the client-----------------------*/ coutput.writeUTF( "Thank you for connecting to " + server.getLocalSocketAddress( ) + "\nGoodbye!" ); server.close( ); } catch( SocketTimeoutException s ) { System.out.println("Socket timed out!"); } catch(IOException e) { e.printStackTrace( ); } } } © 2011 Gilbert Ndjatou Page 17 The following are the images of two command prompt windows in which each of these programs is compiled and executed. Note that the server program must be executed before the client. Hands-On TCP 1 Type and execute the TCP server application GreetingServer.java in one Command Prompt window and then the TCP client application GreetingClient.java in another Command Prompt window. Example TCP 1 The following program consists of a TCP client application and a TCP server application. The TCP server application binds itself to the port number 6066 and then does the following in an infinite loop: a. Accept a client connection b. Otput the information about the client application (address of host computer and port number), and c. Send to the client application the current time. The server application determines the current time by allocating a class Date (package: java.util) object. The constructor Date( ) allocates a Date object and initializes it so that it represents the time at which it was allocated, measured to the nearest millisecond. The client application does the following: a. Use a socket to connect to the server application. b. Read the current time (sent by the server) and print it. © 2011 Gilbert Ndjatou Page 18 /*---------------------------------------------Server Application---------------------------------------------*/ /*-----This application is executed as follows: java DaytimeServer ---------------------------*/ // File Name DaytimeServer.java import java.net.*; import java.io.*; import java.util.*; public class DaytimeServer { public static int portNumber = 6066; public static void main(String [] args) { try { /*-----------------------------Define an instance of the ServerSocket class ---------------------------*/ ServerSocket serverSocket = new ServerSocket( port ); /*-------------------------------------------accept one or more clients ----------------------------------*/ while( true ) { /*--------------------------accept the connection from the next client ------------------------*/ Socket server = serverSocket.accept( ); /*-----------------------display the information about this client ------------------------------*/ System.out.println("Received request from:|t" + server.getInetAdress( ) + “:” + server.getPort( )); /*-------- Get a reference of the server socket’s output stream and connect a filter to it------*/ DataOutputStream coutput = new DataOutputStream( server.getOutputStream( ) ); /*--------------------- send the current date to the client as a string-----------------------------*/ String st = (String)( new Date( ) ); coutput.writeUTF( st ); /*---------------------close the stream and the connection------------------------------------------*/ coutput.close( ); server.close( ); } } catch( BindException s ) { System.out.println("Port Number:\t" + portNumber + “ already in use”); } catch(IOException e) { e.printStackTrace( ); } } } © 2011 Gilbert Ndjatou Page 19 /*-------------------------------------------Client Application -------------------------------------------------------*/ /*-----This application is executed as follows: java DaytimeClient -----------------------------------------*/ // File Name DaytimeClient.java import java.net.*; import java.io.*; public class DaytimeClient { public static int portNumber = 6066; public static String serverHostName = “localhost”; public static void main(String [] args) { try { /*-----------------------------Define an instance of the Socket class -----------------------------------*/ System.out.println("Connecting to " + serverHostName + " on port " + portNumber); Socket client = new Socket(serverHostName, portNumber); // connect to the server System.out.println("Just connected to " + client.getRemoteSocketAddress( )); /*-------- Get a reference of the client socket’s input stream and connect a filter to it------------*/ InputStream inFromServer = client.getInputStream( ); DataInputStream cinput = new DataInputStream( inFromServer ); /*----------------- get the date from the server application and display it --------------------*/ System.out.println("Current Time is:\t " + cinput.readUTF( )); client.close( ); } catch(IOException e) { e.printStackTrace( ); } } } Hands-On TCP 1 Type and execute the TCP server application DaytimeServer.java in one Command Prompt window and then the TCP client application DaytimeClient.java in two or three other Command Prompt windows. You stop the DaytimeServer application by closing its Command Prompt window. Hands-On TCP 2 Type and execute the TCP server application DaytimeServer2.java below in one Command Prompt window and then the TCP client application DaytimeClient.java in two or three other Command Prompt windows. You stop the DaytimeServer2 application by closing its Command Prompt window. © 2011 Gilbert Ndjatou Page 20 /*---------------------------------------------Server Application----------------------------------------*/ /*-----This application is executed as follows: java DaytimeServer2 ---------------------------*/ // File Name DaytimeServer2.java import java.net.*; import java.io.*; import java.util.*; public class DaytimeServer2 extends Thread { public static int portNumber = 6066; private Socket newServer; public DaytimeServer2( Socket socket ) { newServer = socket; } public static void main(String [] args) { try { /*-----------------------------Define an instance of the ServerSocket class ---------------------------*/ ServerSocket serverSocket = new ServerSocket( portNumber ); /*-------------------------------------------accept one or more clients ----------------------------------*/ while( true ) { /*----------------------------------accept the connection from the next client ---------------------*/ Socket server = serverSocket.accept( ); /*-------create and start a DaytimeServer2 thread to communicate with the new client------*/ Thread serverThread = new DaytimeServer2( server ); serverThread.start( ); } } catch( BindException s ) { System.out.println("Port Number:\t" + portNumber + “ already in use”); } catch(IOException e) { e.printStackTrace( ); } } © 2011 Gilbert Ndjatou Page 21 public void run( ) { /*-----------------------display the information about this client ------------------------------*/ System.out.println("Received request from:|t" + newServer.getInetAdress( ) + “:” + newServer.getPort( )); /*-------- Get a reference of the server socket’s output stream and connect a filter to it------*/ DataOutputStream coutput = new DataOutputStream( newServer.getOutputStream( ) ); /*--------------------- send the current date to the client--------------------------------------------*/ coutput.writeUTF( new Date( ) ); /*---------------------close the stream and the connection------------------------------------------*/ coutput.close( ); newServer.close( ); } }// end of class DaytimeServer2 Exercise TCP 1 1. Write a TCP client application named ComputeClient.java that reads from the keyboard an integer value followed by an arithmetic operator ( + or * ) which is also followed by another integer value. It then sends these input values to the server application in this order, and then receives from the server application the result of the application of the arithmetic operator on the two numerical values that it outputs on the screen. Use 6066 as the the server application port number. 2. Write a TCP server application named ComputeServer.java that does the following: a. Define an instance of the ServerSocket class. b. Then in an infinite loop, do the following: i. Accept a connection from a client application. ii. Read the integer value which is followed by an arithmetic operator ( + or *) and which is also followed by another integer value from the client application. iii. Perform the specified operation on the values and send the result back to the client application. iv. Close the stream and the connection. Use 6066 as the the server application port number. 3. Type and execute the TCP server application ComputerServer.java in one Command Prompt window and then the TCP client application ComputeClient.java in two or three other Command Prompt windows. You stop the ComputerServer application by closing its Command Prompt window.. Exercise TCP 2 Modify the server application of Exercise TCP1 such that it creates in the loop, a thread to read the values and the arithmetic operator from the client application, to perform the specified operation on the values, and to send the result back to the client application. © 2011 Gilbert Ndjatou Page 22 Port Scanning Port Scanning is the process of trying to connect to a port (open a port) with the sole intention to find out if it is already bound to a service. The following program scans a port on a computer given its hostname. The program should be executed in a command prompt window with the following command line argument (for the hostname, you may use cs.wpunj.edu and cs2.wpunj.edu): Java PortScanner <hostname> // File Name PortScanner.java import java.net.*; import java.io.*; public class PortScanner { public static void main(String [] args) { String serverName = args[0]; final int portNum = 21; // get the server’s hostname // try this port number /*----------------------------find out if the host exists -------------------------------------------------------------*/ try { InetAddress ipAddress = InetAddress.getByName( serverName ); try { /*-----------------------------Define an instance of the Socket class -----------------------------------*/ System.out.println("Connecting to " + serverName + " on port " + port); Socket client = new Socket(serverName, portNum); // connect to the server System.out.println("A server application is running on port:\t” + portNum); client.close( ); } catch(IOException e) // the port is open { System.out.println("No server application is running on port:\t” + portNum); } } catch(UnknownHostException e) // the host does not exits { System.out.println( "Could not find host:\t” + serverName ); } } // end of main } // end of PortScanner © 2011 Gilbert Ndjatou Page 23 Hands-On TCP 3 Type and execute the PortScanner application: note that the port number is set to 21. Repeat its execution by setting the port number to some of the following port numbers: Services Port Number FTP 21 SSH / SFTP 22 Telnet 23 Simple Mail Transfer Protocol (SMTP) 25 HyperText Transfer Protocol (HTTP) 80 Post Office Protocol 3 (POP3) 110 IMAP 143 © 2011 Gilbert Ndjatou Page 24 Writing a Java Application that Access a Database with JDBC What is a Database? A database is a structured collection of information about some entities and their relationships. An entity can be: A person like a faculty member at a university. A place like a department in a university. A thing like a classroom or a course. A database management system (DBMS) is a software that provides mechanisms for: Storing, Organizing, Retrieving, and Modifying data. It allows for the access and storage of data without concern for its internal representation. Most popular DBMS today are relational databases. A relational database stores the information about entities in tables. For example, a university database may have a table for each of the following entities: Faculty members, Departments Classrooms, Courses. A table is a file that consists of records (or rows). A record holds the information about an instance of an entity and consists of fields (or columns). A field represents a unit of information about an entity. A field has a name and a data type. The following are examples of fields of a record to hold the information about a faculty member: © 2011 Gilbert Ndjatou Page 25 Field Name Data Type Employee ID ID int (integer) Age age int name name varchar (variable length, non-Unicode string) Department Dept varchar (fixed length, non-Unicode string) Salary salary decimal The name of a field may not contain a space and must starts with a letter. For data type varchar, you must also specify the maximum number of characters following the data type in parentheses. For example, VARCHAR (25). For the data type decimal, you must also specify the maximum number of spaces and the number of digits after the decimal point. For example, DECIMAL (10, 2). Table’s Primary Key One of the fields in a record is identified as the table’s primary key. The value of a record’s primary key is used to uniquely identify that record in the table: two records cannot have the same value for the primary key. The primary key of this table is the employee ID. Most Commonly used Relational DBMSs The following are the most commonly used relational database management systems: RDBMS Java DB (Apache Derby) MySQL ORACLE DB2 Sybase A language called SQL (pronounced “sequel”) is the standard language used with relational databases to perform queries. You use queries to request information that satisfies some given criteria, and to manipulate data. © 2011 Gilbert Ndjatou Page 26 Java DB Relational Database Management System In this class we will use the Java DB relational database management system in embedded mode. It is the Oracle release of the Apache Software Foundation’s (ASF) open source relational database management system, Derby. Derby is written completely in Java and therefore runs in the java virtual machine (JVM). The Java DB product includes Derby without any modification. It is downloaded and installed automatically with the Java Development Kit (JDK). It is installed in the db directory of the JDK installation. For example: For a 64-bit installation, it is: C:\Program Files\Java\jdk1.8.0_25\db The installation contains the following subdirectories: The bin subdirectory: contains the scripts for executing utilities and setting up environment variables. The lib subdirectory: contains the Java DB jar files. Running the Derby ij Tool The Derby ij tool is a command line tool that you can use for interacting with Java DB RDBMS. In order to run Derby ij, you must first do the following: 1. Create a new user or system environment variable named DERBY_HOME. 2. Set the environment variables DERBY_HOME with the pathname of the db directory. For example: set DERBY_HOME=C:\Program Files\Java\jdk1.8.0_25\db 3. Update the PATH environment variable with the pathname of the db\bin directory. For example: set PATH=%DERBY_HOME%\bin;%PATH% Note: a. Steps 1 and 2 could be replaced with the following SET command that will create and set the environment variable DERBY_HOME: set $DERBY_HOME=C:\Program Files\Java\jdk1.8.0_25\db b. Steps 1, 2, and 3 need to be done only once if you are using the system as an administrator. You start Derby ij by opening a command window, and typing the command: ij Derby ij will display the prompt ij> if the command is successful. You exit Derby ij by typing the command: exit; Note that every Derby ij command end with a semicolon ( ; ). © 2011 Gilbert Ndjatou Page 27 Creating a Database You need the following things before you can create a database, the name for your database (collection of tables (files)) a username, and a password for your database. You have to make sure that the folder/directory where you want to create the database is the default directory. Start Derby ij and type the following command to create the database named database-name, with the username username and password password. ij> CONNECT ‘jdbc:derby:database-name; create=true ‘ user ‘username’ password ‘password’; Example: ij> CONNECT ‘jdbc:derby:universitydb; create=true’ user ‘ndjatou’ password ‘gncs4501’; Will cause Derby ij to create a subfolder (subdirectory) with the name universitydb in the default folder (directory). Creating a Table in a Database You create a table with name table-name in a database by using the following create command: ij> CREATE TABLE table-name ( column_name column_data_type, column_name column_data_type, column_name column_data_type, . . . ); Derby ij will create a subfolder (subdirectory) with the name of your table in the default folder (directory). Example: ij> create table faculty (id int, age int, name varchar(25), dept varchar(10), salary decimal(10,2)); Will create the subdirectory faculty in the directory universitydb. © 2011 Gilbert Ndjatou Page 28 After you have created a database table, you can display its contents by using the following SELECT command: ij> SELECT * from Table-name; Example ij> select * from faculty; ID |AGE |NAME |DEPT |SALARY ------------------------------------------------------------------------- 0 rows selected The INSERT Statement The INSERT statement is used to insert a record (row of values) into a database table. Its syntax is as follows: ij> INSERT INTO table_name VALUES (column1-value, column2-value, ...); Example ij> insert into faculty values (103, 43, 'John Doe', 'CSC', 120000.00); 1 row inserted/updated/deleted ij> insert into faculty values (107, 65, 'Jane Doe', 'Math', 90000.00); 1 row inserted/updated/deleted ij> insert into faculty values (117, 60, 'Jack Doe', 'Math', 95000.00); 1 row inserted/updated/deleted ij> insert into faculty values (134, 69, 'Jack Kemp', 'Music', 99000.00); 1 row inserted/updated/deleted ij> insert into faculty values (114, 59, 'Joe Kow', 'CSC', 89000.00); 1 row inserted/updated/deleted ij> insert into faculty values (104, 72, 'Bob Boo', 'Physics', 130000.00); 1 row inserted/updated/deleted ij> insert into faculty values (101, 52, 'Carl Sy', 'English', 125000.00); 1 row inserted/updated/deleted © 2011 Gilbert Ndjatou Page 29 ij> select * from faculty; ID |AGE |NAME |DEPT |SALARY ------------------------------------------------------------------------103 |43 |John Doe |CSC |120000.00 107 |65 |Jane Doe |Math |90000.00 117 |60 |Jack Doe |Math |95000.00 134 |69 |Jack Kemp |Music |99000.00 114 |59 |Joe Kow |CSC |89000.00 104 |72 |Bob Boo |Physics |130000.00 101 |52 |Carl Sy |English |125000.00 7 rows selected © 2011 Gilbert Ndjatou Page 30 Java Database Connectivity (JDBC) Architecture A Java program interacts with a database by using the JDBC API. The JDBC library includes APIs for each of the following tasks: Making a connection to a database. Creating SQL statements. Executing SQL queries in the database. Viewing & Modifying the resulting records. The JDBC Architecture consists of two layers: JDBC API: which provides the application-to-JDBC Manager connection. JDBC Driver API: which supports the JDBC Driver Manager-to-Driver Connection. JDBC Driver A JDBC driver enables a Java executable (Java Applications, Java Applets, Java Servlets, Java ServerPages (JSPs), or Enterprise JavaBeans (EJBs)) to connect to a database. It also allows you to manipulate the data in a database using the JDBC API. Most popular database management systems provide their JDBC drivers. Third-party vendors also provide JDBC drivers for many DBMSs. The JDBC driver manager ensures that the correct driver is used to access a data source. It is capable of supporting multiple concurrent drivers connected to multiple heterogeneous databases. The following architectural diagram shows the location of the driver manager with respect to the JDBC drivers and the Java application: © 2011 Gilbert Ndjatou Page 31 Common JDBC Components The JDBC API consists of the following interfaces and classes: Interfaces: Connection, Driver, ResultSet, and Statement. Classes: DriverManager and SQLExeption. The Connection Interface This interface has all methods for contacting a database. An object of a class that implements the Connection interface represents a communication context: Any communication with a database is through one such object only. The Driver Interface This interface handles the communications with the database server. You will rarely interact directly with objects of a class that implements the Driver interface. Instead, you use DriverManager objects, which manage objects of this type. A DriverManager object also abstracts the details associated with working with objects of a class that implements the Driver interface. The ResultSet Interface The objects of a class that implements this interface hold the data retrieved from a database after you execute an SQL query using an object of a class that implement the Statement interface. They also act as an iterator to allow you to move through their data. The Statement Interface You use objects created from a class that implements this interface to submit SQL statements to a database. Some derived interfaces accept parameters in addition to executing stored procedures. The DriverManager Class Manages a list of database drivers. Matches connection requests from a java application with the proper database driver using a communication sub protocol. The first driver that recognizes a certain sub-protocol under JDBC will be used to establish a database Connection. © 2011 Gilbert Ndjatou Page 32 The SQLException Class This class handles any errors that occur in a database application. © 2011 Gilbert Ndjatou Page 33 JDBC - Database Connections In order to establish a database connection using JDBC, you must first do the following: 1. Create a new user or system environment variable named DERBY_HOME. 2. Set the environment variables DERBY_HOME with the pathname of the db directory. For example: set DERBY_HOME=C:\Program Files\Java\jdk1.8.0_25\db 3. Update the PATH environment variable with the pathname of the db\bin directory. For example: set PATH=%DERBY_HOME%\bin;%PATH% 4. Execute the batch file setEmbeddedCP.bat at the command prompt. Note: a. Steps 1, 2, and 3 are the same steps that you have to perform before you can run the Derby ij Tool. b. These steps need to be performed only once if you are using the system as an administrator. c. Steps 1 and 2 could be replaced with the following SET command that will create and set the environment variable DERBY_HOME: set $DERBY_HOME=C:\Program Files\Java\jdk1.8.0_25\db © 2011 Gilbert Ndjatou Page 34 Making a Connection to a Database Every Java application that makes a connection to a database using the JDBC should first import the JDBC package by adding the following import statements: import java.sql.* ; // for standard JDBC programs: import java.math.* ; // for BigDecimal and BigInteger support You make a connection to a database using JDBC in the following two steps: Step 1: Register the Corresponding JDBC Driver: The driver names of the most popular DBMS are provided in the following table: RDBMS JDBC driver name URL format Java DB Apache Derby org.apache.derby.jdbc.EmbeddedDriver (for an embedded database) jdbc:derby: databaseName org.apache.derby.jdbc.ClientDriver ( for a network database) (for an embedded database) jdbc:derby://hostname:portNumber/databaseName (for a network database) MySQL com.mysql.jdbc.Driver jdbc:mysql://hostname/ databaseName ORACLE oracle.jdbc.driver.OracleDriver jdbc:oracle:thin:@hostname:portNumber:databaseName DB2 COM.ibm.db2.jdbc.net.DB2Driver jdbc:db2:hostname:portNumber/databaseName Sybase com.sybase.jdbc.SybDriver jdbc:sybase:Tds:hostname: portNumber/databaseName This step causes the JVM to load the desired driver implementation into memory so it can be utilized as an implementation of the JDBC interfaces. It also starts the database engine. You need to do this registration only once in your program. The most commonly used method to register a driver is the static method: void forName(<driverName> ) of the Java class Class. The following example uses the static method Class.forName( ) to register the Java DB embedded database driver: © 2011 Gilbert Ndjatou Page 35 try { Class.forName("org.apache.derby.jdbc.EmbeddedDriver"); } catch(ClassNotFoundException ex) { System.out.println("Error: unable to load driver class!"); System.exit(1); } Step 2: Create a Connection Object You need the following information in order to create a Connection object for a particular database: o Your username and password for that database o The database URL. You formulate a database URL by using the information in the table above that lists the most popular RDBMS with their JDBC driver names and their corresponding database URL. The highlighted part in a URL format is static and you need to change only the remaining part as per your database setup. For example, the URL of the database universitydb that we have created above is: jdbc:derby: universitydb. You create a connection by using one of the following static methods of the class DriverManager that return a Connection object: a. Connection getConnection(String url, String user, String password) b. Connection getConnection(String url) // the username and password specified in the form “:username/password” are inserted in the // url, following the driver’s name c. Connection getConnection(String url, Properties prop) // username and password are specified in the Properties string. The first one is the most commonly used form of getConnection( ). If you append the string “;create=true” to the url, the database will be created if it does not yet exist. © 2011 Gilbert Ndjatou Page 36 Example 1: In this example, we are using The Java DB embedded DBMS. The database name is UNIVERSITYDB. The static method getConnection( ) is called to get a Connection object in one of the following ways: 1. with the appropriate username and password: String URL = " jdbc:derby:UNIVERSITYDB"; String USER = "ndjatou"; String PASS = "gncs4501"; Connection conn = DriverManager.getConnection(URL, USER, PASS); 2. The url includes the username and password: String URL = " jdbc:derby:ndjatou/gncs4501:UNIVERSITYDB"; Connection conn = DriverManager.getConnection(URL); 3. username and password specified in the Properties string: String URL = " jdbc:derby:UNIVERSITYDB"; Properties info = new Properties( ); info.put(“user”, “ndjatou”); info.put(“password”, “gncs4501”); Connection conn = DriverManager.getConnection(URL, info); The whole source code required to make a JDBC connection to the Java DB embedded database UNIVERSITYDB for which my username is “ndjatou”, and my password “gncs4501” follows: © 2011 Gilbert Ndjatou Page 37 // Make a connection to a Java DB database using JDBC import java.sql.* ; // for standard JDBC programs: import java.math.* ; // for BigDecimal and BigInteger support public class JdbcTest1 { // JDBC driver name and database URL static string DRIVER = "org.apache.derby.jdbc.EmbeddedDriver"; static String URL = "jdbc:derby:UNIVERSITYDB"; // Database credentials static String USER = "ndjatou"; static String PASS = "gncs4501"; public static void main (String[] args) { try { // Step 1: register the corresponding JDBC driver Class.forName( DRIVER ); // Step 2: create a Connection Object Connection conn = DriverManager.getConnection(URL, USER, PASS); } catch (Exception e) { System.err.println("problem with the driver or the connection"); System.err.println(e.getMessage()); } } } Example 2: In this example, we are using The Oracle's thin driver, The host at TCP/IP address 192.0.0.1 with the host name of amrood, The Oracle listener is configured to listen on port 1521, and The database has the name EMP. The username and the password for this database are: username and password respectively. The static method getConnection( ) is called to get a Connection object in one of the following ways: © 2011 Gilbert Ndjatou Page 38 1. with the appropriate username and password: String URL = "jdbc:oracle:thin:@amrood:1521:EMP"; String USER = "username"; String PASS = "password" Connection conn = DriverManager.getConnection( URL, USER, PASS ); 2. The url includes the username and password: String URL = "jdbc:oracle:thin:username/password@amrood:1521:EMP"; Connection conn = DriverManager.getConnection( URL ); 3. The username and the password specified in the Properties string: String URL = "jdbc:oracle:thin:@amrood:1521:EMP"; Properties info = new Properties( ); info.put(“user”, “username”); info.put(“password”, “password”); Connection conn = DriverManager.getConnection( URL, info ); Note As you can see, connecting to a database requires just these two steps. Assuming that these steps work successfully, the object conn is a connection to your database. You can use this connection to SELECT, INSERT, and DELETE data in your database tables. Closing JDBC Connections It is recommended that you always close the connection to a database by using the instance method close( ) of the Connection class. To ensure that a connection is closed, you could provide a 'finally' block in your code in which this statement is specified. Example To close the opened connection above, you should call the close( ) method as follows: conn.close( ); © 2011 Gilbert Ndjatou Page 39 Interacting with a Database After you have made a connection to a database, you can interact with it in the following two steps: Step 3: Create a Statement Object You can create a Statement object by using a class that implements one of the following interfaces: Statement, CallableStatement, and PreparedStatement The following table provides a summary of each interface properties: Interfaces Recommended Use Statement Used for general-purpose access to your database. Useful when you are using static SQL statements at runtime. The Statement interface cannot accept parameters. PreparedStatement Used when you plan to use the SQL statements many times. The PreparedStatement interface accepts input parameters at runtime. CallableStatement Used when you want to access the database stored procedures. The CallableStatement interface can also accept runtime input parameters. A Statement object is created by calling the instance method createStatement( ) on the Connection object. The signature of this method is: Statement createStatement(int RSType, int RSConcurrency); This method returns a Statement object that you will use to execute SQL statements. Some SQL statements read data from a database and return that data in a ResultSet object. RSType indicates the type of ResultSet object to be generated, and RSConcurrency is one of two ResultSet constants for specifying whether a result set is readonly or updatable. © 2011 Gilbert Ndjatou Page 40 The three possible RSTypes (RresultSet types) are described as follows: Type Description ResultSet.TYPE_FORWARD_ONLY The cursor can only move forward in the result set. This is the default. ResultSet.TYPE_SCROLL_INSENSITIVE The cursor can scroll forward and backward, and The result set is not sensitive to changes made by others to the database that occur after the result set was created. ResultSet.TYPE_SCROLL_SENSITIVE. The cursor can scroll forward and backward, and The result set is sensitive to changes made by others to the database that occur after the result set was created. The possible RSConcurrency are given below. Concurrency Description ResultSet.CONCUR_READ_ONLY Creates a read-only result set. This is the default ResultSet.CONCUR_UPDATABLE Creates an updateable result set. In the following example, we instantiate a Statement object to create a forward-only, read only ResultSet object. try { Statement stmt = conn.createStatement( ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); } catch( Exception ex ) { .... } finally { .... } © 2011 Gilbert Ndjatou Page 41 Step 4: Execute a SQL Statement Once you have created a Statement object, you can then use it to execute a SQL statement with one of its three execute instance methods that follow: Method Description boolean execute (String SQL) int executeUpdate (String SQL) ResultSet executeQuery (String SQL) Returns a boolean value of true if a ResultSet object can be retrieved; otherwise, it returns false. Use this method to execute SQL DDL statements or when you need to use truly dynamic SQL. Returns the number of rows affected by the execution of the SQL statement. Use this method to execute SQL statements for which you expect to get a number of rows affected – for example, an INSERT, UPDATE, or DELETE statement. Returns a ResultSet object. Use this method when you expect to get a result set, as you would with a SELECT statement. Examples 1. ResultSet rs = stmt.executeQuery(“SELECT * FROM faculty” ); 2. String sql; sql = "SELECT id, age, name, dept, salary FROM faculty"; ResultSet rs = stmt.executeQuery(sql); 3. String sql; sql = "SELECT name, salary FROM faculty WHERE salary > 100000.0"; ResultSet rs = stmt.executeQuery(sql); 4. String sql; sql = "INSERT INTO faculty VALUES(333, 33, ‘Zara Ali’, ‘CSC’, 75000.0)"; int num = stmt.executeUpdate(sql); 5. int num = stmt.executeUpdate(“DELETE FROM faculty WHERE age > 68”); 6. String sql = “UPDATE faculty SET salary=150000.0 WHERE id=107”; int num = stmt.executeUpdate(sql); © 2011 Gilbert Ndjatou Page 42 Closing a Statement Object It is a common practice to always close a Statement object with the close( ) method. Closing a Connection object will close the associated Statement object as well. However, you should always explicitly close a Statement object to ensure proper cleanup. Example You may close the Statement object defined in the example above as follows: try { Statement stmt = conn.createStatement( ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); ... } catch (SQLException ex) { ... } finally { stmt.close(); } Step 5: Extract Data from the result Set Some SQL statements read data from a database table and return that data in a result set. The SELECT statement is the standard way to select rows from a database table and to view them in a result set. The result set of a database query is represented by using an object of a class that implements the ResultSet (package java.sql ) interface. This object maintains a pointer to the current row in the result set. The methods of the ResultSet interface are classified into the following three categories: Navigational methods: Get methods: are used to view the data in the columns of the row being pointed to by the cursor. Update methods: are used to update the data in the columns of the current row. The updates can then be updated in the underlying database as well. are used to move the cursor around. The cursor is movable based on the properties of the ResultSet that are specified when the corresponding Statement object is instantiated. © 2011 Gilbert Ndjatou Page 43 Navigating a Result Set The following are some of the instance methods in the ResultSet interface that involve moving the cursor: Methods & Description public void beforeFirst() throws SQLException Moves the cursor just before the first row. public void afterLast() throws SQLException Moves the cursor just after the last row. public boolean first() throws SQLException Moves the cursor to the first row. public void last() throws SQLException Moves the cursor to the last row. public boolean absolute(int row) throws SQLException Moves the cursor to the specified row. public boolean relative(int row) throws SQLException Moves the cursor the given number of rows forward or backward, from where it is currently pointing. public boolean previous() throws SQLException Moves the cursor to the previous row. This method returns false if the previous row is off the result set. public boolean next() throws SQLException Moves the cursor to the next row. This method returns false if there are no more rows in the result set. public int getRow() throws SQLException Returns the row number that the cursor is pointing to. public void moveToInsertRow() throws SQLException Moves the cursor to a special row in the result set that can be used to insert a new row into the database. The current cursor location is remembered. public void moveToCurrentRow() throws SQLException Moves the cursor back to the current row if the cursor is currently at the insert row; otherwise, this method does nothing © 2011 Gilbert Ndjatou Page 44 Viewing a Result Set The ResultSet interface contains methods for getting the data in the columns of the current row. There is a get method for each of the possible data types, and Each get method has two versions: One that takes in a column name. One that takes in a column index. For example, if the column you are interested in viewing contains an int, you need to use one of the following getInt( ) methods of the ResultSet: Methods & Description public int getInt(String columnName) throws SQLException Returns the int in the current row in the column named columnName. public int getInt(int columnIndex) throws SQLException Returns the int in the current row in the specified column index. The column index starts at 1, meaning the first column of a row is 1, the second column of a row is 2, and so on. Similarly, there are get methods in the ResultSet interface for each of the eight Java primitive types (such as getDouble( ) ) as well as: String (getString( )) , Object, URL, and The SQL data types: java.sql.Date, java.sql.Time, java.sql.TimeStamp, java.sql.Clob, and java.sql.Blob. © 2011 Gilbert Ndjatou Page 45 Updating a Result Set The ResultSet interface contains a collection of methods for updating the data in a result set. As with the get methods, there are two update methods for each data type: One that takes in a column name. One that takes in a column index. For example, to update a String column of the current row of a result set, you would use one of the following updateString() methods: Methods & Description public void updateString(int columnIndex, String s) throws SQLException Changes the String in the specified column to the value of s. public void updateString(String columnName, String s) throws SQLException Similar to the previous method, except that the column is specified by its name instead of its index. There are update methods for each of the eight primitive data types, as well as: String, Object, URL, and the SQL data types in the java.sql package. Updating a row in the result set changes the columns of the current row in the ResultSet object, but not in the underlying database. To update your changes to the row in the database, you need to invoke one of the following methods: Methods & Description public void updateRow() Updates the current row by updating the corresponding row in the database. public void deleteRow() Deletes the current row from the database public void refreshRow() Refreshes the data in the result set to reflect any recent changes in the database. public void cancelRowUpdates() public void insertRow() pointing to the insert row. © 2011 Gilbert Ndjatou Cancels any updates made on the current row. Inserts a row into the database. This method can only be invoked when the cursor is Page 46 Example of an JDBC Application In this application, we connect to the database “jdbc:derby:UNIVERSITYDB” , access the faculty table, and display its rows on the screens. It will show you how to open a database connection, execute a SQL query, and display the result set. This application can serve as a template when you need to create your own JDBC application in the future. //Establish a connection to a Java DB database using JDBC import java.sql.* ; // for standard JDBC programs: import java.math.* ; // for BigDecimal and BigInteger support public class FirstExample { // JDBC driver name and database URL static String DRIVER = "org.apache.derby.jdbc.EmbeddedDriver"; static String URL = "jdbc:derby:UNIVERSITYDB"; // Database credentials static String USER = "ndjatou"; static String PASS = "gncs4501"; public static void main (String[] args) { Connection conn = null; Statement stmt = null; Try { // Step 1: "Load" the JDBC driver Class.forName( DRIVER ); // Step 2: Establish the connection to the database System.out.println("Connecting to database..."); conn = DriverManager.getConnection(URL, USER,PASS); //STEP 3: Create a Statement object System.out.println("Creating statement..."); stmt = conn.createStatement(); //STEP 4: Execute a query String sql; sql = "SELECT id, age, name, dept, salary FROM faculty"; ResultSet rs = stmt.executeQuery(sql); © 2011 Gilbert Ndjatou Page 47 //STEP 5: Extract data from the result set while(rs.next()) { //Retrieve by column name int id = rs.getInt("id"); int age = rs.getInt("age"); String name = rs.getString("name"); String department = rs.getString("dept"); double grossPay = rs.getDouble( “salary” ); //Display values System.out.print("ID: " + id); System.out.print(", Age: " + age); System.out.print(", Name: " + name); System.out.print(", DEPARTMENT: " + department); System.out.println(", SaSALARY " + salary); } //STEP 6: Clean-up environment rs.close(); stmt.close(); conn.close(); } catch(SQLException se) { //Handle errors for JDBC se.printStackTrace(); } catch(Exception e) { //Handle errors for Class.forName e.printStackTrace(); } System.out.println("Goodbye!"); }//end main }//end FirstExample © 2011 Gilbert Ndjatou Page 48 Compiling the Program We assume that the data base is created in drive E: and that the program source file is in drive E: You compile the program as follows: E:\>javac FirstExample.java Executing the Program In order to establish a database connection using JDBC, you must first do the following: 1. Create a new user or system environment variable named DERBY_HOME. 2. Set the environment variables DERBY_HOME with the pathname of the db directory. For example: set DERBY_HOME=C:\Program Files\Java\jdk1.8.0_25\db 3. Update the PATH environment variable with the pathname of the db\bin directory. For example: set PATH=%DERBY_HOME%\bin;%PATH% Note: a. Steps 1 and 2 could be replaced with the following SET command that will create and set the environment variable DERBY_HOME: set $DERBY_HOME=C:\Program Files\Java\jdk1.8.0_25\db b. Steps 1, 2, and 3 need to be done only once if you are using the system as an administrator. 1. First execute the batch file: setEmbeddedCP.bat E:\>setEmbeddedCP It will display the following lines of text on the screen: E:\>SET DERBY_HOME=C:\PROGRA~1\Java\JDK18~1.0_6\db E:\>set CLASSPATH=C:\PROGRA~1\Java\JDK18~1.0_6\db\lib\derby.jar;C:\PROGRA~1\Java\ JDK18~1.0_6\db\lib\derbytools.jar;C:\PROGRA~1\Java\JDK18~1.0_6\db/lib/derbyoptionaltools.jar; E:\> 2. Run the program: E:\>java FirstExample The output will be displayed as follows: © 2011 Gilbert Ndjatou Page 49 Connecting to database... Creating statement... ID: 103, Age: 43, Name: John Doe, Department: CSC, Salary 120000.0 ID: 107, Age: 65, Name: Jane Doe, Department: Math, Salary 90000.0 ID: 117, Age: 60, Name: Jack Doe, Department: Math, Salary 95000.0 ID: 134, Age: 69, Name: Jack Kemp, Department: Music, Salary 99000.0 ID: 114, Age: 59, Name: Joe Kow, Department: CSC, Salary 89000.0 ID: 104, Age: 72, Name: Bob Boo, Department: Physics, Salary 130000.0 ID: 101, Age: 52, Name: Carl Sy, Department: English, Salary 125000.0 Goodbye! Hands-on Exercise DB1 Type and execute the program above with the following modification: make sure that you have changed the username and the password on the database “jdbc:derby:UNIVERSITYDB” to your username and password and that you have created the faculty table with the same rows as in the notes. Exercise DB1 Modify the program above as follows: it displays the records of the faculty members who make more than 100 000, it displays the name and the salary of the faculty members who are less than 60 year-old. It insers the record (333, 33, ‘Zara Ali’, ‘CSC’, 75000.0) into the table. It deletes the records of all the faculty members who are older than 68 year old. It changes the salary in the reord with ID 107 to 150000.0. It displays the records of all faculty members in the table. © 2011 Gilbert Ndjatou Page 50 SQL Syntax Structured Query Language (SQL) is a standardized language. It allows you to perform operations on a database, such as: creating entries, reading content, updating content, and deleting entries. SQL is supported by most databases, and It allows you to write database code independently of the underlying database. This chapter gives an overview of SQL, which is a prerequisite to understand JDBC concepts. After going through this chapter, you will be able to: Create, Read, Update, and Delete (often referred to as CRUD operations) data from a database. The CREATE DATABASE statement (does not work with Derby ij) is used for creating a new database. Its syntax is as follows: SQL> CREATE DATABASE DATABASE_NAME; Example The following SQL statement creates a Database named EMP − SQL> CREATE DATABASE EMP; The DROP DATABASE statement is used for deleting an existing database. Its syntax is as follows: SQL> DROP DATABASE DATABASE_NAME; © 2011 Gilbert Ndjatou Page 51 Note: To create or drop a database you should have administrator privilege on your database server. When you delete a database, you lose all the data stored in that database. The CREATE TABLE statement is used for creating a new table. Its syntax is as follows: SQL> CREATE TABLE table_name ( column_name column_data_type, column_name column_data_type, column_name column_data_type ... ); Example The following SQL statement creates a table named Employees with four columns: SQL> CREATE TABLE Employees ( id INT NOT NULL, age INT NOT NULL, first VARCHAR(255), last VARCHAR(255), PRIMARY KEY ( id ) ); The DROP TABLE Statement is used for deleting an existing table. Its syntax follows: SQL> DROP TABLE table_name; Example The following SQL statement deletes a table named Employees SQL> DROP TABLE Employees; © 2011 Gilbert Ndjatou Page 52 The INSERT Statement Is used to insert a record (row of values) into a database table. Its syntax is as follows: SQL> INSERT INTO table_name VALUES (column1-value, column2-value, ...); Example The following SQL INSERT statement inserts a new row in the Employees table created earlier: SQL> INSERT INTO Employees VALUES (100, 18, 'Zara', 'Ali'); The SELECT Statement is used to retrieve data from a database table. It has the following syntax: SQL> SELECT column_name, column_name, ... FROM table_name WHERE conditions; The WHERE clause can use the comparison operators such as =, !=, <, >, <=,and >=, as well as the BETWEEN and LIKE operators. Examples The following SQL statement selects the age, first, and last columns from the Employees table, where id column is 100: SQL> SELECT first, last, age FROM Employees WHERE id = 100; The following SQL statement selects the age, first, and last columns from the Employees table where first column contains Zara: SQL> SELECT first, last, age FROM Employees WHERE first LIKE '%Zara%'; © 2011 Gilbert Ndjatou Page 53 The UPDATE statement is used to update data in a database table. It has the following syntax: SQL> UPDATE table_name SET column_name = value, column_name = value, ... WHERE conditions; The WHERE clause can use the comparison operators such as =, !=, <, >, <=,and >=, as well as the BETWEEN and LIKE operators. Example The following SQL UPDATE statement changes the age column of the employee whose id is 100: SQL> UPDATE Employees SET age=20 WHERE id=100; The DELETE statement is used to delete data from tables. It has the following syntax: SQL> DELETE FROM table_name WHERE conditions; The WHERE clause can use the comparison operators such as =, !=, <, >, <=,and >=, as well as the BETWEEN and LIKE operators. Example The following SQL DELETE statement deletes the record of the employee whose id is 100 − SQL> DELETE FROM Employees WHERE id=100; © 2011 Gilbert Ndjatou Page 54 Introduction to GUI Components A graphical user interface (GUI) presents a user-friendly mechanism for interacting with an application. GUIs are built from GUI components such as buttons, check boxes, and menus. GUI components are sometimes called controls or widgets (short for window gadgets). The user interacts with a GUI component via the mouse, the keyboard, or another form of input such as voice recognition. The component’s appearance and the way in which the user interacts with it are known as its lookand-feel. Some IDEs such as NetBeans, provide GUI design tools with which you can specify a component’s exact size and location in a visual manner by using the mouse, and they generate the Java code for you. However, because each IDE generates this code differently, we will write the code ourselves by using the Java Swing component classes from the javax.swing package. Class JComponent is the superclass of all Swing component classes. It extends class Container, which itself extends class Component. Class Component includes everything from providing layout hints to supporting painting and events. Class Container has support for adding components to the container and laying them out. Class JComponent provides the following functionality to its descendants: 1. Pluggable look-and-feel: an application can customize components’ look-and-feel on each platform by using the UIManager.setLookAndFeel method. 2. Shortcut keys (key bindings) for direct access to GUI components through the keyboard. 3. Tool tips: By specifying a string with the setToolTipText method, you can provide help to users of a component. When the cursor pauses over the component, the specified string is displayed in a small window that appears near the component. 4. Support for accessibility: The JComponent class provides API and basic functionality to help assistive technologies such as braille screen readers get information from Swing components, 5. Painting and borders: the setBorder method allows you to specify the border that a component displays around its edges. To paint the inside of a component, override the paintComponent method. 6. Support for user-interface localization: customizing the user interface to display in different languages and use local cultural conventions. © 2011 Gilbert Ndjatou Page 55 Swing GUI components allow you to specify a uniform look-and-feel for your application across all platforms or to use each platform’s custom look-and-feel. An application can even change the look-and-feel during execution to enable users to choose their own preferred look-and-feel. © 2011 Gilbert Ndjatou Page 56 Dialog Windows A Dialog window (aka Dialog) is a pop-up window that prompts users for a value or informs them for something. The JOptionPane class (from the package javax.swing), allows you to quickly create and customize several different kinds of dialogs. The following table lists the JOptionPane class (static) methods with a description of the kind of dialog window that they create: Method Name Description showMessageDialog Tell the user about something that has happened. showOptionDialog The Grand Unification of the other three. showInputDialog Prompt for some input. showConfirmDialog Asks a confirming question, like yes/no/cancel. Message Types Each message displayed by a Dialog must have a type (message type). You specify a message type by using a value stored in one of the following static variables from the class JOptionPane: ERROR_MESSAGE INFORMATION_MESSAGE WARNING_MESSAGE QUESTION_MESSAGE PLAIN_MESSAGE (for an error message) (for an information) (for a warning) (for a question) (for a plain message) Icons Displayed by Dialog Windows JOptionPane's icon support lets you specify which icon the dialog displays. The following four standard JOptionPane’s icons (question, information, warning, and error) are the default icons for each of the specified message types. © 2011 Gilbert Ndjatou Page 57 Icons used by JOptionPane Icon description Java look and feel Windows look and feel question information warning error You can also use a custom icon or no icon at all (default icon for plain messages). A Dialog is modal: When a Dialog is visible, it blocks user input to all other windows in the program. Frame Component The frame component is the main window of an application. Every dialog is dependent on a Frame component: When that frame is destroyed, so are its dependent Dialogs. When the frame is iconified, its dependent Dialogs also disappear from the screen. When the frame is deiconified, its dependent Dialogs return to the screen. The Title for the Dialog The title for a dialog is the text that appears at the top of the dialog windows. Note Except for Example 7, it is assumed that the code in each of the examples that follow is preceded by the following import statement: import javax.swing.JOptionPane; or import javax.swing.*; © 2011 Gilbert Ndjatou Page 58 showMessageDialog Method The signatures of showMessageDialog methods follows: public static void showMessageDialog( Component parentComponent, Object message, String title, int messageType, Icon icon ) throws HeadlessException The title, message type, and icon may be ommitted: The default string title is Message, the default message type is information, and the default icon depends on the message type. Parameters of the showMessageDialog Method: parentComponent message title is the Frame on which the dialog will depend: if you specify null, or if the parentComponent that you specify has no Frame, a default Frame is used. the Object (message) to display: non-string objects are displayed using their toSting method output representation. the title for the dialog (optional: the default is Message) the type of message to be displayed (optional: the default is information) It must be an integer value stored in one of the following class variables from the class JOptionPane: ERROR_MESSAGE, INFORMATION_MESSAGE, WARNING_MESSAGE, QUESTION_MESSAGE, or PLAIN_MESSAGE. an icon to display in the dialog (optional: the default depends on the message type) this icon helps the user identify the kind of message that is being displayed. messageType icon © 2011 Gilbert Ndjatou Page 59 Example //Example1 //custom title, custom icon JOptionPane.showMessageDialog(frame, "Eggs aren’t supposed to be green.", "Inane custom dialog", JOptionPane.INFORMATION_MESSAGE, icon); The icon parameter is ommitted: The default icon is determined by the messageType parameter. Examples //Example 2 //custom title, warning icon JOptionPane.showMessageDialog(null, "Eggs aren’t supposed to be green.", "Inane warning", JOptionPane.WARNING_MESSAGE); //Example 3 //custom title, error icon JOptionPane.showMessageDialog(null, "Eggs aren’t supposed to be green.", "Inane error", JOptionPane.ERROR_MESSAGE); //Example 4 //custom title, no icon JOptionPane.showMessageDialog(null, "Eggs aren’t supposed to be green.", "A plain message", JOptionPane.PLAIN_MESSAGE); © 2011 Gilbert Ndjatou Page 60 The title, message type, and icon are ommitted: The default string title is Message, the default message type is information, and the default icon is information icon. Example //Example 5 //default title and icon JOptionPane.showMessageDialog(null, "Eggs aren’t supposed to be green."); Hands-On Exercise GUI1 Execute the codes in Examples 2, 3, 4, and 5. © 2011 Gilbert Ndjatou Page 61 showOptionDialog Method The signature of showOptionDialog method follows: public static int showOptionDialog( Component parentComponent, Object message, String title, int optionType, int messageType, Icon icon, Object[ ] options, Object initialValue ) throws HeadlessException The initialValue, the options, and the icon may be specified as null: This method returns an integer value stored in one of the following static variables from the class JOptionPane: o o o o o YES_OPTION NO_OPTION CANCEL_OPTION OK_OPTION CLOSED_OPTION The value returned indicates the option chosen by the user; but the value in variable CLOSED_OPTION is returned when the user closes the dialog. © 2011 Gilbert Ndjatou Page 62 Parameters of the showOptionDialog Method: is the Frame on which the dialog will depend: if you specify null, or if the parentComponent that you specify has no Frame, a default Frame is used. the Object (message) to display: non-string objects are displayed using their toSting method output representation. parentComponent message title the title for the dialog (optional: the default is Message) o o o o optionType Each of these values defines the set of options that will appear at the bottom of the dialog box. the type of message to be displayed (optional: the default is information) It must be an integer value stored in one of the following class variables from the class JOptionPane: ERROR_MESSAGE, INFORMATION_MESSAGE, WARNING_MESSAGE, QUESTION_MESSAGE, or PLAIN_MESSAGE. an icon to display in the dialog. If you do not have your own icon, specify null in order to use the default icon (for the message type that you have specified) to be displayed. This icon helps the user identify the kind of message that is being displayed. icon an array of objects indicating the possible choices that the user can make: if the objects are components, they are rendered properly; non-String objects are rendered using their toString methods; if this parameter is null (and the optionType is YES_NO_OPTION, or YES_NO_CANCEL_OPTION), the options are determined by the Look and Feel. the object that represents the default selection for the dialog; it can be null. Object [ ] options © 2011 Gilbert Ndjatou DEFAULT_OPTION YES_NO_OPTION YES_NO_CANCEL_OPTION OK_CANCEL_OPTION. messageType initialValue an integer value from one of the following static variables from the class JOptionPane: Page 63 Examples Example 6 //Custom button text Object[] options = {"Yes, please", "No, thanks", "No eggs, no ham!"}; int n = JOptionPane.showOptionDialog(null, "Would you like some green eggs to go " + "with that ham?", "A Silly Question", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[2]); Example 7 import static javax.swing.JOptionPane.*; public class TestDialogOption2 { public static void main( String argv[ ] ) { int selection = showOptionDialog(null, "Would you like some eggs with your ham?", "Make your Selection", YES_NO_CANCEL_OPTION, QUESTION_MESSAGE, null, null, null ); } } © 2011 Gilbert Ndjatou Page 64 Hands-On Exercise GUI2 Execute the code in Example 6 and Example 7. Exercise GUI1 Write a program that does the following: 1. Display the following option dialog. 2. Display an information message dialog that displays the user’s selection. © 2011 Gilbert Ndjatou Page 65 showInputDialog Method The signatures of showOptionDialog methods follows: public static Object showInputDialog( Component parentComponent, Object message, String title, int messageType, Icon icon, Object[ ] selectionValues, Object initialSelectionValue ) throws HeadlessException Each of the above parameters may be ommitted except for the message parameter. These methods do the following: Prompts the user for input in a blocking dialog where the initial selection, possible selections, and all other options can be specified. The user will be able to choose from selectionValues parameter. If the selectionValues parameter is null or is ommitted, then the user can input whatever they wish, usually by means of a JTextField. initialSelectionValue is the initial value to prompt the user with. It is up to the UI to decide how best to represent the selectionValues, but usually a JComboBox, JList, or JTextField will be used. The dialog is displayed on top of the Component's frame, and is usually positioned below the Component. Return Value: This method returns the user's input, or null if the user canceled the input. © 2011 Gilbert Ndjatou Page 66 Parameters of the showInputDialog Method: is the Frame on which the dialog will depend (is optional): if you specify null, or if the parentComponent that you specify has no Frame, a default Frame is used. the Object (message) to display: non-string objects are displayed using their toSting method string representation. parentComponent message title the title for the dialog (optional: the default is Input) messageType icon the type of message to be displayed (optional: the default is Question) It must be an integer value stored in one of the following class variables from the class JOptionPane: ERROR_MESSAGE, INFORMATION_MESSAGE, WARNING_MESSAGE, QUESTION_MESSAGE, or PLAIN_MESSAGE. an icon to display in the dialog (optional). If you do not have your own icon, specify null in order to use the default icon (for the message type that you have specified) to be displayed. This icon helps the user identify the kind of message that is being displayed. an array of Objects that gives the possible selections (optional). Object [ ] selectionValues If the selectionValues parameter is null, or is ommitted, then the user can input whatever they wish, usually by means of a JTextField. initialSelectionValue the value used to initialize the input field (optional). © 2011 Gilbert Ndjatou Page 67 Examples Example 8 Object[] possibilities = {"ham", "spam", "yam"}; String s = (String)JOptionPane.showInputDialog( frame, "Complete the sentence:\n" + "\"Green eggs and...\"", "Customized Dialog", JOptionPane.PLAIN_MESSAGE, icon, possibilities, "ham"); //If a string was returned, say so. if ((s != null) && (s.length() > 0)) { JOptionPane.showMessageDialog(null, "Green eggs and... " + s + "!", "Complete Sentence", JOptionPane.PLAIN_MESSAGE); } else //If you're here, the return value was null/empty. JOptionPane.showMessageDialog(null, "You did not complete the sentence!", "Incomplete Sentense", JOptionPane.WARNING_MESSAGE); © 2011 Gilbert Ndjatou Page 68 SelectionValue parameter is set to null: the user can input whatever they wish. Example 9 String s = (String)JOptionPane.showInputDialog( frame, "Complete the sentence:\n" + "\"Green eggs and...\"", "Customized Dialog", JOptionPane.PLAIN_MESSAGE, icon, null, "ham"); //If a string was returned, say so. if ((s != null) && (s.length() > 0)) { JOptionPane.showMessageDialog(null, "Green eggs and... " + s + "!", "Complete Sentence", JOptionPane.PLAIN_MESSAGE); } else //If you're here, the return value was null/empty. JOptionPane.showMessageDialog(null, "You did not complete the sentence!", "Incomplete Sentense", JOptionPane.WARNING_MESSAGE); Example 10 Object[] possibleValues = { "First", "Second", "Third" }; String selectedValue = (String) JOptionPane.showInputDialog( null, "Choose one", "Input", OptionPane.INFORMATION_MESSAGE, null, possibleValues, possibleValues[0]); © 2011 Gilbert Ndjatou Page 69 The icon, selectionValues, and initialSelectionValue are ommitted: public static String showInputDialog( Component parentComponent, Object message, String title, int messageType ) throws HeadlessException Example 11 String s = JOptionPane.showInputDialog( null, "Enter a name please:", "Input", JOptionPane.QUESTION_MESSAGE); The title, messageType, icon, and selectionValues are ommitted: public static String showInputDialog( Component parentComponent, Object message, Object initialSelection ) throws HeadlessException Shows a question-message dialog that requests input from the user. The input value will be initialized to initialSelectionValue. Example 12 String s = JOptionPane.showInputDialog( null, "Enter a name please:", “John”); © 2011 Gilbert Ndjatou Page 70 The title, messageType, icon, and selectionValues are ommitted: a. public static String showInputDialog( Component parentComponent, Object message ) throws HeadlessException Shows a question-message dialog that requests input from the user. Example 13 String s = JOptionPane.showInputDialog( null, "Enter a name please:"); b. public static String showInputDialog( Object message, Object initialSelection ) throws HeadlessException Shows a question-message dialog that requests input from the user. The input value will be initialized to initialSelectionValue. The dialog uses the default frame, and is centered on the screen. Example 14 String s = JOptionPane.showInputDialog( "Enter a name please:" “John”); c. public static String showInputDialog( Object message ) throws HeadlessException Shows a question-message dialog that requests input from the user. The dialog uses the default frame, and is centered on the screen. Example 15 String s = JOptionPane.showInputDialog( "Enter the pay rate please:"); © 2011 Gilbert Ndjatou Page 71 Hands-On Exercise GUI3 Execute the code in the examples above. Exercise GUI2 Write a program that does the following: 1. Display an input dialog to read the name of a product, its unit price and the quantity purchased: these values are entered in this order and are separated by spaces. 2. User a Scanner object to read from the string returned in step 1 the name of the product, its unit price, and the quantity purchased. 3. Display an information message dialog that displays the name of the product, its quantity, its unit price, and its price. Note: use the format method of the String class to build your displayed string. Note: The class Scanner constructor, public Scanner( String source) creates a new Scanner object that produces values scanned from the string source. Example: Scanner input = new Scanner(“john 25.70”); String name = input.next( ); double payRate = input.nextDouble( ); © 2011 Gilbert Ndjatou Page 72 showConfirmDialog Methods static int showConfirmDialog(Component parentComponent, Object message) Brings up a dialog with the options Yes, No and Cancel; with the title, Select an Option. static int showConfirmDialog(Component parentComponent, Object message, String title, int optionType) Brings up a dialog where the number of choices is determined by the optionType parameter. static int showConfirmDialog(Component parentComponent, Object message, String title, int optionType, int messageType) Brings up a dialog where the number of choices is determined by the optionType parameter, where the messageType parameter determines the icon to display. static int showConfirmDialog(Component parentComponent, Object message, String title, int optionType, int messageType, Icon icon) optionType an integer value from one of the following static variables from the class JOptionPane that specifies the options available on the dialog: YES_NO_OPTION, YES_NO_CANCEL_OPTION, or OK_CANCEL_OPTION. Returns: an integer indicating the option selected by the user. This method returns the integer value stored in one of the following class variables from the class JOptionPane: YES_OPTION NO_OPTION CANCEL_OPTION OK_OPTION CLOSED_OPTION The value returned indicates the option chosen by the user; but the value in variable CLOSED_OPTION is returned when the user closes the dialog. Exercise GUI3 Write a program that does the following: 1. Display a confirmation dialog. 2. Display an information message dialog that displays the user’s selection. © 2011 Gilbert Ndjatou Page 73 Frames (Main Windows) A Frame is a top-level window with a title bar, a content pane, and a border. The size of a frame includes any area designated for the border. The content pane contains the visible components in a frame. You can optionally add a menu bar to a frame. The menu bar is by convention positioned within the frame, but outside the content pane. Some look and feels, such as the Mac OS look and feel, give you the option of placing the menu bar in another place more appropriate for the look and feel, such as at the top of the frame. You create a frame in one of the following two ways: by using an instance of the class JFrame (from the package javax.swing) or as a subclass of the class JFrame. The class JFrame is an indirect subclass of class java.awt.Window that provides the basic attributes and behaviors of a window: A title bar at the top of the window, and Buttons to minimize, maximize, and close the window. The following is a picture of a frame: A JFrame actually consists of three layers: the content pane, the background, and the glass pane. The content pane appears in front of the background and is where the GUI components in the JFrame are displayed. The glass pane is used to display tool tips and other items that should appear in front of the GUI components on the screen. © 2011 Gilbert Ndjatou Page 74 Creating and Setting up a Frame You create and set up a Fram in the following seven steps: Step 1: create the frame. Step 2: Specify how components will be displayed in the frame (optional). Step 3: Create components and add them in the frame. Step 4: Specify what will happen when the user closes the frame (optional). Step 5: Set the size the frame. Step 6: set the frame location (optional). Step 7: Display the frame. © 2011 Gilbert Ndjatou Page 75 1. Creating a Frame You create a frame by using one of the following constructors of the JFrame class (package javax.swing): Constructor Description JFrame( ) Create a frame that is initially invisible. JFrame( String ) Create a frame (that is initially invisible) and set its title. Examples JFrame frame = new JFrame( ); JFrame frame = new JFrame( “Frame Demo” ); You can do this in two different ways: by using a class that extends the JFrame class or by using a static method in which you define an object of the class JFrame. © 2011 Gilbert Ndjatou Page 76 Using a Class that extends Class JFrame to create a Frame import javax.swing.JFrame; public class CreateAFrame1 extends JFrame { . . . public CreateAFrame1( ) { // Step 1 Create the frame super( “Frame Title” ); . . . // constructor } } Using a Method in which we instantiate an object of the Class JFrame import javax.swing.JFrame; public class CreateAFrame2 { public static void createAFrame( ) { // Step 1 Create the frame JFrame frame = new JFrame ( “Frame Title” ); . . . } } © 2011 Gilbert Ndjatou Page 77 2. Specifying How Components will be displayed in the Frame You can specify how components are displayed in a frame in the following two ways: Using a layout manager. Using the absolute positioning. Using a Layout Managers A layout manager arranges GUI components in a container for presentation purposes. The way components are arranged depends on the layout manager that you use. Layout managers are classes that implement the interface LayoutManager (in package java.awt). Some of these classes are provided in the following table: Layout Manager FlowLayout (package java.awt) (default for javax.swing.JPanel) Description It places components sequentially (left to right) in the order they are added. Components can be left aligned, centered (default), or right aligned. You specify the alignment by using the instance method setAlignment of the class FlowLayout and a value in one of the FlowLayout’s static variables, FlowLayout.CENTER, FlowLayout.LEFT, and FlowLayout.RIGHT Example: FlowLayout layout = new FlowLayout( ); layout.setAlignment( FlowLayout.LEFT); BorderLayout (package java.awt) (default for JFrame) GridLayout (package java.awt) © 2011 Gilbert Ndjatou It arranges components into five regions that you can specify by using one of the static variables, top (NORTH), bottom (SOUTH), left (EAST), right (WEST), and center (CENTER) of the class BorderLayout. Constructor: BorderLayout(int hgap, int vgap) where hgap is the number of pixels between components that are arranged horizontally, and vgap is the number of pixels between components that are arranged vertically. The default is 1 pixel. It limits a container to containing at most five components. When you add a component to a container, you have to specify also the region where it must be added (using one of the static variable above); otherwise, it will be added to the center. Example: frame. add(component, BorderLayout.NORTH); It arranges components into rows and columns Constructor: GridLayout(int numRow, int numCol, int hgap, int vgap) where numRow is the number of rows, numCol is the number of columns, hgap is the number of pixels between components that are arranged horizontally, and vgap is the number of pixels between components that are arranged vertically. The default is 1 pixel. Page 78 BoxLayout (package javax.swing) GridBagLayout (package java.awt) It arranges components horizontally along a container’s x-axis, or vertically along its y-axis, with all the components having the same size. Class Box declares a container with the BoxLayout as its default layout manager and provides static methods to create a Box with a horizontal or vertical BoxLayout. Is similar to the Gridlayout manager, but the components can vary in size and can be added in any order. You specify a layout manager as follows: a. Instantiate an object of a layout manager class. b. Specify that object as the argument of the instance method void setLayout of the class JFrame (package javax.swing). Examples: 1. import java.awt.FlowLayout; import javax.swing.JFrame; public class CreateAFrame1 extends JFrame { . . . public CreateAFrame1( ) { // Step 1 Create the frame super( “Frame Title” ); //Step 2 Specify how components will be displayed in the frame FlowLayout layout = new FlowLayout( ); setLayout( layout ); . . . } } Note: The two statements in Step 2 can be written as one statement as follows: setLayout( new FlowLayout( ) ); © 2011 Gilbert Ndjatou Page 79 2. import java.awt.FlowLayout; import javax.swing.JFrame; public class CreateAFrame2 { public static void createAFrame( ) { // Step 1 Create the frame JFrame frame = new JFrame ( “Frame Title” ); //Step 2 Specify how components will be displayed in the frame FlowLayout layout = new FlowLayout( ); frame.setLayout( layout ); . . . } } Note: The two statements in Step 2 can be written as one statement as follows: frame.setLayout( new FlowLayout( ) ); Adjusting a Frame’s Layout You must do one of the following things after you have adjusted (or change) a frame’s layout: Call the instance method void layoutContainer(Container ) of the LayoutManager interface (inherited by all layout managers) to specify that the JFrame’s container should be rearranged based on the adjusted layout. Call the instance method void validate( ) of the class Container (package: java.awt) to recompute the container’s layout based on the current layout manager for the Container and the current set of displayed GUI components. Example: layout.setAlignment( FlowLayout.LEFT ); // adjust the alignment to left alignment layout.layoutContainer( frame.getContentPane( ) ); //rearrange the JFrame ( frame.getContentPane( ) ).validate( ); © 2011 Gilbert Ndjatou Page 80 Absolute positioning By setting a container’s layout to null, you can specify the absolute position of each component with respect to the upper-left corner of the container by using the Component class instance methods setSize and setLocation or setBounds. If you do this, you must also specify each component’s size. 3. Creating Components and adding them to the Frame The way you create a component depends on its type and on whether or not this component is a source of events. The following table lists the basic Swing GUI components that we will discuss. Component Source of Event Description JLabel No Displays un-editable test and/or icons. JTextField Yes Receives input from the user. JButton Yes Triggers an event when clicked with the mouse. JCheckBox Yes Specifies an option that can be selected or not selected. Yes A drop-down list of items from which the user can make a selection. Yes A list of items from which the user can make a selection by clicking on any one of them. Multiple elements can be selected. Yes An area in which components can be placed and organized. JComboBox JList JPanel © 2011 Gilbert Ndjatou Page 81 You add a component to a frame by using one of the following JFrame (inherited) add instance methods: Modifier and Type Method and Description Component add(Component comp) Appends the specified component to the end of this container. It returns the component argument. Component add(Component comp, int index) Adds the specified component to this container at the given position. It returns the component argument. void add(Component comp, Object constraints) Adds the specified component to the end of this container. Also notifies the layout manager to add the component to this container's layout using the specified constraints object. void add(Component comp, Object constraints, int index) Adds the specified component to this container with the specified constraints at the specified index. Also notifies the layout manager to add the component to this container's layout using the specified constraints object. Examples: 1. import java.awt.FlowLayout; import javax.swing.JFrame; public class CreateAFrame1 extends JFrame { . . . public CreateAFrame1( ) { // Step 1 Create the frame super( “Frame Title” ); //Step 2 Specify how components will be displayed in the frame setLayout( new FlowLayout( ) ); // Step 3 Create components and add them to the frame <to be done later> . . . } } © 2011 Gilbert Ndjatou Page 82 2. import java.awt.FlowLayout; import javax.swing.JFrame; public class CreateAFrame2 { public static void createAFrame( ) { // Step 1 Create the frame JFrame frame = new JFrame ( “Frame Title” ); //Step 2 Specify how components will be displayed in the frame frame.setLayout( new FlowLayout( ) ); // Step 3 Create components and add them to the frame <to be done later> . . . } } 4. Specifying what to do when the User closes the Frame By default, when the user closes a frame onscreen, the frame is hidden. Although invisible, the frame still exists and the program can make it visible again. If you do not want this to take place when you close a frame, then you have to do one of the following things: Register a window listener that handles window-closing events. Specify the default close behavior using the instance method void setDefaultCloseOperation ( int ) of the JFrame class. You can even do both. The argument to the method void setDefaultCloseOperation ( int ) must be a value in one of the following class variables: © 2011 Gilbert Ndjatou Page 83 Static Variables Class or Interface Close Operation DO_NOTHING_ON_CLOSE WindowConstants interface (package javax.swing) Do not do anything when the user requests that the window close. Instead, the program should probably use a window listener that performs some other action in its windowClosing method. WindowConstants interface (package javax.swing) Hide the window when the user closes it. This removes the window from the screen but leaves it displayable. DISPOSE_ON_CLOSE WindowConstants interface (package javax.swing) Hide and dispose of the window when the user closes it. This removes the window from the screen and frees up any resources used by it. EXIT_ON_CLOSE JFrame Exit the application, using System.exit(0). HIDE_ON_CLOSE (the default) Notes: DISPOSE_ON_CLOSE is similar to EXIT_ON_CLOSE if there is only one window onscreen. The default close operation is executed after any window listeners handle the window-closing event. Besides handling window-closing events, window listeners can also react to other window state changes, such as iconification and activation. © 2011 Gilbert Ndjatou Page 84 Examples: 1. import java.awt.FlowLayout; import javax.swing.JFrame; public class CreateAFrame1 extends JFrame { . . . public CreateAFrame1( ) { // Step 1 Create the frame super( “Frame Title” ); //Step 2 Specify how components will be displayed in the frame setLayout( new FlowLayout( ) ); // Step 3 Create components and add them to the frame <to be done later> // Step 4 Specify what to do when the user closes the frame setDefaultCloseOperation (EXIT_ON_CLOSE ); . . . } } © 2011 Gilbert Ndjatou Page 85 2. import java.awt.FlowLayout; import javax.swing.JFrame; public class CreateAFrame2 { public static void createAFrame( ) { // Step 1 Create the frame JFrame frame = new JFrame ( “Frame Title” ); //Step 2 Specify how components will be displayed in the frame frame.setLayout( new FlowLayout( ) ); // Step 3 Create components and add them to the frame <to be done later> // Step 4 Specify what to do when the user closes the frame frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE ); . . . } } © 2011 Gilbert Ndjatou Page 86 5. Sizing the Frame You establish the frame size in one of the following ways: Explicitly by calling class JFrame’s instance method setSize or setBounds (which also sets the frame location). By calling class JFrame’s instance method void pack(void) which sizes the frame so that all its contents are or above their preferred sizes. Note: In general, using the pack instance method is preferable to calling the setSize instance method for the following reasons: pack leaves the frame layout manager in charge of the frame size, and layout managers are good at adjusting to platform dependencies and other factors that affect component size. 6. Setting the Frame Location (optional) You can set the location of a frame by using one of the JFrame class instance methods, setLocationRelativeTo or setLocation: void setLocation(int, int) void setLocationRelativeTo(Component) Set the location of the upper left corner of the window. The parameters are the x and y values, respectively. Position the window so that it is centered over the specified component. If the argument is null, the window is centered onscreen. To properly center the window, you should invoke this method after the window size has been set. 7. Showing the Frame In order to make a frame appear onscreen, you have to call the JFrame class’s instance method void setVisible with the argument true: setVisible(true). You may also use the void show(void) method instead. The two usages are equivalent, but we use setVisible(true) for consistency's sake. © 2011 Gilbert Ndjatou Page 87 Examples: 1. import java.awt.FlowLayout; import javax.swing.JFrame; public class CreateAFrame1 extends JFrame { . . . public CreateAFrame1( { ) // Step 1 Create the frame super( “Frame Title” ); //Step 2 Specify how components will be displayed in the frame setLayout( new FlowLayout( ) ); // Step 3 Create components and add them to the frame <to be done later> // Step 4 Specify what to do when the user closes the frame setDefaultCloseOperation (EXIT_ON_CLOSE ); // Step 5 Size the frame pack( ); // Step 6 Set the frame location setLocationRelativeTo( null ); // Step 7 show the frame setVisible(true); . . . } } © 2011 Gilbert Ndjatou Page 88 2. import java.awt.FlowLayout; import javax.swing.JFrame; public class CreateAFrame2 { public static void createAFrame( { ) // Step 1 Create the frame JFrame frame = new JFrame ( “Frame Title” ); //Step 2 Specify how components will be displayed in the frame frame.setLayout( new FlowLayout( ) ); // Step 3 Create components and add them to the frame <to be done later> // Step 4 Specify what to do when the user closes the frame frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE ); // Step 5 Size the frame frame.pack( ); // Step 6 Set the frame location frame.setLocationRelativeTo( null ); // Step 7 show the frame frame.setVisible(true); . . . } } © 2011 Gilbert Ndjatou Page 89 Setting a Frame Background Color Because the content pane completely hides the background, you change the background color by changing the content pane’s background color as flows: a. Use the instance method Container getContentPane(void) of the class JFrame to get a reference to the JFrame’s content pane and then b. Call the instance method void setBackground( Color bgcolor ) of the class Container (in package java.awt) on that object to set its color. You set the colors by using one of the following constant values in the static variables from the class Color (in package java.awt): Color.BLACK, Color.BLUE, Color.CYAN, Color.DARK_GRAY, Color.GRAY, Color.GREEN, Color.LIGHT_GRAY, Color.MAGENTA, Color.ORANGE, Color.PINK, Color.RED, Color.WHITE, Color.YELLOW. © 2011 Gilbert Ndjatou Page 90 Examples: 1. import java.awt.Color; import java.awt.Container; import java.awt.FlowLayout; import javax.swing.JFrame; public class CreateAFrame1 extends JFrame { . . . public CreateAFrame1( { ) // Step 1 Create the frame super( “Frame Title” ); //Step 2 Specify how components will be displayed in the frame setLayout( new FlowLayout( ) ); // Set frame background color to red Container contentPane = getContentPane( ); contentPane.setBackground( Color.RED ); // Step 3 Create components and add them to the frame <to be done later> // Step 4 Specify what to do when the user closes the frame setDefaultCloseOperation (EXIT_ON_CLOSE ); // Step 5 Size the frame pack( ); // Step 6 Set the frame location setLocationRelativeTo( null ); // Step 7 show the frame setVisible(true); . . . } } Note: The two statements: Container contentPane = getContentPane( ); and can be replaced with the following statement: contentPane.setBackground( Color.RED ); getContentPane( ).setBackground( Color.RED ); In this case, it would not be necessary to include the import statement: © 2011 Gilbert Ndjatou import java.awt.Container; Page 91 2. import java.awt.Color; import java.awt.Container; import java.awt.FlowLayout; import javax.swing.JFrame; public class CreateAFrame2 { public static void createAFrame( { ) // Step 1 Create the frame JFrame frame = new JFrame ( “Frame Title” ); //Step 2 Specify how components will be displayed in the frame frame.setLayout( new FlowLayout( ) ); // Set frame background color to red Container contentPane = frame.getContentPane( ); contentPane.setBackground( Color.RED ); // Step 3 Create components and add them to the frame <to be done later> // Step 4 Specify what to do when the user closes the frame frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE ); // Step 5 Size the frame frame.pack( ); // Step 6 Set the frame location frame.setLocationRelativeTo( null ); // Step 7 show the frame frame.setVisible(true); . . . } } Note: The two statements: Container contentPane = frame.getContentPane( ); contentPane.setBackground( Color.RED ); can be replaced with the statement: (frame.getContentPane( )).setBackground( Color.RED ); In this case, it would not be necessary to include the import statement: © 2011 Gilbert Ndjatou import java.awt.Container; Page 92 Creating a Custom Icon from an Image File Many Swing components, such as labels, buttons, and tabbed panes can be decorated with an icon which is a fixed-sized picture. You may also use your own custom icon on a top-level window, instead of the images used by the native windowing systems. You create an icon as an object of a class that implements the Icon interface. One implementation of the Icon interface named ImageIcon (from the javax.swing package) paints an icon from a GIF, JPEG, or PNG image file. In general, applications provide their own set of images to be used as part of the application. When this is the case, you should use the instance method getResource of the class Class to obtain the pathname of the image file: this allows the application to verify that the image is available and to provide sensible error handling if it is not. It returns the URL of the image file, and its signature (method header) is as follows: java.net.URL = getResource( <image-file-pathname>) When the image is not part of the application, getResource should not be used and the ImageIcon constructor is used directly on the image pathname. When specifying a file pathname, use the Internet-standard forward-slash ("/") as a separator (for example “images/myImage.gif”). The following constructors are provided to build icons from their URL or image files: Constructor Purpose ImageIcon( String filename ) Create an image icon from the specified file Create an image icon from the specified file; the second parameter is a textual description of the image that may be used for assistive technologies. Create an image icon from the specified URL location Create an image icon from the specified URL location; the second parameter is a textual description of the image that may be used for assistive technologies. ImageIcon( String filename, String description ) ImageIcon( URL location ) ImageIcon( URL location, String description ) Examples: 1. ImageIcon icon = new ImageIcon( ("images/myImage.gif"); 2. ImageIcon icon = new ImageIcon( (getClass( )).getResource("images/myImage.gif") ); © 2011 Gilbert Ndjatou Page 93 Creating a Frame with a Custom Icon You create a frame with a custom icon as follows: 1. Call the instance method Image getImage( ) of the class ImageIcon on the custom icon object in order to create the object of the class Image that corresponds to this icon. 2. Call the instance method void setIconImage( Image image ) of the class JFrame with the Image object above as argument to set the image to be displayed as the icon for this frame: setIconImage( image ); Example: // create a frame with title “Frame Title” and icon from the image file ("images/myImage.gif"); JFrame frame = new JFrame ( “Frame Title” ); ImageIcon icon = new ImageIcon( "images/myImage.gif" ); Image newImage = icon.getImage( ); frame.setIconImage( newImage ); © 2011 Gilbert Ndjatou Page 94 Examples: 1. import import import import javax.swing.ImageIcon; java.awt.Color; java.awt.FlowLayout; javax.swing.JFrame; public class CreateAFrame1 extends JFrame { . . . public CreateAFrame1( { ) // Step 1 Create the frame super( “Frame Title” ); //Step 2 Specify how components will be displayed in the frame setLayout( new FlowLayout( ) ); // Set frame background color to red getContentPane( ).setBackground( Color.RED ); // Set this frame custom icon to the image in the file “image\myImage.gif” ImageIcon myIcon = new ImageIcon( "images/myImage.gif"); setIconImage( myIcon.getImage( ) ); // Step 3 Create components and add them to the frame <to be done later> // Step 4 Specify what to do when the user closes the frame setDefaultCloseOperation (EXIT_ON_CLOSE ); // Step 5 Size the frame pack( ); // Step 6 Set the frame location setLocationRelativeTo( null ); // Step 7 show the frame setVisible(true); . . . } } © 2011 Gilbert Ndjatou Page 95 2. import import import import javax.swing.ImageIcon; java.awt.Color; java.awt.FlowLayout; javax.swing.JFrame; public class CreateAFrame2 { public static void createAFrame( { ) // Step 1 Create the frame JFrame frame = new JFrame ( “Frame Title” ); //Step 2 Specify how components will be displayed in the frame frame.setLayout( new FlowLayout( ) ); // Set frame background color to red (frame.getContentPane( )).setBackground( Color.RED ); // Set this frame custom icon to the image in the file “image\myImage.gif” ImageIcon myIcon = new ImageIcon( "images/myImage.gif" ); frame.setIconImage( myIcon.getImage( ) ); // Step 3 Create components and add them to the frame <to be done later> // Step 4 Specify what to do when the user closes the frame frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE ); // Step 5 Size the frame frame.pack( ); // Step 6 Set the frame location frame.setLocationRelativeTo( null ); // Step 7 show the frame frame.setVisible(true); . . . } } © 2011 Gilbert Ndjatou Page 96 Adding Components Component classes are subclasses of the JComponent class and text components also have a font that is created by using the class Font. Creating Font Objects The constructor of the class Font (package java.awt) is specified as follows: public Font(String name, int style, int size) It creates a new font from the specified name, style, and point size. Font Names The font name can be a font face name or a font family name. A font face is a name from a collection of font faces that are present in the system resources of the host system. Examples of Font Faces on IBM PC: Arial Calibri Serif Cambria Courier Century Arial Bold Century Gothic Courier Bold Italic Roman Font Style You specify the font style by using one of the following static final variables of the class Font: Font.PLAIN (for plain text) Font.ITALIC (for text in italic) Font.BOLD (for bold faced text) Font.BOLD | Font.ITALIC (for text in bold and italic) Font Size The parameter Size is the font size (in point): examples 10, 12, 14, 20, 24. Examples Font plainFont = new Font(“Serif”, Font.PLAIN, 24); Font boldFont = new Font(“Helvetica”, Font.BOLD, 30); Font boldItalicFont = new Font(“Serif”, Font.BOLD | Font.ITALIC, 24); © 2011 Gilbert Ndjatou Page 97 JComponent Methods The following JComponent class instance methods are commonly used on all components: Method Purpose void setForeground(Color) void setBackground(Color) Set the foreground or background color for the component. The foreground is generally the color used to draw the text in a component. The background is (not surprisingly) the color of the background areas of the component, assuming that the component is opaque. Get the foreground or background color for the component. void setOpaque(boolean) boolean isOpaque() Set or get whether the component is opaque. An opaque component fills its background with its background color. void setFont(Font) Font getFont() Set or get the component's font. If a font has not been set for the component, the font of its parent is returned. void setToolTipText(String) Set the text to display in a tool tip. It turns off the tool tip if the argument is null. Set or get the name of the component. This can be useful when you need to associate text with a component that does not display text. Determine whether the component is showing on screen. This means that the component must be visible, and it must be in a container that is visible and showing. Color getForeground() Color getBackground() void setName(String) String getName() boolean isShowing() void setEnabled(boolean) boolean isEnabled() Set or get whether the component is enabled. An enabled component can respond to user input and generate events. void setVisible(boolean) boolean isVisible() Set or get whether the component is visible Components are initially visible, with the exception of top-level components. void addComponentListener(ComponentListener) void removeComponentListener(ComponentListener) © 2011 Gilbert Ndjatou Add or remove a component listener to or from the component. Component listeners are notified when the listened-to component is hidden, shown, moved, or resized. Page 98 JLabel Component Use or extend class JLabel (package javax.swing) to create a component that displays: a string, an image, or both. The following table lists the commonly used JLabel constructors and methods. Other methods that you are likely to call are the instance methods of the JComponent class. Setting or Getting the Label's Contents Constructor Purpose JLabel(Icon) JLabel(Icon, int) JLabel(String) JLabel(String, Icon, int) JLabel(String, int) JLabel() © 2011 Gilbert Ndjatou Creates a JLabel instance, initializing it to have the specified text/image/alignment. The int argument specifies the horizontal alignment of the label's contents within its drawing area. The horizontal alignment must be one of the following static variables defined in the SwingConstants interface (which JLabel implements): LEFT, CENTER, RIGHT, LEADING, or TRAILING. For ease of localization, we strongly recommend using LEADING and TRAILING, rather than LEFT and RIGHT. Page 99 Method Description Sets or gets the text displayed by the label. You can use HTML tags to format the text, as described in Using HTML in Swing Components. void setIcon(Icon) Icon getIcon() Sets or gets the image displayed by the label. void setLabelFor(Component) Component getLabelFor( ) Sets or gets which component the label describes. Sets or gets the area on the label where its contents should be placed. The values these alignments are defined as static variables in the SwingConstants interface: for horizontal alignments: LEFT, CENTER (the default for image-only labels), RIGHT, LEADING (the default for text-only labels), TRAILING. For vertical alignment: TOP, CENTER (the default), and BOTTOM. void setText(String) String getText() void setHorizontalAlignment(int) void setVerticalAlignment(int) int getHorizontalAlignment( ) int getVerticalAlignment( ) void setHorizontalTextPosition(int) void setVerticalTextPosition(int) int getHorizontalTextPosition() int getVerticalTextPosition() void setIconTextGap(int) int getIconTextGap() © 2011 Gilbert Ndjatou Sets or gets the location where the label's text will be placed, relative to the label's image. The SwingConstants interface defines five possible values for horizontal position: LEADING, LEFT, CENTER, RIGHT, and TRAILING (the default). For vertical position: TOP, CENTER (the default), and BOTTOM. Sets or gets the number of pixels between the label's text and its image. Page 100 Example L1 1. /*--------- create a label with text only and add it to a frame---------------*/ import java.awt.FlowLayout; import javax.swing.JFrame; import javax.swing.JLabel; class LabelFrame1A extends JFrame { private JLabel plainLabel; public LabelFrame1A( ) { super( “My First Label” ); FlowLayout layout = new FlowLayout( ); setLayout( layout ); // Step 1 //Step 2 /*---create components and add them to the frame--*/ // Step 3 plainLabel = new JLabel( “My first label with text only”); plainLabel.setToolTipText(“This is plainLabel”); add(plainLabel); setDefaultCloseOperation (EXIT_ON_CLOSE ); pack( ); setLocationRelativeTo( null ); setVisible(true); // Step 4 // Step 5 // Step 6 // Step 7 } } public class TestLabel1A { public static void main( String[ ] args ) { LabelFrame1A labelFrame = new LabelFrame1A ( ); } } © 2011 Gilbert Ndjatou Page 101 2. /*--------- create a label with text only and add it to a frame---------------*/ import java.awt.FlowLayout; import javax.swing.JFrame; import javax.swing.JLabel; public class LabelFrame1B { public static void main( String[ ] args ) { JFrame frame = new JFrame ( “My First Label”); // Step 1 FlowLayout layout = new FlowLayout( ); frame.setLayout( layout ); // Step 2 /*---create components and add them to the frame--*/ JLabel plainLabel = new JLabel( “Label with text only”); plainLabel.setToolTipText(“This is plainLabel”); frame.add(plainLabel); // Step 3 frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE ); frame.pack( ); frame.setLocationRelativeTo( null ); frame.setVisible(true); // Step 4 // Step 5 // Step 6 // Step 7 } } © 2011 Gilbert Ndjatou Page 102 Example L2 Using Foreground Color and Font /*--------- create a label with text only 30 point red and add it to a frame---------------*/ /*----------The frame is created using an extension of the class JFrame------------------*/ /*----------But Steps 4, 5, 6, and 7 are specified in the method main ---------------------*/ import java.awt.Font; import java.awt.Color; import java.awt.FlowLayout; import javax.swing.JFrame; import javax.swing.JLabel; class LabelFrame2 extends JFrame { private JLabel fancyLabel; public LabelFrame2( ) { super( “My Fancy Label” ); FlowLayout layout = new FlowLayout( ); setLayout( layout ); // Step 1 //Step 2 /*---create components and add them to the frame--*/ // Step 3 fancyLabel = new JLabel( “My fancy label in 30 point red”); Font font = new Font(“Serif”, Font.PLAIN, 30); fancyLabel.setFont( font ); fancyLabel.setForeground( Color.RED ); fancyLabel.setToolTipText(“This is plainLabel”); add(fancyLabel); } } public class TestLabel2 { public static void main( String[ ] args ) { LabelFrame2 labelFrame2 = new LabelFrame2 ( ); labelFrame2.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE ); labelFrame2 .pack( ); labelFrame2 .setLocationRelativeTo( null ); labelFrame2 setVisible(true); // Step 4 // Step 5 // Step 6 // Step 7 } } © 2011 Gilbert Ndjatou Page 103 Example L3 Creating a Frame with a Custom Icon and Background Color /*--------- create a frame with a custom icon and an orange background color and add a label with text only to it----------------------------------------------*/ /*----------The frame is created by using an extension of the class JFrame-------------*/ /*----------But Steps 4, 5, 6, and 7 are specified in the method main ---------------------*/ import java.awt.Color; import javax.swing.Icon; import javax.swing.ImageIcon; import java.awt.FlowLayout; import javax.swing.JFrame; import javax.swing.JLabel; class LabelFrame3 extends JFrame { private JLabel plainLabel; public LabelFrame3( ) { super( “Frame With Custom Icon and Background Color” ); FlowLayout layout = new FlowLayout( ); setLayout( layout ); // Step 1 //Step 2 /*--- Set frame background color to orange --------------*/ getContentPane( ).setBackground( Color.ORANGE ); /*-- Set this frame custom icon to the image in the file “bug1.gif” --*/ ImageIcon icon = new ImageIcon("bug1.gif") ); setIconImage( icon.getImage( ) ); /*---create components and add them to the frame--*/ // Step 3 plainLabel = new JLabel( “A simple label with text only”); add(plainLabel); } } public class TestLabel3 { public static void main( String[ ] args ) { LabelFrame3 labelFrame = new LabelFrame3 ( ); labelFrame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE ); labelFrame .pack( ); labelFrame .setLocationRelativeTo( null ); labelFrame.setVisible(true); // Step 4 // Step 5 // Step 6 // Step 7 } } © 2011 Gilbert Ndjatou Page 104 Example L4 Labels with Text and Icons /*--------- create two labels with icons -------------------------------------------------------*/ /*----------The frame is created by using an extension of the class JFrame-------------*/ /*----------But Steps 4, 5, 6, and 7 are specified in the method main --------------------*/ import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.SwingConstants; import java.awt.FlowLayout; import javax.swing.JFrame; import javax.swing.JLabel; class LabelFrame4 extends JFrame { private JLabel label1; private JLabel label2; public LabelFrame4( ) { super( “Frame With Two Labels with Text and Icons” ); FlowLayout layout = new FlowLayout( ); setLayout( layout ); // Step 1 //Step 2 /*-- Get the icon from the image in the file “bug1.gif” --*/ ImageIcon icon = new ImageIcon("bug1.gif" ); /*---create components and add them to the frame--*/ // Step 3 label1 = new JLabel( “label with text and icon”, icon, SwingConstants.LEFT); add( label1 ); label2 = new JLabel( ); label2.setText( “Label with icon and text at bottom” ); //add text to label label2.setIcon( icon ); // add icon to it label2.setHorizontalTextPosition( SwingConstants.CENTER ); label2.setVerticalTextPosition( SwingConstants.BOTTOM ); add( label2 ); } } © 2011 Gilbert Ndjatou Page 105 public class TestLabel4 { public static void main( String[ ] args ) { LabelFrame4 labelFrame = new LabelFrame4 ( ); labelFrame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE ); labelFrame .pack( ); labelFrame .setLocationRelativeTo( null ); labelFrame.setVisible(true); // Step 4 // Step 5 // Step 6 // Step 7 } } Hands-On Exercise GUI4 Type and execute the programs in examples L1, L2, L3, and L4 (use your own image files). Exercise GUI4 Write a program that creates a frame with the following characteristics: The title of the frame is “My First Window”. The window icon is created from the image file bug2.jif. (or use your own image file) Its background color is white. Add to this frame a label consisting of your name in blue, serif font in 24 point. Add to this frame a label consisting of the icon of the image in the image file bug.png (or use your own image file). This label has the tooltiptext “a bug”. Add to this frame a label consisting of the icon of the image in the image file bug1.gif (or use your own image file) and the text “This is a bug” on the left of the icon. The text is also centered. © 2011 Gilbert Ndjatou Page 106 Handling Events Some GUI components are sources of one or more events. An event occurs on a GUI component as a result of the interaction between the user and that component: For example: when the user enter text in a GUI component and then press the Enter key; when the user click the mouse on a GUI component; when the user select an item from a list; or when the user drag the mouse on a GUI component. Each java event type is represented by a class called event class and, When an event occurs on a GUI component, java creates an object instance of the corresponding event class to hold the information about that event. Java also has one or more event listener interfaces for each event class (type). You must provide the definitions of the abstract methods in an event listener interface (implement the event listener interface) so that events are handled in the way that you want whenever they occur. You must follow the following steps to set up event handling for a GUI component: Step 1: Implement one or more event listener interfaces that correspond to this event type. class <event-class-handler> implements <listener-interface> { <definitions-of-the-abstract-methods> } Step 2: Create an object of each class that implements the event listener interfaces in step 1: this object is referred to as the event handler. <Event-class-handler> < handler-name> Step 3: = new <Event-class-handler>( ); Register each event handler by passing it as an argument to one of the add methods of the GUI component. <component-object>.<add-method>( <handler-name>); © 2011 Gilbert Ndjatou Page 107 Notes: 1. Steps 1, 2, and 3 can be performed in one step by using an anonymous class as follows: <component-object>.<add-method> ( new <interface-name>( ) { <definitions-of-the-abstract-methods> } ); 2. Steps 1, 2, and 3 can also be performed in two steps by using an anonymous class as follows: <interface-name> <handler-name> = new <interface-name>( ) { <definitions-of-the-abstract-methods> } <component-object>.<add-method>( <handler-name>); The following event types will be discussed: Action event Item event List selection event Key event © 2011 Gilbert Ndjatou Page 108 Action Event An action event occurs, whenever an action is performed by the user on certain components: for examples when the user clicks a button, chooses a menu item, or presses Enter in a text field. When an action event occurs on a component, an actionPerformed message is sent to all action listeners that are registered on that component. Event Class: ActionEvent Method (package: java.awt.event) Purpose String getActionCommand( ) Returns the string associated with this action. Most objects that can fire action events support a method called setActionCommand that lets you set this string. Returns an integer representing the modifier keys the user was pressing when the action event occurred. You can use the ActionEvent-defined constants SHIFT_MASK, CTRL_MASK, META_MASK, and ALT_MASK to determine which keys were pressed. For example, if the user Shift-selects a menu item, then the following expression is nonzero: actionEvent.getModifiers() & ActionEvent.SHIFT_MASK int getModifiers( ) Object getSource( ) (in java.util.EventObject) Event Listener Interface: Returns the reference of the object that fired the event. ActionListener (package: java.awt.event) Method Purpose void actionPerformed( actionEvent e) Called just after the user performs an action. Add Method (to register event handlers): © 2011 Gilbert Ndjatou void addActionListener( <handler> ) Page 109 The following components are sources of an action event: JTextField, JPasswordField, and JButton. © 2011 Gilbert Ndjatou Page 110 JTextField A text field is a basic text control that enables the user to type a small amount of text. You create a text field by using the class JTextField (package: javax.swing) When the user indicates that text entry is complete (usually by pressing Enter), the text field fires an action event. The following are instance methods of the class JTextField (package: javax.swing): Method or Constructor Purpose JTextField() JTextField(String) JTextField(String, int) JTextField(int) void setText(String) String getText() (defined in JTextComponent) void setEditable(boolean) boolean isEditable() (defined in JTextComponent) void setColumns(int); int getColumns() Creates a text field. When present, the int argument specifies the desired width in columns. The String argument contains the field's initial text. Sets or obtains the text displayed by the text field. Sets or indicates whether the user can edit the text in the text field. Sets or obtains the number of columns displayed by the text field. This is really just a hint for computing the field's preferred width. void setHorizontalAlignment(int); int getHorizontalAlignment() Sets or obtains how the text is aligned horizontally within its area. You can use JTextField.LEADING, JTextField.CENTER, and JTextField.TRAILING for arguments. Note: The getActionCommand( ) instance method of the class ActionEvent (package: the text typed by the user. © 2011 Gilbert Ndjatou java.awt.event) returns Page 111 Example T1 /*------- create a frame and add an editable text field to it: the text typed by the user is displayed in a message dialog -------------------------------*/ import java.awt.FlowLayout; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JTextField; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; class TextFieldFrame1 extends JFrame { private JTextField textField; public TextFieldFrame1 ( ) { super( “My First text field” ); // Step 1 FlowLayout layout = new FlowLayout( ); setLayout( layout ); //Step 2 /*---create components and add them to the frame--*/ textField = new JTextField( “Enter editable text here”); textField.setToolTipText(“This is my first text field”); add(textField); // Step 3 /*--------------------- register the event handler ---------------------*/ TextFieldHandler handler = new TextFieldHandler( ); textField.addActionListener( handler ); } /*----------------------- inner class for event handling ------------------------------*/ class TextFieldHandler implements ActionListener { public void actionPerformed( ActionEvent event ) { /*-------------- get the string typed by the user -----------------------*/ String st = event.getActionCommand( ); /*--------------------------Display the message dialog ------------------------*/ JOptionPane.showMessageDialog( TextFieldFrame1.this , st ); } } } © 2011 Gilbert Ndjatou Page 112 public class TestTextField1 { public static void main( String[ ] args ) { TextFieldFrame1 textFieldFrame = new TextFieldFrame1 ( ); textFieldFrame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE ); textFieldFrame.pack( ); textFieldFrame.setLocationRelativeTo( null ); textFieldFrame.setVisible(true); } } Before text is entered // Step 4 // Step 5 // Step 6 // Step 7 After Text is entered Note: Event handling could have been implemented (using an anonymous class) in one of the following two ways: 1. TextFieldHandler handler = new ActionListener( ) { public void actionPerformed( ActionEvent event ) { /*-------------- get the string typed by the user -----------------------*/ String st = event.getActionCommand( ); /*--------------------------Display the message dialog ------------------------*/ JOptionPane.showMessageDialog( TextFieldFrame1.this , st ); } } textField.addActionListener( handler ); 2. textField.addActionListener( new ActionListener( ) { public void actionPerformed( ActionEvent event ) { /*-------------- get the string typed by the user -----------------------*/ String st = event.getActionCommand( ); /*--------------------------Display the message dialog ------------------------*/ JOptionPane.showMessageDialog( TextFieldFrame1.this , st ); } } ); © 2011 Gilbert Ndjatou Page 113 Example T2 /*------- create a frame and add two text fields to it: the first is not editable and the second is editable with a desired width of 30. The text typed by the user is displayed along with the name of the text field object in a message dialog --------------------------------------------------------*/ import java.awt.FlowLayout; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JTextField; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; class TextFieldFrame2 extends JFrame { private JTextField textField1; private JTextField textField2; public TextFieldFrame2 ( ) { super( “My other text fields” ); // Step 1 FlowLayout layout = new FlowLayout( ); setLayout( layout ); //Step 2 /*---create components and add them to the frame--*/ textField1 = new JTextField( “Enter text here”); textField1.setEditable( false ); add(textField1); textField2 = new JTextField( 30 ); add(textField2); // Step 3 /*----create an action event handler and register it to each text field -----*/ TextFieldHandler handler = new TextFieldHandler( ); textField1.addActionListener( handler ); textField2.addActionListener( handler ); } /*-----------------------private inner class for action event handling ---------*/ private class TextFieldHandler implements ActionListener { public void actionPerformed( ActionEvent event ) { /*-------------- get the string typed by the user -----------------------*/ String st = event.getActionCommand( ); /*------- find out the TextField object source of this event ---------*/ JTextField source = (JTextField)event.getSource( ); © 2011 Gilbert Ndjatou Page 114 /*---------------build the string to display in the message dialog ---------*/ if( source == textField1 ) st = “ textField1:\t” + st; else st = “ textField2:\t” + st; /*--------------------------Display the message dialog ------------------------*/ JOptionPane.showMessageDialog( TextFieldFrame2.this , st ); } } } public class TestTextField2 { public static void main( String[ ] args ) { TextFieldFrame2 textFieldFrame = new TextFieldFrame2 ( ); textFieldFrame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE ); textFieldFrame.pack( ); textFieldFrame.setLocationRelativeTo( null ); textFieldFrame.setVisible(true); } } Before any field is selected // Step 4 // Step 5 // Step 6 // Step 7 After clicking the first field and then pressing Enter After entering text in the second field and then pressing Enter © 2011 Gilbert Ndjatou Page 115 JPasswordField A JPasswordField is a subclass of JTextField that provides specialized text fields for password entry. For security reasons, a password field does not show the characters that the user types. Instead, the field displays a character different from the one typed, such as an asterisk '*'. As another security precaution, a password field stores its value as an array of characters, rather than as a string Like an ordinary text field, a password field fires an action event when the user indicates that text entry is complete, for example by pressing the Enter key. The following are instance methods of the class JPasswordField (package: javax.swing): Commonly Used JPasswordField Constructors and Methods Constructor or Method Purpose JPasswordField() JPasswordField(String) JPasswordField(String, int) JPasswordField(int) JPasswordField(Document, String, int) Creates a password field. When present, the int argument specifies the desired width in columns. The String argument contains the field's initial text. The Document argument provides a custom model for the field. char[ ] getPassword( ) Returns the password as an array of characters. void setEchoChar(char) char getEchoChar() Sets or gets the echo character which is displayed instead of the actual characters typed by the user. void addActionListener(ActionListener) void removeActionListener(ActionListener) (defined in JTextField) Adds or removes an action listener. void selectAll( ) (defined in JTextComponent) Selects all characters in the password field. © 2011 Gilbert Ndjatou Page 116 Example P1 /*------- create a frame and add a password field to it. The password field is labeled with the text: Enter password. After the password is entered by the user, a message dialog displays the message displayed in the password field */ import java.awt.FlowLayout; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JPasswordField; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import javax.swing.JLabel; class PasswordFieldFrame extends JFrame { private JPasswordField passwordField; private JLabel label; public PasswordFieldFrame ( ) { super( “Password Processing” ); // Step 1 FlowLayout layout = new FlowLayout( ); setLayout( layout ); //Step 2 /*---create components and add them to the frame--*/ passwordField = new JPasswordField( “Hidden text” , 15 ); label = new JLabel( “Enter Password” ); label.setLabelFor( passwordField ); add( label ); add( passwordField ); // Step 3 /*----create an action event handler (object) and register it to the password field ---*/ PasswordFieldHandler handler = new PasswordFieldHandler ( ); passwordField.addActionListener( handler ); } /*----------------------- inner class for action event handling ------------------------------*/ class PasswordFieldHandler implements ActionListener { public void actionPerformed( ActionEvent event ) { /*-------------- get the string displayed in the field -----------------------*/ String st = event.getActionCommand( ); /*--------------------------Display the message dialog ------------------------*/ JOptionPane.showMessageDialog( PasswordFieldFrame.this , st ); } } } © 2011 Gilbert Ndjatou Page 117 public class TestPasswordField { public static void main( String[ ] args ) { PasswordFieldFrame passwordFieldFrame = new PasswordFieldFrame ( ); passwordFieldFrame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE ); passwordFieldFrame.pack( ); passwordFieldFrame.setLocationRelativeTo( null ); passwordFieldFrame.setVisible(true); } } Before the password is entered // Step 4 // Step 5 // Step 6 // Step 7 After the password is entered Hands-On Exercise GUI5 Type and execute the programs in examples T1, T2, and P1. Exercise GUI5 Write a program that creates a frame with the title “Login Window”. It then adds to it a text field consisting of 15 columns labeled (to the left) with the label “Enter Username”. After the user has entered the username and then pressed the Enter key, it displays a password field consisting of 10 columns labeled (to the left) with the label “Enter Password”. After the user has entered the password and then pressed the Enter key it compares the typed password against a constant password and if they are equal, it displays a message dialog with the message “Successful login”. Otherwise, it displays a message dialog with the message “Unsuccessful login. Try again”. Extra Credit: Rewrite the program such that the text field and the password field are added to the frame before the user enters the username and the password. Note that the username and the password may be entered in any order. In order to do this, you need a counter (static variable) that is incremented by 1 every time the user enters the username or the password. The password is checked only if the value of the counter is 2. You also need only one action handler for both the text field and the password field. © 2011 Gilbert Ndjatou Page 118 Buttons A button is a component that the user click in order to trigger a specific action. A button may display text, an image icon, or both. Several types of buttons are available in java, including the ones that follows: Command buttons Checkboxes Radio buttons, and Toggle buttons. You create a command button by using the class JButton (package: javax.swing) A checkbox is created by using the class JCheckBox (package: javax.swing) A radio button is created by using the class JRadioButton (package: javax.swing), and A toggle button is created by using the class JToggleButton (package: javax.swing). Classes JButton and JToggleButton are subclasses of the abstract class AbstractButton, and classes JCheckBox and JRadioButton are subclasses of JToggleButton. A JToggleButton instance is similar to a JButton, but with two states. Normally, you use a JRadioButton or JCheckBox instead of directly instantiating JToggleButton, But JToggleButton can be useful when you do not want the typical radio button or check box appearance. Note: You can use the tool bars to collect a group of buttons into a row or column. The following methods are instance methods of all classes that implement buttons. © 2011 Gilbert Ndjatou Page 119 Method void setText(String) String getText() void setIcon(Icon) Icon getIcon() void setDisabledIcon(Icon) Icon getDisabledIcon() void setSelectedIcon(Icon) Icon getSelectedIcon() void setDisabledSelectedIcon(Icon) Icon getDisabledSelectedIcon() void setPressedIcon(Icon) Icon getPressedIcon() void setRolloverIcon(Icon) Icon getRolloverIcon() void setRolloverSelectedIcon(Icon) Icon getRolloverSelectedIcon() void setSelected(boolean) boolean isSelected( ) void setHorizontalAlignment(int) void setVerticalAlignment(int) int getHorizontalAlignment() int getVerticalAlignment() void setHorizontalTextPosition(int) void setVerticalTextPosition(int) int getHorizontalTextPosition() int getVerticalTextPosition() Purpose Set or get the text displayed by the button. You can use HTML formatting, as described in Using HTML in Swing Components. Set or get the image displayed by the button when the button isn't selected or pressed. Set or get the image displayed by the button when it is disabled. If you do not specify a disabled image, then the look and feel creates one by manipulating the default image. Set or get the image displayed by the button when it is selected. If you do not specify a disabled selected image, then the look and feel creates one by manipulating the selected image. Set or get the image displayed by the button when it is being pressed. Make the button display the specified (rollover ) icon when the cursor passes over it. Make the button display the specified (rollover ) icon when the button is selected: this is useful for two-state buttons such as toggle buttons. Set or get whether the button is selected. Makes sense only for buttons that have on/off state, such as check boxes. Set or get where in the button its contents should be placed. The AbstractButton class allows any one of the following values for horizontal alignment: RIGHT, LEFT, CENTER (the default), LEADING, and TRAILING. For vertical alignment: TOP, CENTER (the default), and BOTTOM. Set or get where the button's text should be placed, relative to the button's image. The AbstractButton class allows any one of the following values for horizontal position: LEFT, CENTER, RIGHT, LEADING, and TRAILING (the default). For vertical position: TOP, CENTER (the default), and BOTTOM. void setIconTextGap(int) int getIconTextGap() Set or get the amount of space between the text and the icon displayed in this button. void setMargin(Insets) Insets getMargin() Set or get the number of pixels between the button's border and its contents. Set or get the keyboard alternative to clicking the button. One form of the setMnemonic method accepts a character argument; however, the Swing team recommends that you use an int argument instead, specifying a KeyEvent.VK_X constant. void setMnemonic(int) char getMnemonic() © 2011 Gilbert Ndjatou Page 120 JButton You create a command button by using the JButton (package: javax.swing) class. JButton component (command button) fires an action event when the user clicks it. The picture of an application that displays three buttons with text and icon follows: The underlined letter in each button's text shows the mnemonic — the keyboard alternative — for each button. In most look and feels, the user can click a button by pressing the Alt key and the mnemonic. For example, Alt-M would click the Middle button in the ButtonDemo window above. When a button is disabled, the look and feel automatically generates the button's disabled appearance. However, you could provide an image to be substituted for the normal image. For example, you could provide gray versions of the images used in the left and right buttons. The following constructors are provided to create and initialize command buttons with text, image, or both: Constructor Purpose JButton(String, Icon) JButton(String) JButton(Icon) JButton( ) Create a JButton instance, Initialize it to have the specified text/image/action. Note: The getActionCommand( ) instance method of the class ActionEvent (package: the text on the button selected. © 2011 Gilbert Ndjatou java.awt.event) returns Page 121 Example B1 /*---- create two command buttons (JButton), one with text only, and another one with text and icon */ /*--- also set the keyboard alternative to clicking the button import java.awt.FlowLayout; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import javax.swing.JFrame; import javax.swing.JButton; import javax.swing.ImageIcon; import javax.swing.JOptionPane; class ButtonFrame extends JFrame { private JButton plainJButton; private JButton fancyJButton; // button with just text // button with icons public ButtonFrame( ) { super( "Testing Buttons" ); setLayout( new FlowLayout( ) ); // create buttons and add them to the frame plainJButton = new JButton( "Plain Button" ); plainJButton.setMnemonic(KeyEvent.VK_P); add( plainJButton ); // set frame layout // button with text // set keyboard alternative // add plainJButton to JFrame ImageIcon bug1 = new ImageIcon( "bug1.gif" ); ImageIcon bug2 = new ImageIcon( getClass( ).getResource( "bug2.gif" ) ); fancyJButton = new JButton( "Fancy Button", bug1 ); fancyJButton.setRolloverIcon( bug2 ); fancyJButton.setMnemonic(KeyEvent.VK_F); add( fancyJButton ); // set image // set rollover image // set keyboard alternative // add fancyJButton to JFrame // create an action event handler (object) and register it to both JButton objects ButtonHandler handler = new ButtonHandler( ); fancyJButton.addActionListener( handler ); plainJButton.addActionListener( handler ); } // end ButtonFrame constructor © 2011 Gilbert Ndjatou Page 122 // inner class for action event handling private class ButtonHandler implements ActionListener { // handle action event public void actionPerformed( ActionEvent event ) { JOptionPane.showMessageDialog( ButtonFrame.this, String.format("You pressed: %s", event.getActionCommand( ) ) ); } // end method actionPerformed } // end private inner class ButtonHandler } // end class ButtonFrame public class ButtonTest { public static void main( String[] args ) { ButtonFrame buttonFrame = new ButtonFrame( ); buttonFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); buttonFrame.pack( ); buttonFrame.setVisible( true ); } // end main } // end class ButtonTest // create ButtonFrame // set frame size // display frame Window after it has been created Window with the mouse resting on the fancy icon After the Plain Button is clicked After the Fancy Button is clicked © 2011 Gilbert Ndjatou Page 123 Using the BorderLayout Manager The border layout manager (which is the default layout for a JFrame) is implemented by the class BorderLayout (package java.awt) It arranges components into five regions specified by the static variables of class BorderLayout as follows: top (NORTH), bottom (SOUTH), left (EAST), right (WEST), and center (CENTER) One of its constructors is BorderLayout(int hgap, int vgap) where hgap is the number of pixels between components that are arranged horizontally, and vgap is the number of pixels between components that are arranged vertically. The default is 1 pixel. It limits a container to containing at most five components. When you add a component to a container, you have to specify also the region where it must be added (using one of the static variable above); otherwise, it will be added to the center. Example: frame.add(component, BorderLayout.NORTH); What to do After a Frame Layout has been adjusted After a frame’s layout has been adjusted (the number of components has changed), you may do one of the following things: Call the instance method void layoutContainer(Container ) of the LayoutManager interface to specify that the JFrame’s container should be rearranged based on the adjusted layout. Example: button.setVisible( false ); layout.layoutContainer( frame.getContentPane( ) ); // hide this button //rearrange the JFrame Call the instance method void validate( ) of the class Container (package: java.awt) to recompute the container’s layout based on the current layout manager for the Container and the current set of displayed GUI components. © 2011 Gilbert Ndjatou Page 124 Example: button.setVisible( false ); ( frame.getContentPane( ) ).validate( ); // hide this button //rearrange the JFrame Example BL1 The following application creates five JButtons with text, "Hide North", "Hide South", "Hide East", "Hide West", and "Hide Center" respectively. Each JButton is placed in the frame using the BorderLayout in the implied location. When the user clicks one of the buttons, it is made invisible, and the content pane layout is reorganized. We use to class that creates the frame to also implement the ActionListener interface. // Demonstrating BorderLayout. import java.awt.BorderLayout; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import javax.swing.JFrame; import javax.swing.JButton; class BorderLayoutFrame extends JFrame implements ActionListener { private JButton[] buttons; // array of buttons to hide portions private static final String[] names = { "Hide North", "Hide South", "Hide East", "Hide West", "Hide Center" }; private BorderLayout layout; // borderlayout object // set up GUI and event handling public BorderLayoutFrame( ) { super( "BorderLayout Demo" ); // create a border layout with 5 pixels gap between the components and set it to the frame layout = new BorderLayout( 5, 5 ); // 5 pixel gaps setLayout( layout ); // set frame layout // create an array of five JButtons references buttons = new JButton[ 5 ]; // create JButtons and register listeners for them for ( int count = 0; count < 5; count++ ) { buttons[ count ] = new JButton( names[ count ] ); // create this JButton buttons[ count ].addActionListener( this ); // register the current object (event handler) to this JButton } // end for © 2011 Gilbert Ndjatou Page 125 // add all the JButtons to the frame add( buttons[ 0 ], BorderLayout.NORTH ); add( buttons[ 1 ], BorderLayout.SOUTH ); add( buttons[ 2 ], BorderLayout.EAST ); add( buttons[ 3 ], BorderLayout.WEST ); add( buttons[ 4 ], BorderLayout.CENTER ); } // end BorderLayoutFrame constructor // add button to north // add button to south // add button to east // add button to west // add button to center // How to handle the ActionEvent for each JButtons public void actionPerformed( ActionEvent event ) { // check event source and layout content pane correspondingly for ( JButton button : buttons ) { if ( event.getSource( ) == button ) button.setVisible( false ); // hide button clicked else button.setVisible( true ); // show other buttons } // end for // rearrange the components in the frame layout.layoutContainer( getContentPane( ) ); } // end method actionPerformed } // end class BorderLayoutFrame // Testing BorderLayoutFrame. public class BorderLayoutDemo { public static void main( String[] args ) { BorderLayoutFrame borderLayoutFrame = new BorderLayoutFrame(); borderLayoutFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); borderLayoutFrame.pack( ); // set frame size borderLayoutFrame.setVisible( true ); // display frame } // end main } // end class BorderLayoutDemo © 2011 Gilbert Ndjatou Page 126 Using the GridLayout Manager The grid layout manager is implemented by the class GridLayout (package java.awt). It arranges components into rows and columns. One of its constructors is GridLayout(int numRow, int numCol, int hgap, int vgap) where numRow is the number of rows, numCol is the number of columns, hgap is the number of pixels between components that are arranged horizontally, and vgap is the number of pixels between components that are arranged vertically. The default is 1 pixel. Example GL1 The following application creates a frame with 6 JButtons (command buttons). It also defines two GridLayout managers one with 3 rows and 2 columns, and another with 2 rows and 3 columns. When the user clicks one of the buttons, the buttons are reorganized using the other layout manager. We use to class that creates the frame to also implement the ActionListener interface. © 2011 Gilbert Ndjatou Page 127 // Demonstrating GridLayout. import java.awt.GridLayout; import java.awt.Container; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import javax.swing.JFrame; import javax.swing.JButton; class GridLayoutFrame extends JFrame implements ActionListener { private JButton[] buttons; // array of buttons private static final String[] names = { "one", "two", "three", "four", "five", "six" }; private boolean toggle = true; // toggle between two layouts private Container container; // frame container private GridLayout gridLayout1; // first gridlayout private GridLayout gridLayout2; // second gridlayout // no-argument constructor public GridLayoutFrame( ) { super( "GridLayout Demo" ); gridLayout1 = new GridLayout( 2, 3, 5, 5 ); gridLayout2 = new GridLayout( 3, 2 ); container = getContentPane( ); setLayout( gridLayout1 ); // 2 by 3; gaps of 5 // 3 by 2; no gaps // get content pane // set JFrame layout // create an array of six JButtons references buttons = new JButton[ 6 ]; // create 6 JButtons and register listeners for them for ( int count = 0; count < 6; count++ ) { buttons[ count ] = new JButton( names[ count ] ); buttons[ count ].addActionListener( this ); // register listener add( buttons[ count ] ); // add button to JFrame } // end for } // end GridLayoutFrame constructor // How to handle the ActionEvent for each JButtons public void actionPerformed( ActionEvent event ) { if ( toggle ) container.setLayout( gridLayout2 ); // set layout to second else container.setLayout( gridLayout1 ); // set layout to first toggle = !toggle; © 2011 Gilbert Ndjatou // set toggle to opposite value Page 128 container.validate( ); } // end method actionPerformed } // end class GridLayoutFrame // re-lay out container // Testing GridLayoutFrame. public class GridLayoutDemo { public static void main( String[] args ) { GridLayoutFrame gridLayoutFrame = new GridLayoutFrame(); gridLayoutFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); gridLayoutFrame.pack( ); // set frame size gridLayoutFrame.setVisible( true ); // display frame } // end main } // end class GridLayoutDemo Using Panels to Organize Components Complex GUIs that require that each component be placed in an exact location often consists of multiple panels. Panels are implemented by the class JPanel (package: javax.swing) which extends the JComponent class. Every JPanel can therefore have components (including other panels) attached to it with the instance methods add of the class Container. Layout managers are also used to specify how components are organized in a JPanel. Example P1 The following application creates a JPanel that contains 5 JButtons organized using the GridLayout manager (with one row and five columns). This JPanel is added at the bottom of a frame organized using the BorderLayout manager. © 2011 Gilbert Ndjatou Page 129 // Using a JPanel to help lay out components. import java.awt.GridLayout; import java.awt.BorderLayout; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JButton; class PanelFrame extends JFrame { private JPanel buttonJPanel; // panel to hold buttons private JButton[] buttons; // array of buttons // no-argument constructor public PanelFrame( ) { super( "Panel Demo" ); buttons = new JButton[ 5 ]; // create buttons array buttonJPanel = new JPanel( ); // set up panel buttonJPanel.setLayout( new GridLayout( 1, buttons.length ) ); // create and add buttons for ( int count = 0; count < buttons.length; count++ ) { buttons[ count ] = new JButton( "Button " + ( count + 1 ) ); buttonJPanel.add( buttons[ count ] ); // add button to panel } // end for add( buttonJPanel, BorderLayout.SOUTH ); } // end PanelFrame constructor } // end class PanelFrame // add panel to JFrame // Testing PanelFrame. public class PanelDemo extends JFrame { public static void main( String[] args ) { PanelFrame panelFrame = new PanelFrame(); panelFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); panelFrame.pack( ); // set frame size panelFrame.setVisible( true ); // display frame } // end main } // end class PanelDemo © 2011 Gilbert Ndjatou Page 130 Hands-On Exercise GUI8 Type and execute the programs in examples BL1, GL1, and P1. Exercise GUI12 Exercises 14.8, 14.9, and 14.10. Extra credits: Exercises 14.11 to 14.14. © 2011 Gilbert Ndjatou Page 131 © 2011 Gilbert Ndjatou Page 132