/** * Current Account Balances: Graphical Display Applet * @author Robert J Morton UK-YE572246C * @version 12 July 2000, 23 April 2012 * @copyright July 2000 Robert J Morton (all rights reserved) */ // THE PANEL ON WHICH THE ACCOUNT GRAPH IS DISPLAYED import java.awt.*; // for graphics operations (GUI) import javax.swing.*; // swing GUI widgets library import java.io.*; // for stream handling for the above public class graph extends JPanel { private static final Color bg2 = new Color(112,112,112), // graph background colour bg3 = new Color(160,160,160), // graticule colour fg1 = new Color(255,255,0), // my balance colour fg2 = new Color(0,255,255); // combined balance colour private boolean inflate = false, // inflation-correction on switch leap = false; // true if a leap year is selected private int //Used for both penalty threshold level and account balance for each day H = 0, w = 0, // horizontal distance for each vertical graticule line m = 0, // today's balance in integral pence year = 2001; // currently-selected year // Data input stream that holds the downloaded account data. private DataInputStream D; private maxmin mm; // instance reference to the statistics panel private mscale ms; // instance reference of the money-scale panel graph(maxmin mm, mscale ms) { // INSTANCE CONSTRUCTOR this.mm = mm; // instance reference of the max/min statistics panel this.ms = ms; // instance reference of the money-scale panel } //Set reference of the data input stream containing the account data. //set by savlim1 applet void setD(DataInputStream d) { D = d; } // set by selyear: true if selected year is a leap year void setLeap(boolean b) { leap = b; } //set by selyear: year number e.g. 2001 void setYear(int yr) { year = yr; } /* Called by selinfl. Sets whether or not the newly- selected year is a leap year then must repaint the graph with appropriate version of the account data. */ void setInfl(boolean b) { inflate = b; repaint(); } public void paint(Graphics g) { //DRAW THE VERTICAL GRATICULE LINES ONTO THE IMAGE img g.setColor(bg2); // set graph background colour g.fillRect(0,0,366,201); // clear the graph area within it g.setColor(bg3); // graticule colour w = 0; // horizontal distance for each vertical graticule line for(int i = 0; i < 12; i++) { // for each month shown int d = ms.getDays(i); // days in this month if(i == 1 && leap) d++; // add a day if leap year february g.drawLine(w, 0, w, 200); // vertical graticule lines w += d; // accumulated number of days } g.drawLine(w,0,w,200); // final vertical graticule line //DRAW THE HORIZONTAL GRATICULE LINES int z = 0; //vertical graticule increment for(int i = 0; i < 6; i++) { //for each £1000 graduation g.drawLine(0, z, w, z); //final horizontal annotation mark z += 40; //accumulated number of £s (scaled) } // DRAW THE RED PENALTY-THRESHOLD LINE H = 300000; // set penalty threshold // if the inflate flag is set, compute the inflated penalty threshold. if(inflate) H = infln.getInt(H,year); H /= 2500; // rescale H from £s to pixels H = 200 - H; // distance from top of graph to penalty line // Draw the savings penalty threshold figure in red. g.setColor(Color.red); g.drawLine(0, H, w, H); //PLOT THE GRAPH try { // try for IOException D.reset(); // reset byte array pointer to start of data w = 0; // initial x-bias for day number int // previous day's balances prev1 = 0, // for my account only prev2 = 0, // and for summed accounts a = 0, // initialise the total, max = 0, // maximum and min = 2000000; // minimum balances (integral pence) try { // try for EOFException while(true) { // infinite loop broken only by try failure m = 0; // today's balances prev1 = plot(g,prev1,fg1); // plot my account only prev2 = plot(g,prev2,fg2); // plot mine + ruby's balance a += H; // accumulate total pence if(max < H) max = H; // trap maximum balance if(min > H) min = H; // trap minimum balance w++; // increment the day number } } /* Terminate loop when attempt is made to read past the end of the byte array and afterwards, exception or not, display the statistics panel. */ catch(EOFException f) { } finally { mm.atualizar(max, min, a, w); } } catch(IOException e) { } // readByte() can throw an IOException also } private int plot(Graphics g, int prev, Color c) throws IOException { // read account's next day's balance from the input array int x = (int)D.readInt(); if(x == 0) return x; // don't plot zero balances m += x; // add today's balance to total if(inflate) // if inflation radio button checked H = infln.getInt(m,year); // compute inflated balance; else // otherwise the "normal" radio button is checked H = m; // so use normal balance. int h = H / 2500; // scale to pixels if(h < 0) h = -1; // don't plot below the zero line if(h > 200) h = 200; // don't plot above top of graph int y = 200 - h; // off-set it from y-axis zero /* Provided we are plotting beyond the first day of the year AND this plot is not the same height as the previous plot OR it is the same height but the account balance is at least zero AND less than the maximum the graph can show, THEN draw a blue line bet- ween the previous day's balance plot and this day's balance plot. */ if(w > 0 && (y != prev || (y == prev && h > -1 && h < 201))) { g.setColor(c); g.drawLine(w-1, prev, w, y); } return y; // return today's balance as previous balance for next pass } }