GridObserver.java 8.13 KiB
package pikelake;
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Rectangle2D;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import fr.cemagref.observation.gui.Configurable;
import fr.cemagref.observation.gui.Drawable;
import fr.cemagref.observation.kernel.ObservablesHandler;
import fr.cemagref.observation.kernel.ObserverListener;
import fr.cemagref.ohoui.annotations.Description;
import fr.cemagref.ohoui.annotations.NoRecursive;
import fr.cemagref.ohoui.filters.NoTransientField;
import fr.cemagref.ohoui.swing.OhOUI;
import fr.cemagref.ohoui.swing.OhOUIDialog;
import fr.cemagref.simaqualife.kernel.util.TransientParameters;
import fr.cemagref.simaqualife.pilot.Pilot;
@SuppressWarnings("serial")
@NoRecursive
public class GridObserver extends ObserverListener implements Configurable, Drawable, MouseMotionListener {
    private transient JComponent display;
    private transient JLabel label;
    private transient Grid grid;
    private String title;
    private Color envColor = Color.GREEN;
    private Color preyColor = Color.BLUE;
    private Color pikeColor = Color.RED;
    @Description (name="Background color",tooltip="Background color")
    private Color bgColor = Color.WHITE;
    private transient int displayWidthBak,displayHeightBak;
    private transient double cellSizeX, cellSizeY;
    private transient int[] cellsAlpha;
    public String getTitle() {
        return title;
    public JComponent getDisplay() {
        return display;
    public void valueChanged(ObservablesHandler clObservable, Object instance, long t) {
        display.repaint();
    @TransientParameters.InitTransientParameters
    public void init(Pilot pilot) {
    	// init display component
        display = new JPanel(new BorderLayout());
        DisplayComponent displayComponent = new DisplayComponent();
        displayComponent.addMouseMotionListener(this);
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
displayComponent.setVisible(true); displayComponent.setDoubleBuffered(true); label = new JLabel(""); display.add(displayComponent,BorderLayout.CENTER); display.add(label,BorderLayout.PAGE_START); grid = (Grid)pilot.getAquaticWorld().getEnvironment(); // init display variables displayWidthBak = 0; displayHeightBak = 0; // compute HabitatQuality colors double cellsHabitatQualityMin = 0; double cellsHabitatQualityMax = 0; cellsAlpha = new int[grid.getCells().length]; if (grid.getCells().length > 0) { cellsHabitatQualityMin = grid.getCells()[0].getHabitatQuality(); cellsHabitatQualityMax = grid.getCells()[0].getHabitatQuality(); for (int i = 1; i < grid.getCells().length; i++) { if (grid.getCells()[i].getHabitatQuality() < cellsHabitatQualityMin) cellsHabitatQualityMin = grid.getCells()[i].getHabitatQuality(); else if (grid.getCells()[i].getHabitatQuality() > cellsHabitatQualityMax) cellsHabitatQualityMax = grid.getCells()[i].getHabitatQuality(); } } if (Double.compare(cellsHabitatQualityMax,cellsHabitatQualityMin) == 0) { for (int i = 0; i < grid.getCells().length; i++) { cellsAlpha[i] = 255; } } else { for (int i = 0; i < grid.getCells().length; i++) { cellsAlpha[i] = (int)(155 + 100*(grid.getCells()[i].getHabitatQuality() - cellsHabitatQualityMin)/(cellsHabitatQualityMax - cellsHabitatQualityMin)); } } // show the result display.repaint(); } public void disable() { display.setVisible(false); } public static interface AsShapeConvertible { public Shape getShape(); } public void configure() { OhOUIDialog dialog = OhOUI.getDialog(null,this,new NoTransientField()); dialog.setSize(new Dimension(500, 600)); dialog.setVisible(true); display.repaint(); } @Override public void addObservable(ObservablesHandler classObservable) { // nothing to do } @Override public void init() { // nothing to do } @Override public void close() { // nothing to do } private class DisplayComponent extends JComponent { @Override
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
protected synchronized void paintComponent(Graphics g) { super.paintComponents(g); Graphics2D g2d = (Graphics2D)g; // determine if generalPath must be rescaled if ( (this.getWidth() != displayWidthBak) || (this.getHeight() != displayHeightBak) ) { // backup for comparaison in the next loop displayWidthBak = this.getWidth(); displayHeightBak = this.getHeight(); cellSizeX = displayWidthBak/grid.getGridWidth(); cellSizeY = displayHeightBak/grid.getGridHeight(); } // Draw Background g.setColor(bgColor); g2d.setStroke(new BasicStroke(3)); g.fillRect(0, 0, getWidth(), getHeight()); Rectangle2D.Double cellRect = null; Rectangle2D.Double pikeRect = null; double preyDiameterX, preyDiameterY, pikeWidth, pikeHeight; // draw each cell for (int i = 0; i < grid.getCells().length; i++) { // the bounds of a cell cellRect = new Rectangle2D.Double((int)cellSizeX*(i%grid.getGridWidth()), (int)cellSizeY*(i/grid.getGridHeight()), (int)cellSizeX, (int)cellSizeY); // filling the cell with a color corresponding to the habitat level g.setColor(new Color(envColor.getRed(),envColor.getGreen(),envColor.getBlue(),cellsAlpha[i])); g2d.fill(cellRect); // drawing preys if (grid.getCells()[i].getPreys().size() > 0) { g.setColor(preyColor); preyDiameterX = cellRect.width*(double)grid.getCells()[i].getPreys().size()/grid.getCells()[i].getPreyCarryingCapacity(); preyDiameterY = cellRect.height*(double)grid.getCells()[i].getPreys().size()/grid.getCells()[i].getPreyCarryingCapacity(); g.fillOval((int)(cellRect.x + (cellRect.width - preyDiameterX)/2), (int)(cellRect.y + (cellRect.height - preyDiameterY)/2), (int)preyDiameterX, (int)preyDiameterY); // represention as pie ... not very pretty /*g2d.fill(new Arc2D.Double(cellRect,90,-360*((double)grid.getCells()[i].getPreys().size()/grid.getCells()[i].getPreyCarryingCapacity()),Arc2D.PIE)); g2d.draw(new Arc2D.Double(cellRect,90,360,Arc2D.OPEN));*/ } // drawing pikes presence if (grid.getCells()[i].getPikes().size() > 0) { g.setColor(pikeColor); pikeWidth = cellRect.width / 3; pikeHeight = cellRect.height / 3; pikeRect = new Rectangle2D.Double(cellRect.x + (cellRect.width - pikeWidth)/2, cellRect.y + (cellRect.height - pikeHeight)/2, pikeWidth, pikeHeight); g2d.draw(pikeRect); g2d.drawString(""+grid.getCells()[i].getPikes().size(), (float)(cellRect.x + cellRect.width/2 - 5), (float)pikeRect.y+(float)pikeRect.height-1); } } } } public void mouseDragged(MouseEvent e) {} public void mouseMoved(MouseEvent e) { int y = (int)(e.getY()/cellSizeY); int x = (int)(e.getX()/cellSizeX); Cell cell = grid.getCells()[grid.getGridWidth()*Math.min(y,grid.getGridHeight()-1) + Math.min(x,grid.getGridWidth()-1)]; label.setText("( "+x+" , "+y+" ) : habitat value = "+cell.getHabitatQuality()+" / "+cell.getPreys().size() + " preys ( max = "+cell.getPreyCarryingCapacity()+") and " + cell.getPikes().size()+ " pikes."); } public static void main (String [] args){ System.out.println((new XStream(new DomDriver())).toXML(new GridObserver())); } }