📄 ch11.htm
字号:
show();<BR> }<BR> }<BR><BR> // Update message sent when repainting is needed...<BR> // Prevent paint from getting cleared out...<BR> public void update(Graphics g) {<BR> paint(g);<BR> }<BR><BR><BR> // If table is ready, paint all the canvases...<BR> public synchronized void paint(Graphics g) {<BR> if (!(ElectionTable.getElectionTable().ready()))<BR> return;<BR> Dimension d = size();<BR> int height = g.getFontMetrics(getFont()).getHeight();<BR> int y = 2 * height;<BR> y = sc.paint(g,0,y,d.width);<BR> y += states.paint(g,0,y,d.width,d.height- y);<BR> g.drawString("RegisteredUsers: " + getUsers(),<BR> 10,d.height- height);<BR> }<BR><BR> // Toggle radio buttons...<BR> public boolean action(Event ev,Object o) {<BR> if (ev.target instanceof Checkbox){<BR> if (ev.target.equals(graphView)){<BR> states.setMode(StateBreakdownCanvas.GRAPHICS);<BR> sc.setMode(SummaryCanvas.GRAPHICS);<BR> }<BR> else {<BR> states.setMode(StateBreakdownCanvas.TEXT);<BR> sc.setMode(SummaryCanvas.TEXT);<BR> }<BR> repaint();<BR> }<BR> return true;<BR> }<BR><BR><BR> public String getDestHost()<BR> {<BR> return destHost;<BR> }<BR><BR> public int getDestPort()<BR> {<BR> return destPort;<BR> }<BR><BR> public synchronized void recvNewData(byte[]newDataBlock, boolean error)<BR> {<BR> if ( error)<BR> {<BR> ct.send("REFRESH");<BR> return;<BR> }<BR> String cmd= new String(newDataBlock, 0);<BR> StringTokenizercmds = new StringTokenizer(cmd, " \t");<BR> String current= cmds.nextToken();<BR> if (current.equals("CLIENTS"))<BR> users = cmds.nextToken();<BR> else if(current.equals("RESULTS"))<BR> {<BR> nRows = Integer.valueOf(cmds.nextToken()).intValue();<BR> nCols = Integer.valueOf(cmds.nextToken()).intValue();<BR> results = new String[nRows][nCols];<BR> for ( int x = 0; x < nRows; x++ )<BR> {<BR> for ( int y = 0; y < nCols; y++ )<BR> {<BR> results[x][y]= cmds.nextToken("|\r\n");<BR> }<BR> }<BR> // Update the election table with the new data...<BR> ElectionTable.getElectionTable().tableUpdate(nRows,results);<BR> }<BR> // QUERYresponse is unimplemented because<BR> // thisapplet currently sends no QUERY commands<BR> else if(current.equals("QUERY_RSP"))<BR> {<BR> }<BR> }<BR><BR> public synchronized String getUsers()<BR> {<BR> if (users != null)<BR> returnusers;<BR> return numUsers;<BR> }<BR><BR> public void start()<BR> {<BR> ct = new DGTPClient(this);<BR> ct.start();<BR> }<BR><BR> public void stop()<BR> {<BR> System.out.println("Election.stop()");<BR> ct.terminate();<BR> }<BR><BR> public void connectRefused()<BR> {<BR> }<BR>}</TT></BLOCKQUOTE><HR><H4>The ElectionTable Class</H4><P>The ElectionTable class, shown in Listing 11.3, creates a privatetable of the individual state and summary totals. Since ElectionTableis responsible for keeping the local cache of the election data,it isn't allowed to be instantiated by an external class. Thetable has only one instance because it has a private constructor;objects that use the data must get a reference to the table objectfrom a public ElectionTable method called <TT>getElectionTable()</TT>.<P>An internal array, called <TT>states</TT>,maintains each state's election information. It is composed ofStateEntry objects that contain electoral information about thestate, as well as the state totals of the two candidates. The<TT>states</TT> array is not createdin the constructor; rather, it's created when data is first receivedin the <TT>tableUpdate()</TT> method,the only entry point into the table for updating data. When the<TT>states</TT> array is null, itis set up in the <TT>initializeTable()</TT>method. All subsequent updates (called through the <TT>partialUpdate()</TT>method) are applied to the <TT>states</TT>array created at initialization. These write methods are synchronizedto prevent any collisions by other threads reading data.<P>After each update, ElectionTable compiles the state totals toget the summary figures by using the <TT>updateTotals()</TT>method. Since ElectionTable is an instance of the Observable class,it notifies its observers of the changes at the end of the <TT>tableUpdate()</TT>method.<P>The observers use the <TT>getStates()</TT>method to walk through the results of the individual states. Thismethod has an interesting solution to the synchronization problem,such as when an update occurs while an observer is reading thestate information. The <TT>getStates()</TT>method makes a shallow copy of the <TT>states</TT>array; it's "shallow" because it copies only the arrayreferences and not the actual state elements. If an update threadmodifies the original States table, it doesn't affect the copythe reader has because the update makes new StateEntry objectsfor each update. Therefore, the reader won't be adversely affectedby any updates.<HR><BLOCKQUOTE><B>Listing 11.3. The ElectionTable class.<BR></B></BLOCKQUOTE><BLOCKQUOTE><TT>import java.lang.*;<BR>import java.util.Observable;<BR><BR>// This class keeps a local cache of the election results<BR>// The table can only be created once so constructor is private...<BR>// A producer thread keeps the table updated<BR>public class ElectionTable extends Observable {<BR> // The table is static and so can be created only once<BR> private static ElectionTable table = new ElectionTable();<BR><BR> // Data objects...<BR> Candidate Incumbent;<BR> Candidate Challenger;<BR> int totalPopular;<BR> static StateEntry states[];<BR><BR> // Create the table information...<BR> private ElectionTable() {<BR> // Set up the candidates...<BR> Incumbent = new Candidate("Incumbent");<BR> Challenger = new Candidate("Challenger");<BR> // Not ready yet...<BR> states = null;<BR> }<BR><BR> // Get reference to election table...<BR> public static synchronized ElectionTable getElectionTable(){<BR> return table;<BR> }<BR><BR> // See if table is ready...<BR> public static synchronized boolean ready() {<BR> return ((states != null) ?(true) : (false));<BR> }<BR><BR> // Update the states table with new values...<BR> public void tableUpdate(int rows,String results[][]){<BR> if (states == null)<BR> initializeTable(rows,results);<BR> else<BR> partialUpdate(rows,results);<BR> // Update totals...<BR> updateTotals();<BR> // Notify observers of changes...<BR> setChanged();<BR> notifyObservers();<BR> }<BR><BR> // Initialize the table with the first batch of data...<BR> // Code ASSUMES that the results are ordered by<BR> // state and then candidate<BR>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -