⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 queuedrawer.java

📁 一个用于排队系统仿真的开源软件,有非常形象的图象仿真过程!
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/**    
  * Copyright (C) 2006, Laboratorio di Valutazione delle Prestazioni - Politecnico di Milano

  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.

  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.

  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
  
/*
 * Created on 16-mar-2004 by Ernesto
 *
 */
package jmt.jmarkov.Graphics;

import jmt.jmarkov.Graphics.constants.DrawConstrains;
import jmt.jmarkov.Graphics.constants.DrawNormal;
import jmt.jmarkov.Queues.Exceptions.NonErgodicException;
import jmt.jmarkov.Queues.MM1Data;
import jmt.jmarkov.Queues.QueueLogic;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.*;
import java.util.Vector;



/**
 * MMQueues
 * --------------------------------------
 * 16-mar-2004 - Graphics/QueueDrawNotifier.java
 * 
 * @author Ernesto
 */
public class QueueDrawer extends JComponent implements Notifier, Runnable {

	//NEW
    //@author Stefano Omini
    // introduced DEBUG var to skip System.out.println() calls in final release
    private static final boolean DEBUG = false;
    //end NEW

    private QueueLogic ql;
	private Vector jobsv;
	private MM1Data mm1;
	private double Ui;
	
	//timings
	private long remainingTime, 
				 totTime, 
				 runTime,  
				 FPMS = 100;
				 
	//queue data
	private int jobs = 0,
				donejobs = 0,
				totjobs = 0,
				queueMax = 0,
				queueLen = 0,
				queueMedia = 0,
				lostJobs = 0,
				view = 0,
				VIEWS = 2;

	
	//panel settings
	private double panelH = 250,
				   panelW = 400,
				   minH = 100,
				   minW = 400; 
	
	//draw settings
	private DrawConstrains dCst;
	private static double 
						START_GAP,
						END_GAP,
						ELEM_HEIGHT,
						ELEM_WIDTH,
						ELEMS_GAP,
						PROC_RAD,
						STAT_RAD,
						MORE_JOBS_MAX = 100,
						LOST_JOBS_MAX = 100;
	private Rectangle2D[] queue;
	private RoundRectangle2D viewB;
	private Ellipse2D processor, occupiedEll;
	private Rectangle2D occupiedRect, moreStatiRect, lostJobsR, txtBounds, tb;
	private Area  occupiedArea, jobsRemaining;
	private String moreJobsStr, lostJobsStr;
	private Stroke stroke;
	private Font f;
	private String[] legendaS;
	private Color[] legendaC;
	
	// color settings
	private Color emptyC = Color.WHITE,
				  queueC = Color.BLUE,
				  busyC = queueC.brighter().brighter(),
				  animC = Color.RED;
	private boolean procUseGradient = true,
					queueUseGradient = true,
					gradientF,
					viewButtonClicked = false;
	/**
	 * Costruisce il grafico della coda in un pannello di 
	 * altezza = 250, larghezza = 400
	 *
	 */
	public QueueDrawer(QueueLogic ql) {
		super();
		this.ql = ql;
		panelW = this.getWidth();
		panelH = this.getHeight();
		init();
	}

	public QueueDrawer(Dimension panelSize, QueueLogic ql){
		super();
		this.ql = ql;
		panelW = panelSize.width;
		panelH = panelSize.height;
		init();
	}
	

	void init(){
		changeDrawSettings(new DrawNormal());
		setColors(Color.white,Color.BLUE,Color.RED, true);
		legendaS = new String[3];
		legendaC = new Color[3];
		legendaS[0] = "current queue";
		legendaC[0] = queueC;
		legendaS[1] = "lost jobs";
		legendaC[1] = Color.BLACK;
		legendaS[2] = "avg.utilization";
		legendaC[2] = busyC;
		this.reset();
		jobsv = new Vector();
		viewB = new RoundRectangle2D.Double();
		this.addMouseListener(new MouseListener() {
			public void mouseClicked(MouseEvent e) {
			}

			public void mouseEntered(MouseEvent e) {

			}

			public void mouseExited(MouseEvent e) {
			}

			public void mousePressed(MouseEvent e) {
				if (viewB.contains(e.getX(), e.getY())){
					viewButtonClicked = true;
					repaint();
				} 
			}

			public void mouseReleased(MouseEvent e) {
				if (viewB.contains(e.getX(), e.getY())){
					viewButtonClicked = false;
					changeView();
					repaint();
				} 
			}
		});

	}

	public void changeDrawSettings(DrawConstrains dCst){
		this.dCst = dCst;
		
		resize();
		
		//assegno le costanti di disegno
		f = dCst.getFont();
		stroke = dCst.getDrawStroke();
		START_GAP = dCst.getStartingGap();
		END_GAP =  dCst.getStartingGap();
		ELEM_HEIGHT = dCst.getElementHeight();
		ELEM_WIDTH = dCst.getElementWidth();
		ELEMS_GAP = dCst.getElementsGap();
		PROC_RAD = dCst.getProcessorRadius();
		
		//inizializzo la coda
		queueLen = queueLenght();
		queue = new Rectangle2D.Double[queueLenght()];
		processor = new Ellipse2D.Double();	
		//repaint();
	}
	
	/* (non-Javadoc)
	 * @see Graphics.Notifier#runningIn(double)
	 */
	public void runningIn(double t) {
		runTime = (long)t + System.currentTimeMillis();
		remainingTime = totTime = (long)t;
		mm1 = (MM1Data) jobsv.elementAt(0);
		jobsv.remove(0);
		mm1.si = t;
		Ui = mm1.getUi(); 
		this.repaint();	
	}
	
	
	/**
	 * Imposta il numero medio di stati occupati
	 * @param s numero medio di stati occupati
	 */
	public void setMediaJobs(int s){
		queueMedia = s;
		this.repaint();
	}
	
	public void setMaxJobs(int j){
		queueMax = j;
		if (queueMax > 0) MORE_JOBS_MAX = j;
		else {
			reset();
			MORE_JOBS_MAX = 100;
			}
			if (DEBUG) {
                System.out.println("max jobs=" + queueMax);
            }
		this.repaint();
	}

	/* (non-Javadoc)
	 * @see Graphics.Notifier#addingToQ()
	 */
	public void addingToQ(double t) {
		//System.out.println("jobs:" + jobs);
		jobs++;
		if((jobs > queueMax) && (queueMax > 0)) lostJobs++;
		this.repaint();
		mm1 = new MM1Data();
		mm1.lambdai = t;
		jobsv.add(mm1);
	}

	/* (non-Javadoc)
	 * @see Graphics.Notifier#removingFromQ()
	 */
	public void removingFromQ() {
		//System.out.println("jobs:" + jobs);
		donejobs++;
		jobs--;

	}
	/* (non-Javadoc)
	 * @see Graphics.Notifier#reset()
	 */
	public void reset() {
		jobs = 0;
		donejobs = 0;
		totjobs =0;
		runTime = 0;
		totTime = 0;
		remainingTime = 0;
		donejobs = 0;
		lostJobs = 0;
		Ui = 0.0;
	}
	
	public void paint(Graphics g){
		Graphics2D g2d = (Graphics2D)g;
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		
		g2d.setStroke(stroke);
		panelW = this.getWidth();
		panelH = this.getHeight();
		changeDrawSettings(dCst);
		viewB = drawViewButton(10.0,10.0,g2d,false,false);
		viewB = drawViewButton(
			panelW - viewB.getWidth() - END_GAP,
			panelH - viewB.getHeight() - 1,
			g2d,true,
			viewButtonClicked);
		START_GAP = START_GAP * 2 + 
			drawLegend(
				legendaC,
				legendaS,
				dCst.getFont(),
				START_GAP,
				START_GAP,
				g2d ,false);
		
		for (int i = 0; i < queueLenght(); i++){
			if (i < jobs){
				drawQueueStatus(queueLenght() - i - 1, queueC, Color.black, gradientF, g2d);
			}
			else{
				drawQueueStatus(queueLenght() - i - 1, emptyC, Color.black, gradientF, g2d);
			}
		}
		
		drawProcessorView(view, g2d);
		if ((jobs > queueLenght()) && ((queueLenght() < queueMax)||(queueMax == 0)))
			drawMoreStatus(queueC, emptyC, Color.black, gradientF, g2d);
		drawJobs(g2d);
		if(lostJobs > 0) drawLostJobs(Color.BLACK,Color.WHITE,Color.BLACK,true,g2d);
		txtBounds = drawCenteredText("jobs in the system:" + jobs, queueC, Color.white, panelW/2.0, panelH - ELEM_HEIGHT, g2d, false, false);
		drawCenteredText("jobs in the system:" + jobs, queueC, Color.white, panelW/2.0, panelH - txtBounds.getHeight()/2.0, g2d, false, true);
		drawLegend(
			legendaC,
			legendaS,
			dCst.getFont(),
			dCst.getStartingGap(),
			dCst.getStartingGap(),
			g2d ,true);
	}

	/**
	 * @param view
	 */
	private void drawProcessorView(int view, Graphics2D g2d) {
		drawProcessor(Color.white, Color.black, gradientF, g2d);
		double U = 1.0;
		try {
			U = ql.utilization();
		} catch (NonErgodicException e) {
		}
		legendaS[0] = "current queue";
		legendaC[0] = queueC;
		switch (view) {
			case 1 :
				drawOccupiedPercentage(animC, Color.black, gradientF, g2d);
				legendaS[2] = "busy time";
				legendaC[2] = animC;
				break;
			case 2 :
				drawUtilization(U, busyC, Color.black, gradientF, g2d);
				legendaS[2] = "avg.utilization";
				legendaC[2] = busyC.brighter();
				break;

			default :
				drawUtilization(U, busyC, Color.black, gradientF, g2d);
				legendaS[2] = "avg.utilization";
				legendaC[2] = busyC.brighter();
				break;
		}
	}

	/**
	 * @param i
	 * @param color
	 * @param g2d
	 */
	private void drawQueueStatus(int i, Color startC, Color border, boolean gradientFill, Graphics2D g2d) {
		double x = getElementXY(i).x,
			   y = getElementXY(i).y;
		
		queue[i] = new Rectangle2D.Double(x , y, ELEM_WIDTH, ELEM_HEIGHT);
		if (gradientFill){
			GradientPaint gp = new GradientPaint((float)x, (float)y, startC.brighter(), (float)x, (float)(y + ELEM_HEIGHT), startC.darker(),false);
			g2d.setPaint(gp);
		}
		else{
			g2d.setPaint(startC);
		}
		g2d.fill(queue[i]);
		g2d.setPaint(border);
		g2d.draw(queue[i]);

//		Controllo se questo stato corrisponde alla media dei jobs
		if(i == queueLenght() - queueMedia){
			//disegno un triangolo sopra lo stato che rappresenta la media
			GeneralPath gp = new GeneralPath(GeneralPath.WIND_EVEN_ODD);
			gp.moveTo((float)x, (float)(y - ELEM_HEIGHT/2));
			gp.lineTo((float)(x + ELEM_WIDTH), (float)(y - ELEM_HEIGHT/2));
			gp.lineTo((float)(x + ELEM_WIDTH/2.0), (float)(y - ELEMS_GAP));
			gp.closePath();
			drawCenteredText("Q", queueC, null, x + ELEM_WIDTH/2.0, y - ELEM_HEIGHT * 0.7, g2d, false, true);
			g2d.setColor(queueC);
			g2d.fill(gp);
		}
		
		x += ELEM_WIDTH/2.0;
		y += ELEM_HEIGHT/2.0; 
		drawCenteredText("" + (queueLenght() - i), readColor(startC), null, x, y, g2d, false, true);
	}

	private void drawLostJobs2(Color txtColor, boolean gradientFill, Graphics2D g2d) {
		double x = getProcessorXY().x + PROC_RAD,
			   y = getElementXY(0).y + ELEMS_GAP + ELEM_HEIGHT;
		Color tmp = g2d.getColor();
		int lj;
		if (lostJobs > LOST_JOBS_MAX){
			 lj = (int) LOST_JOBS_MAX;
			 lostJobsStr = ">" + (int)LOST_JOBS_MAX;
		}
		else{
			lj = lostJobs;
			lostJobsStr = "" + (int)lj;
			
		}
		g2d.setColor(txtColor);
		g2d.drawString("lost jobs:" + lostJobsStr, (float) (START_GAP), (float) (panelH));
		g2d.setColor(tmp);
	}
	
	private void drawJobs(Graphics2D g2d) {
		double x = getProcessorXY().x + 2 * PROC_RAD,
			   y = getProcessorXY().y + PROC_RAD * 2 + 4 * ELEMS_GAP;
		Color tmp = g2d.getColor();
		txtBounds = drawCenteredText("executing job:" + donejobs + ", busy time:" + remainingTime, Color.BLACK, Color.WHITE, x,y,g2d, true, false);
		drawCenteredText(
			"executing job:" + donejobs + ", busy time:" + remainingTime + "ms", 
			Color.BLACK, 
			Color.WHITE, 
			x - txtBounds.getWidth()/2.0,
			y,
			g2d, true, true);
		//draw box around text
		g2d.setColor(tmp);
	}
	
	private void drawMoreStatus(Color filledc, Color emptyc, Color border, boolean gradientFill, Graphics2D g2d){
		double x = START_GAP + ELEM_WIDTH * 2 + ELEMS_GAP * 2,
			   y = getElementXY(0).y;
		moreStatiRect = new Rectangle2D.Double(x, y, ELEM_WIDTH * 2.0, ELEM_HEIGHT);
		Area moreStatiA = new Area(moreStatiRect);
		int occ = jobs;
		if ((queueMax > 0) && (jobs > queueMax)) occ = queueMax;
		int mult = 1;
		while(occ > (MORE_JOBS_MAX)){
			 occ = (int) (occ / 10);
			 mult = mult * 10;
		}
		moreStatiA.subtract(
			new Area(
				new Rectangle2D.Double(
					x,
					y,
					ELEM_WIDTH * 2 - ELEM_WIDTH * occ * 2/ MORE_JOBS_MAX,
					ELEM_HEIGHT)));
		if (gradientFill){
			GradientPaint gp;
			gp = new GradientPaint(
				(float)x, 
				(float)y, 
				emptyc.brighter(), 
				(float)x, 
				(float)(y + ELEM_HEIGHT), 
				emptyc.darker(),
				false);
			g2d.setPaint(gp);
			g2d.fill(moreStatiRect);
			gp = new GradientPaint(
				(float)x, 
				(float)y, 
				filledc.brighter(), 
				(float)x, 
				(float)(y + ELEM_HEIGHT), 
				filledc.darker(),
				false);
			g2d.setPaint(gp);
			g2d.fill(moreStatiA);

		}
		else{
			g2d.setPaint(filledc);
			g2d.fill(moreStatiA);
			g2d.setPaint(emptyc);
			g2d.fill(moreStatiRect);
		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -