//--------------------------------------------------------------------------------// // COPYRIGHT NOTICE // //--------------------------------------------------------------------------------// // Copyright (c) 2012, Instituto de Microelectronica de Sevilla (IMSE-CNM) // // // // All rights reserved. // // // // Redistribution and use in source and binary forms, with or without // // modification, are permitted provided that the following conditions are met: // // // // * Redistributions of source code must retain the above copyright notice, // // this list of conditions and the following disclaimer. // // // // * Redistributions in binary form must reproduce the above copyright // // notice, this list of conditions and the following disclaimer in the // // documentation and/or other materials provided with the distribution. // // // // * Neither the name of the IMSE-CNM nor the names of its contributors may // // be used to endorse or promote products derived from this software // // without specific prior written permission. // // // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE // // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL // // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR // // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER // // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, // // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // //--------------------------------------------------------------------------------// package xfuzzy.xfsim; import xfuzzy.lang.*; import xfuzzy.util.*; import javax.swing.*; import java.awt.*; import java.awt.event.*; /** * Clase que desarrolla un panel de representaci�n gr�fica de dos * variables de la simulaci�n * * @author Francisco Jos� Moreno Velo * */ public class XfsimPlot extends JPanel implements WindowListener { //----------------------------------------------------------------------------// // COSTANTES PRIVADAS // //----------------------------------------------------------------------------// /** * C�digo asociado a la clase serializable */ private static final long serialVersionUID = 95505666603061L; //----------------------------------------------------------------------------// // MIEMBROS PRIVADOS // //----------------------------------------------------------------------------// /** * Ventana principal de la aplicaci�n */ private Xfsim xfsim; /** * Variable a representar en el eje X */ private int xvar; /** * Vaariable a representar en el eje Y */ private int yvar; /** * Tipo de representaci�n (con puntos, c�rculos, l�neas, etc.) */ private int kind; /** * Nombre de la variable a representar en el eje X */ private String xname; /** * Nombre de la variable a representar en el eje Y */ private String yname; /** * PValores l�mite de las variables */ private double xmin,xmax,ymin,ymax; /** * Marco del panel */ private JDialog frame; /** * Posici�n de los ejes */ private int x0,x1,y0,ym,y1; /** * Componente gr�fico */ private Graphics g; /** * Descripci�n de la fuente */ private FontMetrics fm; /** * Valores de la fuente */ private int ascent, fmheight; /** * Valores hist�ricos */ private double[] xhist, yhist; /** * Valores previos para la representaci�n con l�neas */ private int xprev, yprev; /** * N�mero de reescalados del eje X */ private int xresc; /** * �ndice de los datos a almacenar */ private int index; //----------------------------------------------------------------------------// // CONSTRUCTOR // //----------------------------------------------------------------------------// /** * Constructor */ public XfsimPlot(Xfsim xfsim) { this.xfsim = xfsim; this.xvar = -1; this.yvar = -1; setBackground(XConstants.textbackground); } /** * Constructor * @param xfsim * @param xst * @param yst * @param kind */ public XfsimPlot(Xfsim xfsim, String xst, String yst, int kind) { this.xfsim = xfsim; this.kind = kind; this.xvar = -1; this.yvar = -1; setBackground(XConstants.textbackground); Variable input[] = xfsim.getSpecification().getSystemModule().getInputs(); Variable output[] = xfsim.getSpecification().getSystemModule().getOutputs(); if(xst.equals("_n")) { this.xvar = 0; this.xname = "_n"; this.xmin = 0; this.xmax = 100; } if(xst.equals("_t")) { this.xvar = 1; this.xname = "_t"; this.xmin = 0; this.xmax = 10; } for(int i=0; i<output.length; i++) if(xst.equals(output[i].getName())) { this.xvar = i+2; this.xname = output[i].getName(); this.xmin = output[i].point(0.0); this.xmax = output[i].point(1.0); } for(int i=0; i<input.length; i++) if(xst.equals(input[i].getName())) { this.xvar = i+output.length+2; this.xname = input[i].getName(); this.xmin = input[i].point(0.0); this.xmax = input[i].point(1.0); } for(int i=0; i<output.length; i++) if(yst.equals(output[i].getName())) { this.yvar = i; this.yname = output[i].getName(); this.ymin = output[i].point(0.0); this.ymax = output[i].point(1.0); } for(int i=0; i<input.length; i++) if(yst.equals(input[i].getName())) { this.yvar = i+output.length; this.yname = input[i].getName(); this.ymin = input[i].point(0.0); this.ymax = input[i].point(1.0); } } //----------------------------------------------------------------------------// // M�TODOS P�BLICOS // //----------------------------------------------------------------------------// /** * Devuelve el �ndice de la variable X */ public int getXvar() { return this.xvar; } /** * Devuelve el �ndice de la variable Y */ public int getYvar() { return this.yvar; } /** * Devuelve el tipo de representaci�n */ public int getKind() { return this.kind; } /** * Verifica que la configuraci�n sea correcta */ public boolean isCorrect() { return (xvar >= 0 && yvar >= 0 && kind >= 0 && kind <= 5); } /** * Configura la representaci�n gr�fica */ public void setVar(int xvar, int yvar, int kind) { this.xvar = xvar; this.yvar = yvar; this.kind = kind; Variable input[] = xfsim.getSpecification().getSystemModule().getInputs(); Variable output[] = xfsim.getSpecification().getSystemModule().getOutputs(); if(xvar == 0) { this.xname = "_n"; this.xmin = 0; this.xmax = 100; } else if(xvar == 1) { this.xname = "_t"; this.xmin = 0; this.xmax = 10; } else if(xvar < output.length+2) { this.xname = output[xvar-2].getName(); this.xmin = output[xvar-2].point(0.0); this.xmax = output[xvar-2].point(1.0); } else { this.xname = input[xvar-output.length-2].getName(); this.xmin = input[xvar-output.length-2].point(0.0); this.xmax = input[xvar-output.length-2].point(1.0); } if(yvar < output.length) { this.yname = output[yvar].getName(); this.ymin = output[yvar].point(0.0); this.ymax = output[yvar].point(1.0); } else { this.yname = input[yvar-output.length].getName(); this.ymin = input[yvar-output.length].point(0.0); this.ymax = input[yvar-output.length].point(1.0); } } /** * Genera la ventana con la representaci�n gr�fica */ public void open() { this.xhist = new double[100]; this.yhist = new double[100]; this.index = -1; this.xresc = 0; frame = new JDialog((Frame) null,toString(),false); Container content = frame.getContentPane(); content.add(this); frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); frame.addWindowListener(this); frame.setSize(600,450); frame.setVisible(true); } /** * Dibuja un nuevo punto de la representaci�n */ public void iter(double iter, double time, double[] fzst, double[] ptst) { this.index++; if(index == xhist.length) { double xaux[] = new double[2*xhist.length]; System.arraycopy(xhist,0,xaux,0,xhist.length); this.xhist = xaux; double yaux[] = new double[2*yhist.length]; System.arraycopy(yhist,0,yaux,0,yhist.length); this.yhist = yaux; } if(xvar == 0) xhist[index] = iter; else if(xvar == 1) xhist[index] = time/1000; else if(xvar<fzst.length+2) xhist[index] = fzst[xvar-2]; else xhist[index] = ptst[xvar-2-fzst.length]; if(yvar<fzst.length) yhist[index] = fzst[yvar]; else yhist[index] = ptst[yvar-fzst.length]; Rectangle r = paintStatus(index); if(r != null) repaint(r); } /** * Cierra la ventana de representaci�n gr�fica */ public void close() { if(this.frame != null) this.frame.setVisible(false); } /** * Pinta la gr�fica completa */ public void paint(Graphics g) { super.paint(g); setConstants(g); paintAxis(); paintHist(); } /** * Descripci�n que aparece en la lista de Xfsim */ public String toString() { return "plot("+xname+","+yname+","+kind+")"; } /** * Descripci�n que aparece en los ficheros de configuracion */ public String toCode() { return "xfsim_plot("+xname+","+yname+","+kind+")"; } /** * Interfaz WindowListener. Acci�n al abrir la ventana */ public void windowOpened(WindowEvent e) { } /** * Interfaz WindowListener. Acci�n al cerrar la ventana */ public void windowClosing(WindowEvent e) { if(xfsim.isSimulating()) return; this.frame.setVisible(false); } /** * Interfaz WindowListener. Acci�n al finalizar el cierre */ public void windowClosed(WindowEvent e) { } /** * Interfaz WindowListener. Acci�n al minimizar la ventana */ public void windowIconified(WindowEvent e) { } /** * Interfaz WindowListener. Acci�n al maximizar la ventana */ public void windowDeiconified(WindowEvent e) { } /** * Interfaz WindowListener. Acci�n al activar la ventana */ public void windowActivated(WindowEvent e) { } /** * Interfaz WindowListener. Acci�n al desactivar la ventana */ public void windowDeactivated(WindowEvent e) { } //----------------------------------------------------------------------------// // M�TODOS PRIVADOS // //----------------------------------------------------------------------------// /** * Inicializa algunas constantes internas */ private void setConstants(Graphics g) { this.g = g; this.fm = getFontMetrics(getFont()); this.ascent = fm.getAscent(); this.fmheight = fm.getHeight(); Dimension size = getSize(); this.x0 = 100; this.x1 = size.width - 100; this.y0 = size.height - 50; this.y1 = 30; this.ym = (y0+y1)/2; } /** * Pinta los ejes de la representaci�n */ private void paintAxis() { g.drawRect(x0,y1,x1-x0,y0-y1); g.drawLine(x0,y1,x0-5,y1); g.drawLine(x0,ym,x0-5,ym); g.drawLine(x0,y0,x0-5,y0); g.drawLine(x1,y1,x1+5,y1); g.drawLine(x1,ym,x1+5,ym); g.drawLine(x1,y0,x1+5,y0); int xdiv = (xvar>1? 2 : 5); for(int i=0; i<=xdiv; i++) { int lpos = x0+(x1-x0)*i/xdiv; g.drawLine(lpos,y0,lpos,y0+5); } String xtitle = xname+(xvar == 1? " (s)": ""); int yposx = (x0-fm.stringWidth(xtitle))/2; int yposy = (y1-fmheight)/2+ascent; int xposx = x1+(getSize().width-x1-fm.stringWidth(yname))/2; int xposy = y0+(getSize().height-y0)/2+ascent; String stymin = ""+ymin; String stymax = ""+ymax; String stymean = ""+((ymax+ymin)/2); g.drawString(xtitle,xposx,xposy); g.drawString(yname,yposx,yposy); g.drawString(stymax,x0-10-fm.stringWidth(stymax),y1+ascent/2); g.drawString(stymean,x0-10-fm.stringWidth(stymean),ym+ascent/2); g.drawString(stymin,x0-10-fm.stringWidth(stymin),y0+ascent/2); g.drawString(stymax,x1+10,y1+ascent/2); g.drawString(stymean,x1+10,ym+ascent/2); g.drawString(stymin,x1+10,y0+ascent/2); for(int i=0; i<=xdiv; i++) { String stval = ""+(xmin+(xmax-xmin)*i/xdiv); int stpos = x0+(x1-x0)*i/xdiv-fm.stringWidth(stval)/2; g.drawString(stval,stpos,y0+10+ascent); } } /** * Pinta un punto de la representaci�n */ private Rectangle paintStatus(int index) { double xvalue = xhist[index]; double yvalue = yhist[index]; if(xvalue > xmax && xvar <= 1) { xresc++; xmax = (xvar ==0? 100 : 10); for(int i=0; i<xresc ; i++) if(i%3 != 0) xmax*=2; else xmax=xmax*5/2; repaint(); return null; } int xpos = x0 + (int) ((x1-x0)*(xvalue-xmin)/(xmax-xmin)); int ypos = y0 + (int) ((y1-y0)*(yvalue-ymin)/(ymax-ymin)); switch(kind) { case 0: if(index != 0) g.drawLine(xprev,yprev,xpos,ypos); Rectangle r = new Rectangle(xprev,yprev,xpos-xprev,ypos-yprev); xprev = xpos; yprev = ypos; return r; case 1: g.fillOval(xpos-2,ypos-2,4,4); return new Rectangle(xpos-2,ypos-2,4,4); case 2: g.drawRect(xpos-3,ypos-3,6,6); return new Rectangle(xpos-3,ypos-3,6,6); case 3: g.drawOval(xpos-3,ypos-3,6,6); return new Rectangle(xpos-3,ypos-3,6,6); case 4: g.drawOval(xpos-5,ypos-5,10,10); return new Rectangle(xpos-5,ypos-5,10,10); case 5: g.drawOval(xpos-10,ypos-10,20,20); return new Rectangle(xpos-10,ypos-10,20,20); default: return null; } } /** * Pinta todos los puntos de la representaci�n */ private void paintHist() { for(int i=0; i<index; i++) paintStatus(i); } }