import java.awt.*; import java.applet.*; import java.io.*; import java.util.*; /** * This class creates a panel to display a table. It is only called from * the TablePanel class which adds a scrollbar to the east of the * table canvas. *

* This TableCanvas class should not have to be used manually. * All its methods are redirected from the TablePanel class. */ public class TableCanvas extends Panel { int start; Vector key; Font font; int panel_height, panel_width; FontMetrics fm; Dimension offscreensize = null; Image offscreen = null; Graphics offGraphics = null; TablePanel panel; final int vertSpace = 17; int highlight; /** * Constructor method of the TableCanvas class. * @param parent The panel with a scrollbar where this table canvas * is going to reside. */ public TableCanvas(TablePanel parent) { this.panel = parent; this.start = 0; this.key = new Vector(); this.font = new Font("Courier", Font.PLAIN, 12); this.fm = this.getFontMetrics(font); this.highlight = -1; } /** * Initialize the table and set all entries to null. */ public void init() { this.key = new Vector(); } /** * Set the starting row, which will be displayed by the table. * @param start The first row to be shown at any one time. */ public void setStart(int start) { if ((start + 6) < key.size()) this.start = start; else if (key.size() > 6) this.start = key.size() - 7; else this.start = 0; } /** * Highlight the table entry with the row specified by the parameter. * There can only be one row highlighted at any one time. If a row * has already been highlighted and this highlightRow * method is called on another different row, the previously highlighted * row will be restored and the new row will be highlighted. * @param i The row to be highlighted. */ public void highlightRow(int i) { this.highlight = i; } /** * This method is used to restore any highlighted row. */ public void restoreRow() { this.highlight = -1; } /** * This method is called to set the size of the table and hence * rescale the scrollbar on the panel it resides in. * @param size The new size of this table. */ public void setTableSize(int size) { key = new Vector(size); key.setSize(size); panel.vScrollbar.setValues(panel.vScrollbar.getValue(), 1, 0, size-1); } /** * Set the object specified by the first parameter to the table row * defined by the second parameter. * @param obj The object to be added to the table. * @param posn The row number where the object is going to be added. */ public void setTableEntry(Object obj, int posn) { if (key.size() > posn) { key.removeElementAt(posn); key.insertElementAt(obj, posn); } } /** * Obtain the object placed at the table row specified by the parameter. * @param posn Table row where the object is to be obtained. * @return The table object at the row specified by the parameter. */ public Object getTableEntryAt(int posn) { Object result = null; if (key.size() > posn) result = key.elementAt(posn); return result; } /** * Check if the table has been fully filled up. * @return TRUE if all entries in the table is non-null object; * FALSE otherwise. */ public boolean full() { boolean f = true; for (int i = 0; i < tableSize(); i++) { if (key.elementAt(i) == null) { f = false; break; } } return f; } /** * Get the number of rows in the table where the contents are non-null * object. * @return The number of non-null object in the table. */ public int numOccupied() { int count = 0; for (int i = 0; i < tableSize(); i++) { if (key.elementAt(i) != null) count++; } return count; } /** * Check if a particular row in the table has a non-null object. * @param i The row number of the table to be checked. * @return TRUE if the row specified by the parameter is occupied. */ public boolean occupied(int i) { if (i >= 0 && i < tableSize()) return (key.elementAt(i) != null); else return true; } /** * Display a status summary of the table regarding the percentage * of the table being occupied, the number of clusters in the table, * and a rough idea of the location of the table being occupied. * @param g Graphical context of the drawing panel where the status * information is going to be shown. * @param x The left most position of the status information display. * @param y The top most position of the status information display. */ public void drawClusters(Graphics g, int x, int y) { g.setColor(Color.lightGray); g.drawRect(x, y, tableSize()*3 + 2, 21); g.setColor(Color.red); g.setFont(font); int numOccupied = 0; int numClusters = 0; for (int i = 0; i < tableSize(); i++) { if (key.elementAt(i) != null) { g.fillRect(x+1+i*3, y+1, 3, 20); numOccupied++; if (i==0) numClusters++; else if (key.elementAt(i-1) == null) numClusters++; } if ( (i%25) == 0 ) { g.setColor(Color.black); g.drawString("" + i, x+i*3, y - 2); g.setColor(Color.red); } } g.setColor(Color.black); g.drawString("Percent", x - 50, y + 30); g.drawString("full", x - 40, y + 42); g.drawString(""+ (numOccupied*100/tableSize()) + "%", x - 30, y + 16); g.drawString(""+ numClusters, x + tableSize()*3 + 10, y + 16); g.drawString("Clusters", x + tableSize()*3 + 4, y + 30); g.drawString("Address", x + tableSize()*3/2 - 20, y - 15); g.drawString("Keys Placed in Table", x + tableSize()*3/2 - 70, y + 35); } /** * Add an entry to the table and push the existing entries after this * newly added object one position down. * @param obj The new object to be added to the table. * @param posn The position in the table (row) where the new object is to * be added. */ public void addTableEntry(Object obj, int posn) { if (key.size() >= posn) { key.insertElementAt(obj, posn); panel.vScrollbar.setValues(panel.vScrollbar.getValue(), 1, 0, key.size()-1); } } /** * Get the maximum size of the table (including all null and non-null * objects). * @return The maximum size of the table. */ public int tableSize() { return key.size(); } /** * Check if the table contains a certain object specified by the parameter. * @param obj The object which is going to be checked for existence. * @return TRUE if the object exists; FALSE otherwise. */ public boolean contains(Object obj) { boolean contain = false; for (int i = 0; i < tableSize(); i++) { if (obj == null || key.elementAt(i) == null) continue; if (obj.equals(key.elementAt(i))) { contain = true; break; } } return contain; } /** * Get the location of an object in the table. * @param obj The object which location is being checked. * @return The row number of the object passed in as the parameter. This * method will return -1 if the object does not exist within the current * table. */ public int indexOf(Object obj) { int index = -1; for (int i = 0; i < tableSize(); i++) { if (obj == null || key.elementAt(i) == null) continue; if (obj.equals(key.elementAt(i))) { index = i; break; } } return index; } /** * Define the default size of the table. * @return The dimension of the table. By default is: 480x320. */ public Dimension preferredSize() { return new Dimension(480, 320); } /** * This method is invoked by the display manager when the * repaint() method of the panel is called. This method * is overridden here to eliminate the flashing characteristic during * the panel update. */ public void update(Graphics g) { Dimension d = size(); if (d.width < 1 || d.height < 1) return; if ((offscreen == null) || (d.width != offscreensize.width) || (d.height != offscreensize.height)) { offscreen = createImage(d.width, d.height); offscreensize = d; offGraphics = offscreen.getGraphics(); } offGraphics.setColor(getBackground()); offGraphics.fillRect(0, 0, d.width, d.height); offGraphics.setFont(font); fm = offGraphics.getFontMetrics(); paint(offGraphics); g.drawImage(offscreen, 0, 0, null); } /** * Method to draw the table canvas. */ public void paint(Graphics g) { panel_height = size().height; panel_width = size().width; int row = 1; for (int i = start; i < key.size(); i++) { drawBox(g, 0, row, ""+i, Color.black, Color.lightGray, 3); String content = (String)key.elementAt(i); if (content == null) { drawBox(g, 26, row, content, Color.black, Color.pink, 28); } else if (highlight == i) drawBox(g, 26, row, content, Color.white, Color.blue, 28); else drawBox(g, 26, row, content, Color.blue, Color.white, 28); row += vertSpace + 2;; } } // paint(); /** * This method is only called by the paint() method to draw * each entry of the table as a box. * @param g Graphical context. * @param x The left most position of the box. * @param y The top most position of the box. * @param str The String object to be drawn inside the box. * @param fg Foreground color (i.e. the text color) of the box. * @param bg Background color of the box. * @param max_length The max_length of the string to be displayed in * the box. */ public void drawBox(Graphics g, int x, int y, String str, Color fg, Color bg, int max_length) { int horizSpace = max_length * 8; g.setColor(bg); g.fillRect(x, y, horizSpace, vertSpace); g.setColor(Color.black); g.drawRect(x, y, horizSpace, vertSpace); g.setColor(fg); g.setFont(font); if (str != null) g.drawString(str, x + 2, y + vertSpace - 4); } } // TableCanvas