samer@0: /* samer@0: * Copyright (c) 2000, Samer Abdallah, King's College London. samer@0: * All rights reserved. samer@0: * samer@0: * This software is provided AS iS and WITHOUT ANY WARRANTY; samer@0: * without even the implied warranty of MERCHANTABILITY or samer@0: * FITNESS FOR A PARTICULAR PURPOSE. samer@0: */ samer@0: samer@0: package samer.tools; samer@0: import samer.core.*; samer@0: import samer.core.util.*; samer@0: import samer.core.util.heavy.*; samer@0: import java.awt.*; samer@0: import java.awt.event.*; samer@0: import java.awt.image.*; samer@0: import java.util.*; samer@0: samer@0: /** samer@0: Displays values of a single real variable as a samer@0: trace: value vs time. The trace can be set to scroll samer@0: or wrap when it reaches the right-hand edge. samer@0: samer@0: */ samer@0: samer@0: public class Trace extends VCanvas implements Observer, Agent, Task samer@0: { samer@0: protected int x1, x2, dx, j0=-1; samer@0: protected IMap map; samer@0: samer@0: boolean scroll=false; samer@0: boolean axisFlag; samer@0: Color axisColor; samer@0: VMap vmap; samer@0: samer@0: public Trace() samer@0: { samer@0: dx = Shell.getInt("scrollStep",4); samer@0: scroll = Shell.getBoolean("scroll", false); samer@0: axisColor=Shell.getColor("axesColor",Color.gray); samer@0: axisFlag=Shell.getBoolean("axesFlag",false); samer@0: samer@0: x1=0; x2=0; samer@0: vmap = new VMap(new LinearMap(-1,1)); samer@0: vmap.addObserver(this); samer@0: exposeCommands(this); samer@0: exposeCommands(vmap); samer@0: map = vmap.getMap(); samer@0: } samer@0: samer@0: public IMap getMap() { return vmap.getMap(); } samer@0: samer@0: public void setScroll(boolean f) { scroll=f; } samer@0: public void setStep(int s) { dx=s; } samer@0: public void setAxisColor(Color c) { axisColor=c; } samer@0: public void setAxis(boolean f) { samer@0: j0= -1; axisFlag=f; if (axisFlag) computeAxisPos(); samer@0: } samer@0: samer@0: public void drawAxis(Graphics g) { samer@0: g.setColor(axisColor); samer@0: g.drawLine(0,j0,width-1,j0); samer@0: } samer@0: samer@0: public void paint(Graphics g) { if (j0>=0) drawAxis(g); } samer@0: public void clear(Graphics g) { super.clear(g); paint(g); } samer@0: samer@0: public void dispose() { vmap.dispose(); } samer@0: public void starting() {} samer@0: public void stopping() {} samer@0: /** samer@0: moves the trace along one time step, by preparing samer@0: space for the next bit of plotting. samer@0: */ samer@0: public void run() samer@0: { samer@0: x1=x2; x2+=dx; samer@0: // graphics.setColor(getBackground()); samer@0: samer@0: if (x2>=width) { samer@0: if (scroll) { // scroll just enough samer@0: int st=1+x2-width; samer@0: graphics.copyArea(st,0,width-st,height,-st,0); samer@0: x1-=st; x2-=st; samer@0: } else { // fly back samer@0: // blank out dead space at right samer@0: // and also first column of pixels at left samer@0: graphics.clearRect(x1+1,0,width-x1-1,height); samer@0: graphics.clearRect(0,0,1,height); samer@0: x1=0; x2=dx; samer@0: } samer@0: } samer@0: samer@0: // clear rectangle and draw axis samer@0: graphics.clearRect(x1+1,0,dx,height); samer@0: if (j0>=0) { samer@0: graphics.setColor(axisColor); samer@0: graphics.fillRect(x1,j0,dx+1,1); samer@0: } samer@0: } samer@0: samer@0: samer@0: public void update(Observable o, Object arg) samer@0: { samer@0: if (o==vmap) { samer@0: if (arg==VMap.NEW_MAP) map=vmap.getMap(); samer@0: if (axisFlag) computeAxisPos(); samer@0: clear(getGraphics()); samer@0: } samer@0: } samer@0: samer@0: public Dimension getPreferredSize() { return new Dimension(256,64); } samer@0: protected void sized() { samer@0: map.setIntRange(height); samer@0: if (axisFlag) computeAxisPos(); samer@0: } samer@0: samer@0: public void getCommands(Registry r) { samer@0: r.add("scroll",scroll).add("axis",axisFlag).add("step"); samer@0: } samer@0: public void execute(String cmd, Environment env) throws Exception { samer@0: if (cmd.equals("scroll")) { scroll = X._bool(env.datum(),!scroll); } samer@0: else if (cmd.equals("axis")) { setAxis(X._bool(env.datum(),!axisFlag)); } samer@0: else if (cmd.equals("step")) { dx = X._int(env.datum(),dx); } samer@0: } samer@0: samer@0: private void computeAxisPos() { samer@0: j0 = height-map.toInt(0.0); samer@0: if (map.wasClipped()) j0=-1; samer@0: } samer@0: }