📄 programcanvas.java
字号:
import java.awt.*;import java.awt.image.*;import java.util.Vector;import java.util.Enumeration;import java.awt.event.*;import java.lang.Math;import com.sun.java.swing.*;/* This class is the canvas on which all drawing of Jumpshot data is done A new data structure containing a vector of JProcess objects resides here. Each of these JProcess objects represent a process and contain a vector 'stateVector' which is a list of all states of that process, in ascending order of their end timestamps. Double Buffering is used for smooth scrolling. For an explanation see the documents.*/public class ProgramCanvas extends JComponent implements ComponentListener { Graphics currG; public ClogDisplay parent; boolean blink = false; boolean blFlag = true; //Data Structures //Vector containing all displayed processes including those whose //dispStatus is turned off and which are not deleted. Vector procVector; Vector dprocVector; //Vector containing all deleted processes Vector dtypeV; double xDensity; //pixels / second double yDensity; //pixels / process vertical thickness int _xPix; //width of each image int _yPix; //height of each image int widthCan; //height of the viewport int heightCan; //width of the viewport double maxT; //Maximum time in the display double tMaxT; //end time of the last state in all processes int maxH; //horizontal pixel limit on display //horizontal distance between the start of the viewport and the zoom lock line int zDist; int panePosX; //horizontal scroll postion of ScrollPane container int sbPos; int cursorPos; //Horizontal cursor position in this canvas int tbegH; //previous horizontal scrollbar value boolean fflagH, bflagH; //flags describing forward or backward scrolling (horizontally) public double zoomH; //double value describing the zoom double zF; //zoom Factor double begTime; //time at start of the viewport double endTime; //time at the end of the viewport double currTime; //time at the current cursor position double zXTime; //time at which the zoom lock line was set double elapsedPoint; //time at which the elapsed time line was set private boolean elTLineDispStatus = true; //elapsed time line display status private boolean zoomLkLineDispStatus = true; //zoom lock line display status int proct; //process count int dproct; //deleted process count int pu = 1; int endGap = 5; //horizontal gap at the end of drawings so that //the drawings towards the right end are not //covered by the ScrollPane Container MyImage [] img; //array of 3 offscreen images MyImage currImg; //current image placed in the viewport int lineSize, rulerHt, hBWt, allDispHt, eachDispHt, eachDispIHt, fDescent; public int dpi; //number of pixels / inch on the screen public FontMetrics fm; //FontMetrics object describing the curren font int maxLevel = 0; //maximum level of nesting double nestFactor; //value describing the height difference between levels //nestFactor * yDensity will be the difference in height between two consecutive levels boolean message = false; //value decribing whether an arrow circle is present ?? boolean Windows = false; //catering for the extra scrollbar boolean arrowDispStatus = true; public boolean setupComplete; //setup status Timer timer; int totalProc; private int elTimeStrW, zLockStrW; //Constructor public ProgramCanvas () {super ();} //Setup methods ----------------------------------------------------------- void init (ClogDisplay p) { setupComplete = false; parent = p; setupData (); adjustCanvasStuff (); setupStates (); //if (parent.dtype == CONST.TIMELINES) setupNestedStates (); dtypeV = new Vector (); dtypeV.addElement (new Integer (parent.dtype)); parent.optionsDlg.addDisplay (parent.dtype); //else setupMtns (); totalProc = proct; tMaxT = maxT; timer = new Timer (200, new TimerListener ()); Resize (); setupEventHandlers (); adjustStartEndTimes (); setupComplete = true; } private void setupData () { proct = 0; dproct = 0; procVector = new Vector (); dprocVector = new Vector (); nestFactor = 0.10; zoomH = 1.0; zF = 2.0; begTime = 0.0; zXTime = 0.0; elapsedPoint = 0.0; hBWt = 2; } private void adjustCanvasStuff () { Font f = parent.frameFont; setFont (f); fm = getToolkit ().getFontMetrics (f); lineSize = fm.getHeight (); rulerHt = 3 * lineSize; zLockStrW = fm.stringWidth ("Zoom Lock"); elTimeStrW = fm.stringWidth ("Elapsed Time"); fDescent = fm.getDescent (); dpi = getToolkit ().getScreenResolution (); } private void setupStates () { Enumeration enum = parent.data.elements (); while (enum.hasMoreElements ()) { StateInfo evt = (StateInfo)enum.nextElement (); addState (evt); } enum = procVector.elements (); while (enum.hasMoreElements ()) { JProcess p = (JProcess)enum.nextElement (); p.begT = ((ProcessState)p.procStateVector.firstElement ()).info.begT; } } /* private void setupMtns () { Enumeration enum = parent.mtns.elements (); while (enum.hasMoreElements ()) { MtnInfo mtn = (MtnInfo)enum.nextElement (); if (mtn.endT > maxT) maxT = mtn.endT; } }*/ /** * This method goes trough the stateVector for each process and assigns the * appropriate level to each state. If no nesting is present then a level of * 0 will be assigned */ private void setupNestedStates () { waitCursor (); maxLevel = 0; Enumeration enum = procVector.elements (); while (enum.hasMoreElements ()) { //Scan each process StateInfo prev = null; JProcess p = (JProcess)enum.nextElement (); Vector a = p.procStateVector; //For each process assign levels to all states for (int i = a.size () - 1; i >= 0; i--) { ProcessState currState = (ProcessState)a.elementAt (i); if (currState.info.stateDef.checkbox.isSelected ()) { if (prev != null) { if (prev.begT <= currState.info.begT) { //Entering here should mean that this state is nested inside the //previous state and hence shoud be smaller. currState.info.level = prev.level + 1; currState.info.higher = prev; } else { //Entering here means that the this state is independent of the previous //state. however there may be higher states that contain both this and //the previous state. An EFFICIENT WAY FOR THIS HAS TO BE DETERMINED. StateInfo temp = prev.higher; currState.info.level = prev.level; while (temp != null && temp.begT > currState.info.endT) { //Means that the current State is definately not containted in temp.. currState.info.level --; temp = temp.higher; } currState.info.higher = temp; } } prev = currState.info; } if (currState.info.level > maxLevel) maxLevel = currState.info.level; } } normalCursor (); } /** * Draw initial view consisting of entire data in viewport */ private void drawInitImg () { double b = begTime, e = getTime (_xPix); img [0].drawRegion (b, e); currImg = img [0]; panePosX = _xPix; repaint (); } //end of setup methods----------------------------------------------------------- public void paintComponent (Graphics g) { //We request keyboard focus out here so that we can catch events for locking zoom, etc. requestFocus (); //3 Images are painted each time. The reason we use images rather than directly drawing //onto the graphics context is that the drawings of one image can be taking place //concurrently with the other using threads into offscreen graphic contexts assoc. //with the respective images. While printing we do the opposite if (setupComplete && currImg != null){ int prevH = getPrev (currImg.imgIdH); int nextH = getNext (currImg.imgIdH); if (blFlag || !timer.isRunning ()) { img [prevH].paintStuff1 (0, g, this); currImg.paintStuff1 (_xPix, g, this); img [nextH].paintStuff1 (_xPix + _xPix, g, this); /*g.drawImage (img [prevH].img, 0, 0, this); g.drawImage (img [prevH].timeimg, 0, _yPix, this); g.drawImage (currImg.img, _xPix, 0, this); g.drawImage (currImg.timeimg, _xPix, _yPix, this); g.drawImage (img [nextH].img, _xPix + _xPix, 0, this); g.drawImage (img [nextH].timeimg, _xPix + _xPix, _yPix, this);*/ } else { img [prevH].paintStuff2 (0, g, this); currImg.paintStuff2 (_xPix, g, this); img [nextH].paintStuff2 (_xPix + _xPix, g, this); /*g.drawImage (img [prevH].img1, 0, 0, this); g.drawImage (img [prevH].timeimg, 0, _yPix, this); g.drawImage (currImg.img1, _xPix, 0, this); g.drawImage (currImg.timeimg, _xPix, _yPix, this); g.drawImage (img [nextH].img1, _xPix + _xPix, 0, this); g.drawImage (img [nextH].timeimg, _xPix + _xPix, _yPix, this);*/ } } if (zoomLkLineDispStatus && zXTime >= begTime && zXTime <= endTime) { int xcord = panePosX + getEvtXCord (zXTime - begTime); g.setColor (Color.white); g.drawLine (xcord, 0, xcord, _yPix); g.fillRect (xcord, _yPix - lineSize, zLockStrW + 2, lineSize); g.setColor (Color.black); g.drawRect (xcord, _yPix - lineSize, zLockStrW + 1, lineSize - 1); g.setColor (Color.red); g.drawString ("Zoom Lock", xcord + 1, _yPix - fDescent); } if (elTLineDispStatus && elapsedPoint >= begTime && elapsedPoint <= endTime) { int xcord = panePosX + getEvtXCord (elapsedPoint - begTime); g.setColor (Color.white); g.drawLine (xcord, 0, xcord, _yPix); g.fillRect (xcord, _yPix - lineSize, elTimeStrW + 2, lineSize); g.setColor (Color.black); g.drawRect (xcord, _yPix - lineSize, elTimeStrW + 1, lineSize - 1); g.setColor (Color.red); g.drawString ("Elapsed Time", xcord + 1, _yPix - fDescent); } } //methods for handling smooth scrolling, double buffereing------------------------ /** * Allocate memory for 3 offscreen images */ private void setupImg () { killImgs (); setValues (); parent.vcanvas1.repaint (); parent.vcanvas2.repaint (); img = new MyImage [3]; for (int i = 0; i < 3; i++) { img [i] = new MyImage (i, _xPix, _yPix, dtypeV, this); } } protected void setValues () { int numDisp = dtypeV.size (); allDispHt = _yPix - rulerHt; eachDispHt = (int)Math.rint (allDispHt / (double)numDisp); eachDispIHt = eachDispHt - 2 * hBWt; if (eachDispHt < 1) eachDispHt = 1; //eachDispHt should be non zero calcYDensity (); } Image getOffScreenImage (int x, int y) {return createImage (x, y);} private void killImgs () { if (img != null) for (int i = 0; i < 3; i++) if (img [i] != null) { img [i].kill (); img [i] = null; } } /** * Get the appropriate display for the given scroll bar position */ void adjustImgH (int x) { MyImage prev = img [getPrev (currImg.imgIdH)]; MyImage next = img [getNext (currImg.imgIdH)]; int epos1 = getEvtXCord (currImg.begT); int epos2 = getEvtXCord (currImg.endT); int beg = x, end = x + widthCan, tendH = tbegH + widthCan; int gap1 = epos1 - beg; int gap2 = end - epos2; panePosX += (beg - tbegH); //Move the scroll position according to the increment if ((beg < epos1 && tbegH > epos1)) bflagH = true; else if (beg > epos1 && tbegH < epos1) bflagH = false; if ((end > epos2 && tendH < epos2)) fflagH = true; else if (end < epos2 && tendH > epos2) fflagH = false; int gr = getCurrGridH (x); boolean change = ((bflagH && gap1 >= widthCan) || (fflagH && gap2 >= widthCan) || gap1 > _xPix || gap2 > _xPix)? true : false; if (change) { getImgH (gr); panePosX = _xPix + (x - (gr * _xPix)); bflagH = false; fflagH = false; } tbegH = beg; begTime = getTime (tbegH); adjustStartEndTimes (); // zXTime = getTime (tbegH); } private int getGridValue (int val) {return val - (getCurrGridH (val) * _xPix);} /** * Get the appropriate display for the given grid */ private void getImgH (int grid) { double begT = getTime (grid * _xPix); double endT = begT + getTime (_xPix); MyImage i = searchImg (begT, endT); if (i != null) currImg = i; else currImg.drawRegion (begT, endT); centralizeH (); repaint (); } /** * search for a image with the given starting and ending times */ private MyImage searchImg (double begT, double endT) { for (int i = 0; i < 3; i++) { MyImage cImg = img [i]; if (cImg != null && cImg.begT == begT && cImg.endT == endT) return cImg; } return null; } /** * Return the appropriate value from the circular buffer */ private int getNext (int t) {return (t + 1) % 3;} private int getPrev (int t) { int ret = (t - 1) % 3; if (t == 0) ret = 2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -