import java.awt.*; import java.util.*; import java.net.*; import java.io.*; import java.applet.Applet; public class Users_6 extends Applet { userClient c; public void init() { c = new userClient(); c.show(); } } class userClient extends Frame { final int SERVICE = 9001; Panel main_panel, status_panel, summ_panel; GridBagPanel full_panel; CardLayout cardMgr; Label stat_label; List summ_list; Clock clk_ticker; Socket server; eventTracker et; DataInputStream sock_in; DataOutputStream sock_out; Hashtable db; int currentItem; userClient() { int REMN = GridBagConstraints.REMAINDER; db = new Hashtable(20); et = new eventTracker(); resize(500, 300); setLayout(new BorderLayout()); add("North", main_panel = new Panel()); add("South", status_panel = new Panel()); main_panel.setLayout(cardMgr = new CardLayout()); status_panel.setLayout(new BorderLayout()); main_panel.add("Full", full_panel = new GridBagPanel()); main_panel.add("Summary",summ_panel = new Panel()); status_panel.add("West", stat_label = new Label("Application Started")); status_panel.add("East", clk_ticker = new Clock()); // WGT WIDTH full_panel.add_textfield("Name", 1, REMN); full_panel.add_textfield("Title", 1, REMN); full_panel.add_textfield("Email", 1, REMN); full_panel.add_textfield("Company", 1, REMN); full_panel.add_textfield("Dept", 1, 2); full_panel.add_textfield("MailStop",1, REMN); full_panel.add_textfield("City", 1, 4); full_panel.add_textfield("State", 1, 1); full_panel.add_textfield("Zip", 1, REMN); summ_panel.setLayout(new BorderLayout()); summ_list = new List(10, false); summ_panel.add("Center", summ_list); userMenu menu = new userMenu(this); setMenuBar(menu); setTitle("My first client"); } /**/ void Connect() { new ConnectDialog(this, "Connect to Server", true); } /**/ void Exit() { Runtime.getRuntime().exit(0); } void Edit() { TextField text; printStatus("Editing record"); Enumeration elems = full_panel.fieldlist.elements(); while (elems.hasMoreElements()) { text = (TextField) elems.nextElement(); text.setEditable(true); } } void Add() { TextField text; String name; int a; boolean found_match; printStatus("Saving changes"); UserRecord rec = new UserRecord(full_panel.fieldlist); try { rec.send(sock_out); } catch (IOException e) { printStatus("Add failed: " + e.getMessage()); } text = (TextField) full_panel.fieldlist.get("Name"); name = (String) text.getText(); db.put(name, rec); Enumeration elems = full_panel.fieldlist.elements(); while (elems.hasMoreElements()) { text = (TextField) elems.nextElement(); text.setEditable(false); } for (a = 0, found_match = false; a < summ_list.countItems(); a++) { String item = summ_list.getItem(a); if (item.equals(name)) { found_match = true; break; } } if (found_match == false) summ_list.addItem(name); currentItem = a; summ_list.select(currentItem); } void Delete() { String name = summ_list.getSelectedItem(); if (name == null) return; UserRecord rec = (UserRecord) db.get(name); try { rec.delete(sock_out); } catch (IOException e) { printStatus("Delete failed: " + e.getMessage()); } summ_list.delItem(currentItem); db.remove(name); if (currentItem > summ_list.countItems()) { currentItem--; summ_list.select(currentItem); } name = summ_list.getItem(currentItem); UserRecord newrec = (UserRecord) db.get(name); full_panel.display_data(newrec); printStatus("Deleted"); } void Full() { String name = (String) summ_list.getItem(currentItem); UserRecord rec = (UserRecord) db.get(name); full_panel.display_data(rec); cardMgr.show(main_panel, "Full"); } void Summary() { cardMgr.show(main_panel, "Summary"); } void printStatus(String str) { stat_label.setText(str); } public boolean handleEvent(Event evt) { if (et != null) et.log(evt); if (evt.id == Event.ACTION_EVENT) action(evt, evt.target); else if (evt.id == Event.LIST_SELECT) { Integer Int = (Integer) evt.arg; currentItem = Int.intValue(); } return false; } public boolean action(Event evt, Object target) { String item = evt.arg.toString(); if (item.equals("Connect")) Connect(); else if (item.equals("Exit")) Exit(); else if (item.equals("Edit")) Edit(); else if (item.equals("Add")) Add(); else if (item.equals("Delete")) Delete(); else if (item.equals("Full")) Full(); else if (item.equals("Summary")) Summary(); else return false; return true; } } class GridBagPanel extends Panel { GridBagLayout gridbag; GridBagConstraints c; Hashtable fieldlist; GridBagPanel() { gridbag = new GridBagLayout(); c = new GridBagConstraints(); c.fill = GridBagConstraints.BOTH; fieldlist = new Hashtable(10); setLayout(gridbag); } void add_textfield(String text, int weight, int width) { c.weightx = 0; c.weighty = 0; c.gridwidth = 1; c.gridheight= 1; Label label = new Label(text); gridbag.setConstraints(label, c); add(label); c.weightx = weight; c.weighty = 0; c.gridwidth = width; c.gridheight= 1; TextField tfield = new TextField(); tfield.setEditable(false); gridbag.setConstraints(tfield, c); add(tfield); fieldlist.put(text, tfield); } void display_data(UserRecord rec) { String rec_key, rec_elem; TextField disp_elem; Enumeration rec_step; rec_step = rec.hash.keys(); while (rec_step.hasMoreElements()) { rec_key = (String) rec_step.nextElement(); rec_elem = (String) rec.hash.get(rec_key); disp_elem = (TextField) fieldlist.get(rec_key); if (disp_elem != null) disp_elem.setText(rec_elem); } } } class userMenu extends MenuBar { userClient u; userMenu(userClient u) { this.u = u; Menu file = new Menu("File"); Menu edit = new Menu("Edit"); Menu view = new Menu("View", true); Menu casc = new Menu("Cascade"); file.add(new MenuItem("Connect")); file.add(new MenuItem("Exit")); edit.add(new MenuItem("Edit")); edit.add(new MenuItem("Add")); edit.add(new MenuItem("Delete")); view.add(new MenuItem("Full")); view.add(new MenuItem("Summary")); view.add(casc); casc.add(new MenuItem("Cascade-1")); casc.add(new MenuItem("Cascade-2")); casc.add(new MenuItem("Cascade-3")); add(file); add(edit); add(view); } } class Clock extends Label implements Runnable { Thread tick; Clock() { super(new Date().toString(), Label.RIGHT); tick = new Thread(this); tick.start(); } public void run() { while (true) { try { Thread.sleep(1000); setText(new Date().toString()); } catch (InterruptedException e) { tick.destroy(); return; } } } } /**/ class ConnectDialog extends Dialog { TextField textfield; userClient parent; public ConnectDialog(Frame f, String title, boolean modal) { super(f, title, modal); parent = (userClient) f; Panel p1 = new Panel(); Panel p2 = new Panel(); p1.add(new Label("Server:")); p1.add(textfield = new TextField(20)); add("Center", p1); p2.add(new Button("Connect")); p2.add(new Button("Cancel")); add("South", p2); pack(); show(); } /**/ public boolean action(Event evt, Object target) { String cmd = evt.arg.toString(); if (cmd.equals("Connect")) { parent.printStatus("Connecting to " + textfield.getText()); Timeout timeout = new Timeout(1000, Thread.currentThread()); try { timeout.start(); parent.server = new Socket(textfield.getText(), parent.SERVICE); timeout.cancel(); } catch (UnknownHostException e) { parent.printStatus("Connect failed: " + e.getMessage()); return true; } catch (IOException e) { parent.printStatus("Connect failed: " + e.getMessage()); return true; } catch (ThreadDeath e) { dispose(); parent.printStatus(e.getMessage()); return true; } try { InputStream in = parent.server.getInputStream(); OutputStream out = parent.server.getOutputStream(); parent.sock_in = new DataInputStream(in); parent.sock_out = new DataOutputStream(out); } catch (IOException e) { parent.printStatus(e.getMessage()); } } else if (cmd.equals("Cancel")) { dispose(); parent.printStatus("Cancelled connection attempt"); return true; } else return true; return true; } } class Timeout extends Thread { Thread target; long timeout; public Timeout(long timeout, Thread target) { this.timeout = timeout; this.target = target; } public void run() { try { Thread.sleep(timeout); } catch (InterruptedException e) { System.err.println("Timer failed " + e.getMessage()); } target.stop(); } public void cancel() { stop(); } } class UserRecord { Hashtable hash = new Hashtable(10); UserRecord() { } UserRecord(Hashtable src) { Enumeration elem, key; String fieldLabel, fieldValue; TextField fieldTextF; elem = src.elements(); key = src.keys(); while (key.hasMoreElements()) { fieldLabel = (String) key.nextElement(); fieldTextF = (TextField) elem.nextElement(); fieldValue = fieldTextF.getText(); hash.put(fieldLabel, fieldValue); } } public void send(DataOutputStream out) throws IOException { Enumeration key; String fieldName, fieldValue; key = hash.keys(); out.writeChars((String)(hash.size() + "\n")); while (key.hasMoreElements()) { fieldName = (String) key.nextElement(); fieldValue = (String) hash.get(fieldName); out.writeChars(fieldName + ":" + fieldValue + "\n"); } } public void delete(DataOutputStream out) throws IOException { Enumeration key; String fieldName, fieldValue; key = hash.keys(); fieldName = (String) key.nextElement(); fieldValue = (String) hash.get(fieldName); out.writeChars("~" + "\n"); out.writeChars(fieldValue); } public String receive(DataInputStream in) throws IOException { int fieldcount; Integer int_obj; StringTokenizer parse; String field, label, data; if (hash.size() > 0) throw new IOException("Already contains data"); int_obj = new Integer(in.readLine()); fieldcount = int_obj.intValue(); while (fieldcount > 0) { field = in.readLine(); parse = new StringTokenizer(field, ":"); label = parse.nextToken(); data = parse.nextToken(); hash.put(label, data); fieldcount--; } String name = (String) hash.get("Name"); return name; } }