// Object Oriented Programming with Java - CD library Part 2 - GUI Client/Server. // John Wilkinson (MS50). //------------------------------------------------------------------------------------------- import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; import java.lang.*; import java.util.*; import java.awt.image.*; public class gui extends Frame implements ActionListener { // AWT COMPONENTS private MenuBar mb; private TextField t, a, c; private List tr; private List cd_choice; private Button display; private Button remove; private cdCover cd_cover; private Label tle, art, com, tra, arrow, choice; // I/O VARIABLES private ObjectOutputStream out = null; // Output Stream variable private ObjectInputStream in = null; // Input Stream variable // USEFULL CLASS VARIABLES private SearchAddDialog s_dialog; // dialog variable private InputDialog i_dialog; // dialog variable private boolean no_dialogs; // boolean so only one dialog can be opened at once private Object fromServer; private Vector tempVector; private String command; private cd CD; // * CONSTRUCTOR * public gui(String title, ObjectInputStream i, ObjectOutputStream o) throws IOException { super(title); setSize(460, 400); addWindowListener(new WindowAdapter () { public void windowClosing(WindowEvent e) { System.exit(0); } }); in = i; // assignes input stream out = o; // assignes output stream no_dialogs = true; // sets check that no dialog exist to true // MENU SETUP Menu m1, m2, m3; MenuItem mi1_1, mi1_2, mi1_3, mi2_1, mi3_1, mi3_2, mi3_3; // Build the menu bar. mb = new MenuBar(); setMenuBar(mb); // Build 'File' menu in the menu bar. m1 = new Menu("File"); mi1_1 = new MenuItem("Load"); mi1_1.addActionListener(this); m1.add(mi1_1); mi1_2 = new MenuItem("Save"); mi1_2.addActionListener(this); m1.add(mi1_2); mi1_3 = new MenuItem("Close"); mi1_3.addActionListener(this); m1.add(mi1_3); mb.add(m1); // Build 'Edit' menu in the menu bar. m2 = new Menu("Edit"); mi2_1 = new MenuItem("add CD"); mi2_1.addActionListener(this); m2.add(mi2_1); mb.add(m2); //Build 'Tools' menu in the menu bar. m3 = new Menu("Tools"); mi3_1 = new MenuItem("Search"); mi3_1.addActionListener(this); m3.add(mi3_1); mi3_2 = new MenuItem("List"); mi3_2.addActionListener(this); m3.add(mi3_2); mi3_3 = new MenuItem("Dump"); mi3_3.addActionListener(this); m3.add(mi3_3); mb.add(m3); // SETUP WINDOW COMPONENTS t = new TextField("", 20); t.setEditable(false); a = new TextField("", 20); a.setEditable(false); c = new TextField("", 20); c.setEditable(false); tr = new List(3, false); cd_choice = new List(5, false); cd_cover = new cdCover(); display = new Button("Display"); remove = new Button("Remove"); tle = new Label("Title:"); art = new Label("Artist:"); com = new Label("Composer:"); tra = new Label("Tracks:"); arrow = new Label(">"); // ADD ACTION LISTENERS TO BUTTONS display.addActionListener(this); remove.addActionListener(this); // POSITION WINDOW COMPONENTS USING GRID BAG LAYOUT MANAGER GridBagLayout gbl = new GridBagLayout(); setLayout(gbl); // set layout in 'panel' of the window GridBagConstraints gbc = new GridBagConstraints(); position(cd_cover, gbc, 0, 2, 2, 5); // direct to 'panel' window position(tle, gbc, 2, 0, 1, 1); position(art, gbc, 2, 1, 1, 1); position(com, gbc, 2, 2, 1, 1); position(tra, gbc, 2, 3, 1, 1); position(t, gbc, 3, 0, 2, 1); position(a, gbc, 3, 1, 2, 1); position(c, gbc, 3, 2, 2, 1); position(tr, gbc, 3, 3, 2, 2); position(cd_choice, gbc, 0, 7, 2, 5); position(arrow, gbc, 2, 11, 1, 1); position(display, gbc, 3, 11, 1, 1); position(remove, gbc, 4, 11, 1, 1); // LOAD/DISPLAY DEFAULT COLLECTION ON START-UP try { processObjects(1); } catch (OptionalDataException e) { System.out.println("Optional Data Exception in constructor!"); } catch (IOException e) { System.err.println("I/O Exception attempting to start program."); System.exit(1); } } // *** EVENTS *** public void actionPerformed(ActionEvent e) { try { // selecting the display button if (e.getSource() == display) { String t = cd_choice.getSelectedItem(); // action on pushing display. out.writeObject("title " + t); // request server to search for cd with selected title processObjects(2); } // selecting the remove button else if (e.getSource() == remove) { String t = cd_choice.getSelectedItem(); // action on pushing display. int i = cd_choice.getSelectedIndex(); out.writeObject("remove " + t); // request server to remove selected title cd_choice.remove(i); processObjects(0); // not processed } // selecting the menu components else if (e.getSource() instanceof MenuItem) { MenuItem mi = (MenuItem)e.getSource(); String arg = mi.getLabel(); if (arg.equals("Save")) { if (no_dialogs) { no_dialogs = false; i_dialog = new InputDialog(this, "Save"); } i_dialog.setVisible(true); } else if (arg.equals("Load")) { if (no_dialogs) { no_dialogs = false; i_dialog = new InputDialog(this, "Load"); } i_dialog.setVisible(true); } else if (arg.equals("add CD")) { if (no_dialogs) { no_dialogs = false; s_dialog = new SearchAddDialog(this, "Add"); } s_dialog.setVisible(true); } else if (arg.equals("Search")) { if (no_dialogs) { no_dialogs = false; s_dialog = new SearchAddDialog(this, "Search"); } s_dialog.setVisible(true); } else if (arg.equals("List")) { out.writeObject("list"); processObjects(3); } else if (arg.equals("Dump")) { out.writeObject("List"); processObjects(4); } else if (arg.equals("Close")) System.exit(0); } else System.exit(0); } catch (IOException exc) { System.err.println("IO Exception in main window events."); } } // ******************************************* METHODS ************************************************** // method for positioning AWT components in Window public void position(Component c, GridBagConstraints gbc, int x, int y, int w, int h) { gbc.gridx = x; gbc.gridy = y; gbc.gridwidth = w; gbc.gridheight = h; add(c, gbc); } // method for displaying CD titles in collection list 'cd_choice' public void displayTitles(cd item) { String s = item.getTitle(); cd_choice.add(s); cd_choice.makeVisible(cd_choice.getItemCount() -1); } // method for displaying contents of a CD in window components public void displayContents(cd item) throws IOException { t.setText(item.getTitle()); a.setText(item.getArtist()); c.setText(item.getComposer()); Vector trks = item.getTracks(); tr.removeAll(); cd_cover.setVisible(false); for (int i = 0; i < trks.size(); ++i) { String string = (String)trks.elementAt(i); tr.add(string); } tr.makeVisible(tr.getItemCount() -1); try { URL image_name = new URL(item.getcover_URL()); cd_cover.i = createImage((ImageProducer)image_name.getContent()); cd_cover.setSize(180,180); cd_cover.setVisible(true); } catch (MalformedURLException exc) { System.out.println("Image Error."); } } // method used to handle ALL server input for entire class public void processObjects(int type) throws IOException { // processes all objects sent by the server try { while (true) { fromServer = in.readObject(); String temp = (String)fromServer; if (temp.equals("SENDING")) { if (type == 3) cd_choice.removeAll(); // type 3 requires collection list to be refreshed while (true) { fromServer = in.readObject(); CD = (cd)fromServer; if (CD == null) break; else { switch (type) { case 1: displayTitles(CD); break; case 2: displayContents(CD); break; case 3: displayTitles(CD); break; case 4: CD.printAll(); break; case 5: tempVector.addElement(CD.getTitle()); break; // puts cd title into vector } } } break; } else break; // "NOT SENDING" } } catch (ClassNotFoundException e) { System.out.println("Class Exception in constructor!"); } } // **************************************** INNER CLASSES *********************************************** // * CLASS FOR SEARCH & ADD DIALOG * class SearchAddDialog extends Dialog implements ActionListener { private TextField t; private TextField a; private TextField c; private TextField url; private TextField track; private List tracks; private gui parent; SearchAddDialog(Frame dw, String title) { // constructor super(dw, title, false); parent = (gui)dw; command = title; // String initialised to type of dialog needed //Create middle section. Panel p1 = new Panel(); p1.setLayout(new FlowLayout(FlowLayout.LEFT)); Label l_t = new Label("Enter Title: "); p1.add(l_t); t = new TextField(40); p1.add("North", t); Label l_a = new Label("Enter Artist: "); p1.add(l_a); a = new TextField(40); p1.add("North", a); Label l_c = new Label("Enter Composer:"); p1.add(l_c); c = new TextField(40); p1.add("North", c); // if ADD dialog is needed offer extra TextField for URL if (command.equals("Add")) { Label l_url = new Label("Enter URL of Image:"); p1.add(l_url); url = new TextField(40); p1.add("North", url); } Label l_track = new Label("Enter track and press 'Enter' to put into 'Track List':"); p1.add(l_track); track = new TextField(40 ); p1.add("North", track); Button a = new Button("Enter"); a.addActionListener(this); p1.add(a); Label l_tracks = new Label("Track list:"); p1.add(l_tracks); tracks = new List(3, false); p1.add("North", tracks); add(p1); //Create bottom row. Panel p2 = new Panel(); p2.setLayout(new FlowLayout(FlowLayout.RIGHT)); Button c = new Button("Cancel"); c.addActionListener(this); Button com = new Button(command); com.addActionListener(this); p2.add(c); p2.add(com); add("South", p2); //Initialize this dialog to preferred size. if (command.equals("Add")) setSize(330, 450); else setSize(350, 400); } // *** EVENTS *** public void actionPerformed(ActionEvent event) { Object source = event.getSource(); Button b = (Button)event.getSource(); String arg = b.getLabel(); try { if (arg.equals("Enter")) { String t = track.getText(); t = t.trim(); // removes all white space to filter empty strings out if (t.length() > 0) { tracks.add(t); tracks.makeVisible(tracks.getItemCount() -1); track.setText(""); } else track.setText(""); // resets TextField } else if (arg.equals("Add")) { if (((t.getText().trim()).length()) > 0) { // only allows cd add if title has been entered int cnt = tracks.getItemCount(); // goes through all tracks in the list Vector temp_vec = new Vector(); for (int i = 0; i < cnt; i++) { String temp = tracks.getItem(i); temp_vec.addElement(temp); } cd element = new cd(a.getText(), c.getText(), t.getText(), temp_vec, url.getText()); out.writeObject("sending_cd"); out.writeObject(element); cd_choice.add(t.getText()); } setVisible(false); // closes dialog no_dialogs = true; } else if (arg.equals("Search")) { Vector temp = new Vector(); // to build a vector of search items int cnt = ((t.getText()).trim()).length(); if (cnt > 0) temp.addElement("title " + t.getText()); cnt = ((a.getText()).trim()).length(); if (cnt > 0) temp.addElement("artist " + a.getText()); cnt = ((c.getText()).trim()).length(); if (cnt > 0) temp.addElement("composer " + c.getText()); int list_cnt = tracks.getItemCount(); for (int i = 0; i < list_cnt; i++) { // goes through all tracks in the list cnt = ((tracks.getItem(i)).trim()).length(); if (cnt > 0) temp.addElement("track " + tracks.getItem(i)); else break; } tempVector = new Vector(); // clears Vector ready to fill for (int i = 0; i < temp.size(); ++i) { // client/server search loop out.writeObject(temp.elementAt(i)); // writes all the search request lines to the server processObjects(5); } if ((tempVector.size()) > 0) { // checks that results vector contains items for displaying cd_choice.removeAll(); // clear collection listing ready to display results of search for (int i = 0; i < tempVector.size(); i++) {// puts titles into list cd_choice.add((String)tempVector.elementAt(i)); cd_choice.makeVisible(cd_choice.getItemCount() -1); } } setVisible(false); // closes dialog no_dialogs = true; } else if (arg.equals("Cancel")) { setVisible(false); // closes dialog no_dialogs = true; } } catch (OptionalDataException e) { System.out.println("Optional Data Exception in constructor!"); } catch (IOException e) { System.err.println("I/O Exception in constructor."); System.exit(1); } /*catch (ClassNotFoundException e) { System.out.println("Class Exception in constructor!"); } */ } } // * CLASS FOR SAVE & LOAD DIALOG * class InputDialog extends Dialog implements ActionListener { private TextField filename; private gui parent; InputDialog(Frame dw, String title) { // constructor super(dw, title, false); parent = (gui)dw; command = title; // String initialised to type of dialog needed //Create middle section. Panel p1 = new Panel(); Label file = new Label("Enter file name:"); p1.add(file); filename = new TextField(40); p1.add("Center", filename); add(p1); //Create bottom row. Panel p2 = new Panel(); p2.setLayout(new FlowLayout(FlowLayout.RIGHT)); Button c = new Button("Cancel"); c.addActionListener(this); Button b = new Button("OK"); b.addActionListener(this); p2.add(c); p2.add(b); add("South", p2); //Initialize this dialog to preferred size. pack(); } // *** EVENTS *** public void actionPerformed(ActionEvent event) { Object source = event.getSource(); Button b = (Button)event.getSource(); String arg = b.getLabel(); if (arg.equals("OK")) { String f = filename.getText(); String f_trim = f.trim(); // removes all white space to filter empty strings out if (f_trim.length() > 0) { try { out.writeObject(command + " " + f); processObjects(3); } catch (OptionalDataException e) { System.out.println("Optional Data Exception in constructor!"); } catch (IOException e) { System.err.println("I/O Exception in constructor."); System.exit(1); } /*catch (ClassNotFoundException e) { System.out.println("Class Exception in constructor!"); }*/ } } filename.setText(""); // resets TextField setVisible(false); no_dialogs = true; } } // * CLASS FOR COVER IMAGE * class cdCover extends Canvas { // puts image inside canvas public Image i; public void paint(Graphics g) { g.drawImage(i, 45, 45, this); } } // ******************************************* MAIN ************************************************** public static void main(String args[]) { Socket socket = null; ObjectOutputStream out = null; ObjectInputStream in = null; try { // could put into constructor socket = new Socket("harrier", 5421); out = new ObjectOutputStream(socket.getOutputStream()); in = new ObjectInputStream(socket.getInputStream()); gui g = new gui("WILKINSON'S GUI CLIENT", in, out); g.show(); } catch (UnknownHostException e) { System.err.println("Don't know about host: harrier."); System.exit(1); } catch (IOException e) { System.err.println("Couldn't get I/O for the connection to: harrier."); System.exit(1); } } }