package mygraphs; import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.util.*; import main.Model; import main.Cell; import main.Node; import main.Globals; import genegui.Pointer; import iterators.MultiFloatReturn; /** This is no longer a general line graph class, its specific to Ingeneue. */ public class LineGraphPanel extends JPanel implements ActionListener { Vector colors = new Vector(); Vector dataVectors = new Vector(); float [] ySlopes = new float[10]; int leftPixel = 0; float timePerPixel = 1f; float [] times = new float[100]; boolean offScrUpToDate = false; Image offScrImage = null; private ActionListener actionListener = null; public LineGraphPanel() { for(int i = 0; i < ySlopes.length; i++) ySlopes[i] = 100f; } public void reset() { leftPixel = 0; } public void addItem(Cell cell, Node node, Model model, Color col) { NodeValueStorage nvs = new NodeValueStorage(cell, node, model); addActionListener(nvs); dataVectors.addElement(nvs); colors.addElement(col); } public void plotNewPoint(float time) { // If there is nothing in the graph, do nothing if(dataVectors.size() == 0) return; if(!offScrUpToDate) { paintOffScreen(); paintImmediately(getBounds()); return; } Graphics og = offScrImage.getGraphics(); Rectangle area = getBounds(); Enumeration data_elem = dataVectors.elements(); Enumeration col_elem = colors.elements(); MultiFloatReturn mfr1 = new MultiFloatReturn(), mfr2 = new MultiFloatReturn(); ((NodeValueStorage)dataVectors.elementAt(0)).getValue(mfr1, NodeValueStorage.FROM_END, -1); ((NodeValueStorage)dataVectors.elementAt(0)).getValue(mfr2, NodeValueStorage.FROM_END, 0); int x1 = Math.round(mfr1.f1 / timePerPixel) - leftPixel; int x2 = Math.round(mfr2.f1 / timePerPixel) - leftPixel; if(x2 >= area.width) { int diff = area.width - x2 - 1; og.drawImage(offScrImage, diff, 0, this); og.setColor(Color.white); og.fillRect(area.width + diff, 0, area.width - 1, area.height); og.setColor(Color.black); leftPixel -= diff; x1 += diff; x2 += diff; } int index = 0; while(data_elem.hasMoreElements()) { NodeValueStorage nvs = ((NodeValueStorage)data_elem.nextElement()); nvs.getValue(mfr1, NodeValueStorage.FROM_END, -1); nvs.getValue(mfr2, NodeValueStorage.FROM_END, 0); og.setColor((Color)col_elem.nextElement()); int y1 = Math.round(mfr1.f2 * ySlopes[index]); y1 = area.height - y1; int y2 = Math.round(mfr2.f2 * ySlopes[index]); y2 = area.height - y2; og.drawLine(x1, y1, x2, y2); index++; } og.dispose(); paintImmediately(area); } private void plotGraph(Graphics g) { if(dataVectors.size() == 0) return; Rectangle area = getBounds(); NodeValueStorage [] data_stores = new NodeValueStorage[dataVectors.size()]; float t = leftPixel * timePerPixel; for(int i = 0; i < data_stores.length; i++) { data_stores[i] = (NodeValueStorage)dataVectors.elementAt(i); data_stores[i].resetScanner(t); } float end_t = (leftPixel + area.width) * timePerPixel; MultiFloatReturn mfr = new MultiFloatReturn(); int x, next_x, y, next_y; for(int item = 0; item < data_stores.length; item++) { if(data_stores[item].hasMorePoints(end_t)) { data_stores[item].getNextPoint(mfr); x = Math.round(mfr.f1 / timePerPixel) - leftPixel; y = Math.round(mfr.f2 * ySlopes[item]); y = area.height - y; while(data_stores[item].hasMorePoints(end_t)) { data_stores[item].getNextPoint(mfr); next_x = Math.round(mfr.f1 / timePerPixel) - leftPixel; next_y = Math.round(mfr.f2 * ySlopes[item]); next_y = area.height - y; // Draw the line segment g.drawLine(x, y, next_x, next_y); x = next_x; y = next_y; } } } } public void update (Graphics g) { paint(g); } public void paint (Graphics g) { paintOffScreen(); g.drawImage( offScrImage, 0,0, this ); } private void paintOffScreen() { Rectangle area = getBounds(); if(offScrImage == null || offScrImage.getWidth(this) != area.width || offScrImage.getHeight(this) != area.height) { offScrImage = createImage(area.width, area.height); offScrUpToDate = false; } if(offScrUpToDate) return; Graphics og = offScrImage.getGraphics(); og.setColor(Color.white); og.fillRect(0, 0, area.width, area.height); plotGraph(og); og.dispose(); offScrUpToDate = true; } public void setTimePerPixel(float timeperpixel) { float t = leftPixel * timePerPixel; timePerPixel = timeperpixel; leftPixel = Math.round(t / timePerPixel); getParent().repaint(); } public void actionPerformed(ActionEvent event) { // if((event.getActionCommand()).equals(Model.UPDATE_CELLS)) { // sendEvent("UpdateCells"); // // plotNewPoint(Globals.time); // } // else if((event.getActionCommand()).equals(Model.NEW_RUN)) { // reset(); // } // else if((event.getActionCommand()).equals("SetModel")) { // ((Model)(((Pointer)event.getSource()).object)).addActionListener(this); // } // else if((event.getActionCommand()).equals("SetNetwork")) { // // Reset graph somehow // } } // Stock code for sending out action events public void addActionListener(ActionListener l) { actionListener = AWTEventMulticaster.add(actionListener, l); } public void removeActionListener(ActionListener l) { actionListener = AWTEventMulticaster.remove(actionListener, l); } public void sendEvent(String type) { if(actionListener != null) { actionListener.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, type)); } } }