/* * Copyright (c) 1997-98 * NorthEast Parallel Architectures Center, Syracuse University. * All Rights Reserved. Permission to use, copy, modify, and distribute this * software and its documentation for educational, research and non-profit * purposes, without fee, and without a written agreement is hereby granted, * provided that the above copyright notice and this paragraph appear in all * copies. Permission to incorporate this software into commercial products may * be obtained by contacting the NorthEast Parallel Architectures Center. * * The software program and documentation are supplied "as is", * without any accompanying services from NPAC. NPAC does not * warrant that the operation of the program will be uninterrupted or * error-free. The end-user understands that the program was developed for * research purposes and is advised not to rely exclusively on the program for * any reason. * */ package cis600.client; import java.awt.*; import java.awt.event.*; import java.awt.image.*; import java.util.Vector; import org.omg.CosNaming.*; import cis600.util.*; /** * Histogram, Pie-chart & Probability Distribution Functions in a single * frame. The probability distribution Function is plotted in ranges. * * @version 0.5 20 April 1998 * @author Shrideep Pallickara * */ public class Histogram extends java.applet.Applet implements Runnable{ /** Variables we are gonna use during the double-buffering */ private Image buf; private Graphics gBuf; /* End of variables used during double buffering */ /** Picking up the width and height from the HTML page */ int xsize=400,ysize=800; /** Self-explanatory variable names, the helper variable is used during the plotting of the pie-chart, in the TransientBuffer() routine */ int currSample, prevSample, helper=0; int basesize=0; /**Vector which keeps track of the samples */ Vector plotInfo; /**Vector which keeps track of the distribution */ Vector distributionInfo; int plotTracker=0; double scale=1; /** The thread which controls the repaint() */ Thread scroller; /**Timeslice allocated to the thread */ int timeout = 250; int count, MaxCount=151; /** This is our random number generator */ cis600.util.RandomGen _randomizer; int numberOfRanges=0; boolean isApplication=false; /** To be used to display revelant textual information */ private Font lbl = new Font("Helvetica", Font.BOLD, 10); /** The Null constructor for the class */ public Histogram() { } /** * The init() method is being used both by the applet and application * capabilities of the program. Depending on how its being used viz. applet * OR application capability of the program * */ public void init() { if (!isApplication) { xsize=getSize().width; ysize=getSize().height; buf = createImage(xsize,ysize); gBuf = buf.getGraphics(); } getRandomizerHandle(); setBackground(Color.white); plotInfo=new Vector(); distributionInfo = new Vector(); numberOfRanges = ysize/50; for ( int i=0; i< numberOfRanges; i++) distributionInfo.addElement(new Integer(0)); for (int i=0; i <xsize; i++) randomize(); } private void getRandomizerHandle() { try { /* Initialize the ORB.*/ org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(this, null); /* Get a reference to the Naming Service */ org.omg.CORBA.Object nameServiceObj = orb.resolve_initial_references("NameService"); /* Check to see if the operation involving getting a reference to the NameService was successful */ if (nameServiceObj == null) { System.out.println("Name Service Object = null"); return; } org.omg.CosNaming.NamingContext nameService = org.omg.CosNaming.NamingContextHelper.narrow(nameServiceObj); if (nameService == null) { System.out.println("nameService = null"); return; } NameComponent[] collabName = { new NameComponent("Utilities", "Randomizer")}; _randomizer= cis600.util.RandomGenHelper.narrow(nameService.resolve(collabName)); System.out.println("Received Generator Handle"); } catch(Exception e) { System.out.println("Exception: " + e); } } /** * Start the thread which controls, the animation of the Randomizer function * Called automatically within the applet but requires an explicit call in * the application version of the program. * */ public void start() { if (scroller == null) { scroller = new Thread(this); scroller.start(); } } public void stop() { if (scroller != null) { scroller.stop(); scroller = null; } } public void run() { try { Thread.currentThread().sleep(5*timeout);} catch (InterruptedException e){} for (count=0; count <= MaxCount; ) { try {Thread.currentThread().sleep(timeout);} catch (InterruptedException e){} randomize(); repaint(); } } /* Dispose off the graphics context */ public void destroy() { gBuf.dispose(); } public void update(Graphics g) { paint(g); } /* * This is the fixed buffer employed in the double-buffering scheme * Basically its responsible, for updating the status information of * the pie-chart, the histogram and PDF headers. Besides this the method * is responsible for drawing the pie-chart with the value of the previous * sample as a precursor to, the animation to the present sample. * */ public void paintFixedBuffer(Graphics g) { double fromX=-Math.PI*scale; double toX=Math.PI*scale; double topY=xsize/2.0*scale; double bottomY=-topY; g.setColor(Color.white); g.fillRect(0,0,xsize, ysize); g.setColor(Color.blue); g.setFont(lbl); g.drawString("PIE CHART Reverting from "+prevSample+" to "+currSample , 40, 10); g.drawString("The HISTOGRAM OF THE ARRIVING SAMPLES", 40, 2*(ysize/3)+40); /*g.drawString("The PROBABILITY DISTRIBUTION FUNCTION", 40, 2*(ysize/3)+40); */ g.drawLine(0,ysize-1, xsize, ysize-1); g.drawLine(0,ysize, 0, ysize-ysize*(3/4)); for (int i=1; i<15; i++) { g.setColor(Color.darkGray); g.fillArc(25, 25+i, 300,120, 0, prevSample); g.setColor(Color.gray); g.fillArc(25, 25+i, 300,120, prevSample, 360-prevSample); } g.setColor(Color.lightGray); g.fillArc(25, 25, 300,120, 0, prevSample); g.setColor(Color.black); g.fillArc(25, 25, 300,120, prevSample, 360-prevSample); } /* * This method is reponsible for the 3D animation of the pie-chart, reverting * to the new value of the sample. * This method is called approx. Math.abs(currentSample-prevSample) * This method reduces/increases the value of the pir-chart plot-angle by * a single degree, to simulate animation. * */ public void paintTransientBuffer(Graphics g) { if (currSample > prevSample) { helper++; if ((prevSample-helper )!=360) { g.setColor(Color.darkGray); for (int i=1; i<15; i++) g.fillArc(25, 25+i, 300,120, 0, prevSample+helper); g.setColor(Color.lightGray); g.fillArc(25, 25, 300,120, 0, prevSample+helper); } } if (currSample < prevSample){ helper++; if ((prevSample-helper )!=0) { for (int i=1; i<15; i++) { g.setColor(Color.gray); g.fillArc(25, 25+i, 300,120, prevSample-helper, 360-prevSample+helper); } g.setColor(Color.black); g.fillArc(25, 25, 300,120, prevSample-helper, 360-prevSample+helper); for (int i=1; i<15; i++) { g.setColor(Color.darkGray); g.fillArc(25, 25+i, 300,120, 0, prevSample-helper); } g.setColor(Color.lightGray); g.fillArc(25, 25, 300,120, 0, prevSample-helper); } } } /** * This method plots the histogram of all the previous samples, and the * current sample. */ public void paintHistogram(Graphics g) { g.setColor(Color.black); int temp_size; for (int i=0; i < plotInfo.size(); i++) { temp_size=(int)((Integer)plotInfo.elementAt(i)).intValue(); g.drawLine(i,(ysize*2)/3,i,(2*ysize/3-temp_size/2)); } } /** * This method plots the Probability Distribution Function of the Values * generated by the Random Number generator. A flat probability distribution * indicates the efficiency of the Random Number generator. * The PDF is plotted for 40 ranges of the values generated by the * Randomizer. * */ public void plotDistribution(Graphics g) { int value; int plotting; plotting = distributionInfo.size(); Color[] col = new Color[plotting]; int l=135,m=165,n=250; for (int i=0; i <plotting; i++) col[i]= new Color( l+ 5*i, m -6*i, n -13*i); for (int i=0; i <plotting/2; i++) { g.setColor(col[i]); value = ((Integer)distributionInfo.elementAt(i)).intValue(); for (int j=0; j < 35; j ++) { g.drawLine(35*i+j, ysize, 35*i+j,(ysize-value)); } } for (int i=plotting/2; i < plotting;i++) { g.setColor(col[i]); value = ((Integer)distributionInfo.elementAt(i)).intValue(); for (int j=0; j < 35; j ++) { g.drawLine(35*(plotting-i)+j, ysize, 35*(plotting-i)+j,(ysize-value)); } } } /** * Paints the Fixed Buffer first, then the pie-chart histogram and PDF in * that order. * */ public void paint(Graphics g) { if (isApplication && buf==null) { buf = createImage(xsize, ysize); gBuf = buf.getGraphics(); } float f = (((Integer)plotInfo.lastElement()).floatValue()/(ysize/2))*360; currSample = (int) f; helper = 0; paintFixedBuffer(gBuf); paintHistogram(gBuf); /* plotDistribution(gBuf); */ if (prevSample!=currSample) { for ( int i=0; i < Math.abs(prevSample-currSample-1) ; i++) { paintTransientBuffer(gBuf); g.drawImage(buf,0,0,this); } } prevSample=currSample; } /** * This method is invoked by the thread responsible for the animation */ public void randomize() { if (plotTracker >xsize) { plotInfo.removeElementAt(0); plotTracker--; } int temp = _randomizer.nextInt((ysize/2-1)); plotInfo.addElement(new Integer(temp)); temp = (int)(temp/50); int temp2 = ((Integer)distributionInfo.elementAt(temp)).intValue(); temp2++; distributionInfo.setElementAt(new Integer(temp2), temp); plotTracker++; } public static void main(String args[]) { Histogram _randomizer = new Histogram(); _randomizer.isApplication =true; _randomizer.init(); RandomizerFrame _frame = new RandomizerFrame(_randomizer); } } /** * This class enables the program to function as an application too. */ class RandomizerFrame extends Frame implements WindowListener { Histogram _randomizer; public RandomizerFrame(Histogram _randomizer) { this._randomizer = _randomizer; setTitle("Randomizer Distribution Function"); add(_randomizer); addWindowListener(this); pack(); setSize(_randomizer.xsize, _randomizer.ysize); show(); _randomizer.start(); } public void windowClosed(WindowEvent event) {} public void windowDeiconified(WindowEvent event) {} public void windowIconified(WindowEvent event) {} public void windowActivated(WindowEvent event) {} public void windowDeactivated(WindowEvent event) {} public void windowOpened(WindowEvent event) {} public void windowClosing(WindowEvent event) { System.out.println("Resources to be returned shortly ....."); System.out.println("Killing the thread"); _randomizer.stop(); System.out.println("Disposing off the graphics context"); _randomizer.destroy(); System.out.println("Done ......"); System.exit(0); } }