Table of Contents
Here is the solution for Chapter 7, Java™ Applets - An Introduction in the section called “An Exercise For You! Passing parameters to an Applet.” The Exercise was to modify the Chess Applet, written earlier in the section called “ChessApplet - An Applet for you to try!” to:
Draw a rectangle around the outside of the board.
Accept a chess board single square size (in pixels) as a parameter called squareSize to the applet.
Accept a parameter firstSquare that sets either a black or white square first.
It should look like Figure 15.1, “The ChessSolution
applet with a square Size of 2, 10, 20 with a reversal in starting colour”.
Figure 15.1. The ChessSolution
applet with a square Size of 2, 10, 20 with a reversal in starting colour
The Solution is at: ChessSolution.html and
the source code is at:
ChessSolution.java
// Chess board Exercise - source code // by Derek Molloy 2000 import java.awt.Graphics; import java.applet.Applet; import java.awt.Color; //must import the color class to use it! public class ChessSolution extends Applet { private boolean whiteFirst = true; private int squareSize = 20; public void init() { // try to read in the parameters from the HTML file String tempFirstSquare = this.getParameter("firstSquare"); if (tempFirstSquare!=null) { if (tempFirstSquare.toLowerCase().equals("black")) this.whiteFirst = false; else this.whiteFirst = true; } String tempSquareSize = this.getParameter("squareSize"); if (tempSquareSize!=null) { this.squareSize = (new Integer(tempSquareSize)).intValue(); } } public void paint(Graphics g) { // this boolean is key to the solution, it must remember if the square is a black // or white square. The first square is black so it is set to true. boolean blackSquare = !this.whiteFirst; for (int y=0; y<8; y++) // for each row { for (int x=0; x<8; x++) // for each column { if (blackSquare) g.setColor(Color.black); //if a blacksquare set the color black else g.setColor(Color.white); // otherwise set the colour white blackSquare = !blackSquare; // invert for the next square g.fillRect((x*squareSize ),(y*squareSize ),squareSize,squareSize); // fill the box with color } blackSquare = !blackSquare; // each row starts with a different colour! } } }
Here is the solution for the section called “An Exercise for You. Images, Sound and Mouse!” in Chapter 8, Java™ Applets - Images and Audio The Exercise was to Write an applet that plays a sound and displays an image wherever you press the mouse on the applet. When the applet first starts it should display the image at (x,y) = (20,20). See Figure 15.2, “Mouse Exercise Applet” for an example of how the applet works.
You can see my solution working here -
MouseSolution.html
and the source code is at:
MouseSolution.java
// An Outline Application for Handling Mouse Events import java.applet.*; import java.awt.*; import java.awt.event.*; public class MouseSolution extends Applet implements MouseListener { private AudioClip theSound; private Image theImage; private int x,y; public void init() { this.theSound = this.getAudioClip( this.getDocumentBase(), "start.wav" ); this.theImage = this.getImage( this.getDocumentBase(), "test.gif" ); this.addMouseListener(this); } public void mousePressed(MouseEvent e) {} public void mouseReleased(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} public void mouseClicked(MouseEvent e) { this.theSound.play(); this.x = e.getX(); this.y = e.getY(); this.repaint(); } public void paint(Graphics g) { g.drawImage(theImage, this.x, this.y, this); } }
Here is the solution for the exercise give in the section called “An Exercise For You. The Colour Chooser Applet” in Chapter 9, Java™ Graphical User Interface(GUI) Components.
The Task Was: Write a Colour Chooser Applet that allows the user to choose a colour to be displayed,
using the scrollbars or by entering the values directly. The applet should check that the user has not inputted invalid
values. Figure 15.3, “The Colour Chooser Applet Exercise Solution” shows my user-interface and you can see it working here -
ColorChooserApplet.html
.
The source code is at:
ColorChooserApplet.java
and as below.
// The Colour Chooser Applet Exercise import java.applet.*; import java.awt.*; import java.awt.event.*; public class ColorChooserApplet extends Applet implements ActionListener, AdjustmentListener { private Scrollbar rBar, gBar, bBar; private TextField rField, gField, bField; private ColorCanvas cs; public void init() { //For the layout I used a 3x3 grid with the canvas and grid added to FlowLayout Panel rightPanel = new Panel(new GridLayout(3,3)); rightPanel.add(new Label("Red:")); rBar = new Scrollbar(Scrollbar.HORIZONTAL, 128, 10, 0, 265); rBar.addAdjustmentListener(this); rightPanel.add(rBar); rField = new TextField("128",10); rField.addActionListener(this); rightPanel.add(rField); rightPanel.add(new Label("Green:")); gBar = new Scrollbar(Scrollbar.HORIZONTAL, 128, 10, 0, 265); gBar.addAdjustmentListener(this); rightPanel.add(gBar); gField = new TextField("128"); gField.addActionListener(this); rightPanel.add(gField); rightPanel.add(new Label("Blue:")); bBar = new Scrollbar(Scrollbar.HORIZONTAL, 128, 10, 0, 265); bBar.addAdjustmentListener(this); rightPanel.add(bBar); bField = new TextField("128"); bField.addActionListener(this); rightPanel.add(bField); cs = new ColorCanvas(); cs.setSize(100,100); this.add(cs); this.add(rightPanel); this.updateColor(); } // Since no invalid value is possible with the scrollbar error checking is not required. public void adjustmentValueChanged(AdjustmentEvent e) { rField.setText(new Integer(rBar.getValue()).toString()); gField.setText(new Integer(gBar.getValue()).toString()); bField.setText(new Integer(bBar.getValue()).toString()); this.updateColor(); } //actionPerformed is a little complex as the user could type in values //>255 <0 or even enter an invalid string public void actionPerformed(ActionEvent e) { try { Integer rVal = new Integer(rField.getText()); Integer gVal = new Integer(gField.getText()); Integer bVal = new Integer(bField.getText()); int rValInt = rVal.intValue(); int gValInt = gVal.intValue(); int bValInt = bVal.intValue(); if(rValInt>=0 && rValInt<=255) rBar.setValue(rValInt); else throw(new NumberFormatException()); if(gValInt>=0 && gValInt<=255) gBar.setValue(gValInt); else throw(new NumberFormatException()); if(bValInt>=0 && bValInt<=255) bBar.setValue(bValInt); else throw(new NumberFormatException()); } catch (NumberFormatException nfe) { rField.setText(new Integer(rBar.getValue()).toString()); gField.setText(new Integer(gBar.getValue()).toString()); bField.setText(new Integer(bBar.getValue()).toString()); } updateColor(); } // I use the scrollbars as storage rather than states private void updateColor() { Color c = new Color(rBar.getValue(), gBar.getValue(), bBar.getValue()); cs.updateColor(c); } } class ColorCanvas extends Canvas { private Color col; public void updateColor(Color c) { this.col = c; repaint(); } public void paint(Graphics g) { g.setColor(col); g.fillRect(0,0,100,100); } }
Task: This exercise in the section called “An Exercise For You. The Updated Client/Server Application” was to update the code for the client/server example in the section called “The TCP Client/Server” to do the following:
Hint: No hints, just get rid of that infinite loop!
See my application working below with the client in Figure 15.4, “My Date Client Exercise Solution” and the server in Figure 15.5, “My Date Server Exercise Solution”. I have run it twice in this case to show you that the client port is different every time that it connects.
The Source files are below and as in
DateClient.java
, DateServer.java
, HandleConnection.java
and DateTimeService.java
.
// The Date Client - The date client connects to the server, sends the "GetDate" command and // waits for a response. // by Derek Molloy import java.net.*; import java.io.*; import java.util.*; public class DateClient { private Socket socket = null; private ObjectOutputStream os = null; private ObjectInputStream is = null; // the constructor expects the IP address of the server - the port is fixed at 6060 public DateClient(String serverIP) { if (!connectToServer(serverIP)) { System.out.println("Cannot open socket connection..."); } } private boolean connectToServer(String serverIP) { try // open a new socket to port 6060 and create streams { this.socket = new Socket(serverIP,6060); this.os = new ObjectOutputStream(this.socket.getOutputStream()); this.is = new ObjectInputStream(this.socket.getInputStream()); System.out.print("Connected to Server\n"); } catch (Exception ex) { System.out.print("Failed to Connect to Server\n" + ex.toString()); System.out.println(ex.toString()); return false; } return true; } private void getDate() { String theDate; System.out.println("Sending GetDate Command:"); this.send("GetDate"); theDate = (String)receive(); if (theDate != null) { System.out.println("The Server's date is " + theDate); } } private void shutdown() { String response = new String(); System.out.println("Sending Shutdown Command:"); this.send("ShutDown"); response = (String)receive(); if (response != null) { System.out.println("The Server said: " + response); } } // method to send a generic object. private void send(Object o) { try { System.out.println("Sending " + o); os.writeObject(o); os.flush(); } catch (Exception ex) { System.out.println(ex.toString()); } } // method to receive a generic object. private Object receive() { Object o = null; try { o = is.readObject(); } catch (Exception ex) { System.out.println(ex.toString()); } return o; } public static void main(String args[]) { if(args.length>0) { DateClient theApp = new DateClient(args[0]); try { theApp.getDate(); theApp.shutdown(); } catch (Exception ex) { System.out.println(ex.toString()); } } else { System.out.println("Error: you must provide the IP of the server"); System.exit(1); } System.exit(0); } }
// The DateServer - The server application that passes control to the Handle Connection // by Derek Molloy import java.net.*; import java.io.*; public class DateServer { public static void main(String args[]) { boolean stillAlive = true; ServerSocket serverSocket = null; try { serverSocket = new ServerSocket(6060); System.out.println("Server has started listening on port 6060"); } catch (IOException e) { System.out.println("Error: Cannot listen on port 6060: " + e); System.exit(1); } while (stillAlive) // infinite loop - loops once for each client { Socket clientSocket = null; try { clientSocket = serverSocket.accept(); //waits here (forever) until a client connects System.out.println("Server has just accepted socket connection from a client"); } catch (IOException e) { System.out.println("Accept failed: 6060 " + e); break; } // Create the Handle Connection object - only create it HandleConnection con = new HandleConnection(clientSocket); if (con == null) //If it failed send and error message { try { ObjectOutputStream os = new ObjectOutputStream(clientSocket.getOutputStream()); os.writeObject("error: Cannot open socket thread"); os.flush(); os.close(); } catch (Exception ex) //failed to even send an error message { System.out.println("Cannot send error back to client: 6060 " + ex); } } else { stillAlive = con.init(); } // change to shutdown if con.init() returns false } try // do not get here at the moment { System.out.println("Closing server socket."); serverSocket.close(); } catch (IOException e) { System.err.println("Could not close server socket. " + e.getMessage()); } } }
// The Handle connection class - that deals will all client requests directly // by Derek Molloy import java.net.*; import java.io.*; import java.util.*; public class HandleConnection { private Socket clientSocket; // Client socket object private ObjectInputStream is; // Input stream private ObjectOutputStream os; // Output stream private DateTimeService theDateService; private boolean shutDownSet = false; private String hostname = ""; private String portnumber = ""; // The constructor for the connecton handler public HandleConnection(Socket clientSocket) { this.clientSocket = clientSocket; //Get the client details InetAddress a = clientSocket.getInetAddress(); this.hostname = a.getHostName(); this.portnumber = "" + clientSocket.getPort(); //Set up a service object to get the current date and time theDateService = new DateTimeService(); } // The main execution method public boolean init() { String inputLine; try { this.is = new ObjectInputStream(clientSocket.getInputStream()); this.os = new ObjectOutputStream(clientSocket.getOutputStream()); while (this.readCommand()) {} } catch (IOException e) { e.printStackTrace(); } if (shutDownSet == true) return false; else return true; } // Receive and process incoming command from client socket private boolean readCommand() { String s = null; System.out.println("Just Received a command from: "+this.hostname+" at port:"+portnumber); try { s = (String)is.readObject(); } catch (Exception e) { s = null; } if (s == null) { this.closeSocket(); return false; } // invoke the appropriate function based on the command if (s.equals("GetDate")) { this.getDate(); } else if(s.equals("ShutDown")) { System.out.println("Received a shutdown command - shutting down server"); this.send("Received a shutdown command - shutting down server"); this.shutDownSet = true; return false; } else { this.sendError("Invalid command: " + s); } return true; } private void getDate() // uses the date service to get the date { String currentDateTime = theDateService.getDateAndTime(); this.send(currentDateTime); } // Send a message back through to the client socket as an Object private void send(Object o) { try { System.out.println("Sending " + o); this.os.writeObject(o); this.os.flush(); } catch (Exception ex) { ex.printStackTrace(); } } // Send a pre-formatted error message to the client public void sendError(String msg) { this.send("error:" + msg); //remember a string IS-A object! } // Close the client socket public void closeSocket() //close the socket connection { try { this.os.close(); this.is.close(); this.clientSocket.close(); } catch (Exception ex) { System.err.println(ex.toString()); } } }
// The DateTimeService class that provides the current date // by Derek Molloy. import java.util.*; public class DateTimeService { private Date theDate; //constructor gets the current date/time public DateTimeService() { this.theDate = new Date(); } //method returns date/time as a formatted string public String getDateAndTime() { return "The date is:" + this.theDate.toString(); } }
Task: Write an applet that when you press the "start" button draws, and keeps drawing
random coloured and sized filled ovals, as can be seen in Figure 15.6, “A Random Draw Thread Exercise Screen Capture - Solution.” until the
"stop" button is pressed. The applet should only display one oval at a time at each loop of the thead. You can
see my version here - RandomDrawThread.html
Hint: You can use the code from the section called “A Functional Canvas
Example” to get
you started.
Solution: My Solution is as below and in
RandomDrawThread.java
import java.awt.*; import java.awt.event.*; import java.applet.*; public class RandomDrawThread extends Applet implements ActionListener { MyCanvas c; Thread thePainter; Button theStart, theStop; public void init() { theStart = new Button("Start"); theStart.addActionListener(this); theStop = new Button("Stop"); theStop.addActionListener(this); c = new MyCanvas(); thePainter = new Thread(c); this.setLayout(new BorderLayout()); Panel p = new Panel(new FlowLayout()); p.add(theStart); p.add(theStop); this.add("North", p); this.add("Center",this.c); } public void actionPerformed(ActionEvent e) { if (e.getSource().equals(theStart)) { thePainter.start(); } else if (e.getSource().equals(theStop)) { c.stopDrawing(); } } } class MyCanvas extends Canvas implements Runnable { private boolean running = true; public void paint(Graphics g) { g.setColor(new Color((float)Math.random(),(float)Math.random(),(float)Math.random())); g.fillOval((int)(Math.random()*400), (int)(Math.random()*400), (int)(Math.random()*200), (int)(Math.random()*200)); } public void run() { while (running) { this.repaint(); try { Thread.currentThread().sleep(100); } catch (InterruptedException e) { System.out.println("Interupted!"); } } } public void stopDrawing() { this.running = false; } }
This is the exercise from the section called “ An Exercise for You. The Image Loader Application”.
Task: Write an Image Loader Application as shown in Figure 12.31, “The Image Loader Application”. The Toolbar should have two functions, Load Image and Close all Images. The Load Image should call up a file chooser as shown in Figure 12.32, “The Image Loader Application (with File Chooser open)”. The internal windows should display the name of the file, the image size and the size of the file from which it was loaded. The internal windows should be minimizable, maximizable, closable and iconifable. The main window should have a status label that displays details of the application as it runs.
Solution: My Solution is as below and in
ImageLoaderApplication.java
// Swing Image Loader Application Loader Application // - Derek Molloy import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.io.*; import java.util.*; public class ImageLoaderApplication extends JFrame implements ActionListener { private JToolBar theToolBar; private JButton loadButton, closeButton; private JDesktopPane desktop; private JLabel status; private Vector theFrames; public ImageLoaderApplication() { super("Image Loader Application"); this.desktop = new JDesktopPane(); theToolBar = new JToolBar("Loader"); loadButton = new JButton("Load Image",new ImageIcon("load.gif")); loadButton.addActionListener(this); closeButton = new JButton("Close All"); closeButton.addActionListener(this); theToolBar.add(loadButton); theToolBar.add(closeButton); status = new JLabel(); theFrames = new Vector(); this.getContentPane().add("North", theToolBar); this.getContentPane().add("Center", desktop); this.getContentPane().add("South", status); this.setSize(400,400); // set the size to 400 x 400 this.show(); // display the frame this.setStatus("Application Started"); } public void actionPerformed(ActionEvent e) { if (e.getSource().equals(loadButton)) { JFileChooser chooser = new JFileChooser(); int returnVal = chooser.showOpenDialog(this); if(returnVal == JFileChooser.APPROVE_OPTION) { File f = chooser.getSelectedFile(); ImageLoader imgldr = new ImageLoader(f); this.desktop.add(imgldr); this.theFrames.add(imgldr); this.setStatus("Loading Image "+f.getName()); } } if (e.getSource().equals(closeButton)) { int selected = JOptionPane.showConfirmDialog(this, "This will close all Windows. Are you sure?", "Confirmation Required", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE); if (selected == JOptionPane.YES_OPTION) { for (int i=0; i<theFrames.size(); i++) { ImageLoader imgldr = (ImageLoader) theFrames.elementAt(i); imgldr.destroy(); theFrames.removeElementAt(i); } this.setStatus("Closed all images"); } else { this.setStatus("Close All not confirmed"); } } } private void setStatus(String s) { this.status.setText("Status: "+s); } public static void main(String[] args) { new ImageLoaderApplication(); } } class ImageLoader extends JInternalFrame { private String filename; private String directory; private Image theImage; private int width, height; private long fileLength; public ImageLoader(File f) { super(f.getName(), true, true, true, true); filename = f.getName(); directory = f.getPath(); fileLength = f.length(); this.theImage = this.getToolkit().getImage(directory); JScrollPane scroll = new JScrollPane(new JLabel(new ImageIcon(this.theImage))); this.getContentPane().setLayout(new BorderLayout()); this.getContentPane().add("North", new JLabel(filename)); this.getContentPane().add("Center",scroll); width = this.theImage.getWidth(null); height = this.theImage.getHeight(null); String details = new String(" Details: Image Size("+width+","+height+") File Size "+fileLength+" bytes"); this.getContentPane().add("South", new JLabel(details)); this.setSize(300,300); this.show(); } public void destroy() { this.dispose(); } }
© 2006
Dr. Derek Molloy
(DCU).