Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
jadex.micro.examples.mandelbrot.DisplayPanel Maven / Gradle / Ivy
Go to download
The Jadex micro applications package contains several example applications, benchmarks and testcases using micro agents.
package jadex.micro.examples.mandelbrot;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import java.awt.geom.Rectangle2D;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.UUID;
import javax.swing.JComponent;
import javax.swing.JProgressBar;
import javax.swing.JViewport;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import jadex.bridge.IComponentStep;
import jadex.bridge.IExternalAccess;
import jadex.bridge.IInternalAccess;
import jadex.bridge.service.RequiredServiceInfo;
import jadex.bridge.service.component.IRequiredServicesFeature;
import jadex.bridge.service.search.SServiceProvider;
import jadex.bridge.service.types.cms.IComponentManagementService;
import jadex.commons.future.IFuture;
import jadex.commons.future.IIntermediateResultListener;
import jadex.commons.future.IResultListener;
import jadex.commons.future.ISubscriptionIntermediateFuture;
import jadex.commons.gui.future.SwingDefaultResultListener;
import jadex.commons.gui.future.SwingResultListener;
/**
* Panel for displaying calculated results.
*/
public class DisplayPanel extends JComponent
{
//-------- constants --------
/** The help text. */
public static final String HELPTEXT =
"Use mouse to navigate:\n" +
"[wheel] zoom in/out\n" +
"[left button] choose and click into area\n" +
"[rigth button] drag to move, click for original area.\n";
//-------- attributes --------
/** The service provider. */
protected IExternalAccess agent;
/** The mandelbrot service. */
protected IMandelbrotService manservice;
/** The colors for drawing. */
protected Color[] colors;
/** The latest area data used for determining original coordinates of painted regions. */
protected AreaData data;
/** The current image derived from the results. */
protected Image image;
/** The current selection start point (if any). */
protected Point point;
/** The current selection range (if any). */
protected Rectangle range;
/** Flag indicating that a calculation is in progress. */
protected boolean calculating;
/** Progress data objects, available only when calculating (progress data -> percent finished). */
protected Map progressdata;
/** Progress update timer. */
protected Timer progressupdate;
/** Start point for dragging (if any). */
protected Point startdrag;
/** End point for dragging (if any). */
protected Point enddrag;
/** The display id. */
protected String displayid;
//-------- constructors --------
/**
* Create a new display panel.
*/
public DisplayPanel(final IExternalAccess agent, IMandelbrotService manservice)
{
this.agent = agent;
this.manservice = manservice;
this.displayid = ""+UUID.randomUUID();
manservice.getDisplayService().addResultListener(new SwingDefaultResultListener()
{
public void customResultAvailable(IDisplayService result)
{
ISubscriptionIntermediateFuture sub = result.subscribeToDisplayUpdates(displayid);
sub.addResultListener(new IIntermediateResultListener()
{
public void resultAvailable(Collection result)
{
}
public void intermediateResultAvailable(Object result)
{
// System.out.println("rec: "+result.getClass());
if(result instanceof AreaData)
{
setResults((AreaData)result);
}
else if(result instanceof ProgressData)
{
addProgress((ProgressData)result);
}
}
public void finished()
{
// todo: close
}
public void exceptionOccurred(Exception exception)
{
exception.printStackTrace();
}
});
setColorScheme(new Color[]{new Color(50, 100, 0), Color.red}, true);
calcDefaultImage();
// Dragging with right mouse button.
MouseAdapter draghandler = new MouseAdapter()
{
public void mousePressed(MouseEvent e)
{
if(!calculating && e.getButton()==MouseEvent.BUTTON3 && e.getClickCount()==1 && image!=null)
{
startdrag = new Point(e.getX(), e.getY());
range = null;
point = null;
}
else
{
startdrag = null;
}
}
public void mouseDragged(MouseEvent e)
{
if(startdrag!=null)
{
enddrag = new Point(e.getX(), e.getY());
repaint();
}
}
public void mouseReleased(MouseEvent e)
{
if(startdrag!=null && enddrag!=null)
{
// System.out.println("dragged: "+startdrag+" "+enddrag);
dragImage();
}
}
};
addMouseMotionListener(draghandler);
addMouseListener(draghandler);
// Zooming with mouse wheel.
addMouseWheelListener(new MouseAdapter()
{
public void mouseWheelMoved(MouseWheelEvent e)
{
if(!calculating)
{
int sa = e.getScrollAmount();
double dir = Math.signum(e.getWheelRotation());
double percent = 10*sa;
double factor;
if(dir>0)
{
factor = (100+percent)/100;
}
else
{
factor = 100/(100+percent);
}
zoomImage(e.getX(), e.getY(), factor);
}
}
});
// Selecting range and default area.
addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
if(SwingUtilities.isRightMouseButton(e))
{
calcDefaultImage();
}
else if(!calculating && range!=null)
{
if(e.getX()>=range.x && e.getX()<=range.x+range.width
&& e.getY()>=range.y && e.getY()<=range.y+range.height)
{
zoomIntoRange();
}
}
}
public void mousePressed(MouseEvent e)
{
if(!calculating)
{
if(SwingUtilities.isRightMouseButton(e))
{
DisplayPanel.this.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
}
else
{
point = e.getPoint();
DisplayPanel.this.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
}
}
}
public void mouseReleased(MouseEvent e)
{
if(!calculating)
{
DisplayPanel.this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
}
});
addMouseMotionListener(new MouseAdapter()
{
public void mouseMoved(MouseEvent e)
{
if(!calculating && range!=null)
{
if(e.getX()>=range.x && e.getX()<=range.x+range.width
&& e.getY()>=range.y && e.getY()<=range.y+range.height)
{
DisplayPanel.this.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
}
else
{
DisplayPanel.this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
}
}
public void mouseDragged(MouseEvent e)
{
if(!calculating && point!=null)
{
range = new Rectangle(
point.x()
{
public IFuture execute(IInternalAccess ia)
{
// do not depend on hosting component!
// IFuture fut = ia.getServiceContainer().getRequiredService("cmsservice");
IFuture fut = SServiceProvider.getService(ia, IComponentManagementService.class, RequiredServiceInfo.SCOPE_PLATFORM);
fut.addResultListener(new SwingResultListener(new IResultListener()
{
public void resultAvailable(IComponentManagementService cms)
{
if(progressdata!=null)
{
Object[] pds = progressdata.keySet().toArray();
for(int i=0; i(new IResultListener()
{
public void resultAvailable(IExternalAccess ea)
{
// It is not really possible to define the progress services as required service.
// Needs component specific progress service.
SServiceProvider.getService(ea, IProgressService.class)
.addResultListener(new SwingResultListener(new IResultListener()
{
public void resultAvailable(IProgressService ps)
{
if(ps!=null)
{
ps.getProgress(progress.getTaskId())
.addResultListener(new SwingResultListener(new IResultListener()
{
public void resultAvailable(Integer current)
{
if(progressdata!=null && progressdata.containsKey(progress))
{
Integer percent = (Integer)progressdata.get(progress);
if(current.intValue()>percent.intValue())
{
progressdata.put(progress, current);
repaint();
}
}
}
public void exceptionOccurred(Exception exception)
{
// Component removed.
if(progressdata!=null)
{
progressdata.remove(progress);
}
else if(progressupdate!=null)
{
progressupdate.stop();
progressupdate = null;
}
}
}));
}
}
public void exceptionOccurred(Exception exception)
{
// Component removed.
if(progressdata!=null)
{
progressdata.remove(progress);
}
else if(progressupdate!=null)
{
progressupdate.stop();
progressupdate = null;
}
}
}));
}
public void exceptionOccurred(Exception exception)
{
// Component removed.
if(progressdata!=null)
{
progressdata.remove(progress);
}
else if(progressupdate!=null)
{
progressupdate.stop();
progressupdate = null;
}
}
}));
}
}
}
}
public void exceptionOccurred(Exception exception)
{
// ignore
exception.printStackTrace();
}
}));
return IFuture.DONE;
}
});
}
else if(progressupdate!=null)
{
progressupdate.stop();
progressupdate = null;
}
}
});
progressupdate.start();
}
}
});
}
//-------- JPanel methods --------
/**
* Paint the results.
*/
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
// Draw image.
if(image!=null)
{
Rectangle bounds = getInnerBounds(true);
int ix = 0;
int iy = 0;
int iwidth = image.getWidth(this);
int iheight = image.getHeight(this);
Rectangle drawarea = scaleToFit(bounds, iwidth, iheight);
// Zoom into original image while calculating
if(calculating && range!=null)
{
ix = (range.x-drawarea.x-bounds.x)*iwidth/drawarea.width;
iy = (range.y-drawarea.y-bounds.y)*iheight/drawarea.height;
iwidth = range.width*iwidth/drawarea.width;
iheight = range.height*iheight/drawarea.height;
// Scale again to fit new image size.
drawarea = scaleToFit(bounds, iwidth, iheight);
g.drawImage(image, bounds.x+drawarea.x, bounds.y+drawarea.y,
bounds.x+drawarea.x+drawarea.width, bounds.y+drawarea.y+drawarea.height,
ix, iy, ix+iwidth, iy+iheight, this);
}
// Offset and clip image and show border while dragging.
else if(startdrag!=null && enddrag!=null)
{
// Draw original image in background
g.drawImage(image, bounds.x+drawarea.x, bounds.y+drawarea.y,
bounds.x+drawarea.x+drawarea.width, bounds.y+drawarea.y+drawarea.height,
ix, iy, ix+iwidth, iy+iheight, this);
g.setColor(new Color(32,32,32,160));
g.fillRect(bounds.x+drawarea.x, bounds.y+drawarea.y, drawarea.width, drawarea.height);
// Draw offsetted image in foreground
Shape clip = g.getClip();
g.setClip(bounds.x+drawarea.x, bounds.y+drawarea.y, drawarea.width, drawarea.height);
int xoff = enddrag.x-startdrag.x;
int yoff = enddrag.y-startdrag.y;
g.drawImage(image, bounds.x+drawarea.x+xoff, bounds.y+drawarea.y+yoff,
bounds.x+drawarea.x+xoff+drawarea.width, bounds.y+drawarea.y+yoff+drawarea.height,
ix, iy, ix+iwidth, iy+iheight, this);
g.setClip(clip);
}
else
{
g.drawImage(image, bounds.x+drawarea.x, bounds.y+drawarea.y,
bounds.x+drawarea.x+drawarea.width, bounds.y+drawarea.y+drawarea.height,
ix, iy, ix+iwidth, iy+iheight, this);
}
// Draw progress boxes.
if(progressdata!=null)
{
JProgressBar bar = new JProgressBar(0, 100);
bar.setStringPainted(true);
Dimension barsize = bar.getPreferredSize();
for(Iterator it=progressdata.keySet().iterator(); it.hasNext(); )
{
ProgressData progress = (ProgressData)it.next();
double xf = drawarea.getWidth()/progress.getImageWidth();
double yf = drawarea.getHeight()/progress.getImageHeight();
int corx = (int)(progress.getArea().x*xf);
int cory = (int)(progress.getArea().y*yf);
int corw = (int)(progress.getArea().width*xf);
int corh = (int)(progress.getArea().height*yf);
if(!progress.isFinished())
{
g.setColor(new Color(32,32,32,160));
g.fillRect(bounds.x+drawarea.x+corx+1, bounds.y+drawarea.y+cory+1, corw-1, corh-1);
}
g.setColor(Color.white);
g.drawRect(bounds.x+drawarea.x+corx, bounds.y+drawarea.y+cory, corw, corh);
// Print provider name.
if(progress.getProviderId()!=null)
{
String name = progress.getProviderId().toString();
String provider = "";
int index = name.indexOf('@');
if(index!=-1)
{
provider = name.substring(index+1);
name = name.substring(0, index);
}
// provider = progress.getTaskId().toString();
FontMetrics fm = g.getFontMetrics();
Rectangle2D sb1 = fm.getStringBounds(name, g);
Rectangle2D sb2 = fm.getStringBounds(provider, g);
int width = (int)Math.max(sb1.getWidth(), sb2.getWidth());
int height = fm.getHeight()*2 + barsize.height + 2;
if(width8 && corh>8)
{
bar.setStringPainted(false);
int x = bounds.x+drawarea.x+corx + 2;
int y = bounds.y+drawarea.y+cory + Math.max((corh-barsize.height)/2, 2);
bar.setValue(((Number)progressdata.get(progress)).intValue());
bar.setBounds(0, 0, corw-4, Math.min(barsize.height, corh-4));
Graphics g2 = g.create();
g2.translate(x, y);
bar.paint(g2);
}
}
}
}
}
// Draw range area.
if(!calculating && range!=null)
{
Rectangle bounds = getInnerBounds(false);
double rratio = (double)range.width/range.height;
double bratio = (double)bounds.width/bounds.height;
// Draw left and right boxes to show unused space
if(rratiobratio)
{
int drawheight = range.width*bounds.height/bounds.width;
int offset = (range.height-drawheight)/2;
g.setColor(new Color(128,128,128,64));
g.fillRect(range.x, range.y+offset, range.width+1, -offset);
g.fillRect(range.x, range.y+range.height, range.width+1, -offset);
}
g.setColor(Color.white);
g.drawRect(range.x, range.y, range.width, range.height);
}
}
/**
* Calculate draw area for image.
*/
protected Rectangle scaleToFit(Rectangle bounds, int iwidth, int iheight)
{
double iratio = (double)iwidth/iheight;
double bratio = (double)bounds.width/bounds.height;
Rectangle drawarea = new Rectangle(0, 0, bounds.width, bounds.height);
// Scale to fit height
if(iratiobratio)
{
double wratio = (double)bounds.width/iwidth;
drawarea.height = (int)(iheight*wratio);
drawarea.y = (bounds.height-drawarea.height)/2;
}
return drawarea;
}
/**
* Get the bounds with respect to insets (if any).
* @param scrollarea True when inner bounds of scroll area instead of visible window space should be considered.
*/
protected Rectangle getInnerBounds(boolean scrollarea)
{
Rectangle bounds = getBounds();
if(!scrollarea && getParent() instanceof JViewport)
{
// Get bounds of outer scroll panel
Rectangle pbounds = getParent().getParent().getBounds();
if(bounds.width>pbounds.width || bounds.height>pbounds.height)
{
bounds = pbounds;
}
}
Insets insets = getInsets();
if(insets!=null)
{
bounds.x = insets.left;
bounds.y = insets.top;
bounds.width -= insets.left + insets.right;
bounds.height -= insets.top + insets.bottom;
}
else
{
bounds.x = 0;
bounds.y = 0;
}
return bounds;
}
/**
* Get the desired size of the panel.
*/
public Dimension getMinimumSize()
{
Insets ins = getInsets();
Dimension ret = new Dimension(ins!=null ? ins.left+ins.right : 0, ins!=null ? ins.top+ins.bottom : 0);
if(image!=null)
{
ret.width += image.getWidth(this);
ret.height += image.getHeight(this);
}
return ret;
}
/**
* Get the desired size of the panel.
*/
public Dimension getPreferredSize()
{
return getMinimumSize();
}
/**
* Set the color scheme.
*/
public void setColorScheme(Color[] scheme, boolean cycle)
{
if(scheme==null || scheme.length==0)
{
colors = new Color[]{Color.white};
}
else if(scheme.length==1)
{
colors = scheme;
}
else if(cycle)
{
colors = new Color[scheme.length*16];
for(int i=0; ibratio)
{
int height = (int)(bounds.width/rratio);
bounds.height = height;
}
// Clear image for painting only background.
DisplayPanel.this.image = createImage(bounds.width, bounds.height);
calcArea(settings.getXStart(), settings.getXEnd(), settings.getYStart(), settings.getYEnd(), bounds.width, bounds.height);
}
/**
* Zoom into the selected range.
*/
protected void zoomIntoRange()
{
// Calculate bounds relative to original image.
Rectangle bounds = getInnerBounds(true);
Rectangle drawarea = scaleToFit(bounds, image.getWidth(DisplayPanel.this), image.getHeight(DisplayPanel.this));
final double x = (double)(range.x-bounds.x-drawarea.x)/drawarea.width;
final double y = (double)(range.y-bounds.y-drawarea.y)/drawarea.height;
final double x2 = x + (double)range.width/drawarea.width;
final double y2 = y + (double)range.height/drawarea.height;
// Original bounds
final double ox = data.getXStart();
final double oy = data.getYStart();
final double owidth = data.getXEnd()-data.getXStart();
final double oheight = data.getYEnd()-data.getYStart();
// Calculate pixel width/height of visible area.
bounds = getInnerBounds(false);
double rratio = (double)range.width/range.height;
double bratio = (double)bounds.width/bounds.height;
if(rratiobratio)
{
bounds.height = (int)(bounds.width/rratio);
}
final Rectangle area = bounds;
calcArea(ox+owidth*x, ox+owidth*x2, oy+oheight*y, oy+oheight*y2, area.width, area.height);
}
/**
* Calculate the given area.
*/
protected void calcArea(double x1, double x2, double y1, double y2, int sizex, int sizey)
{
AreaData settings;
if(data==null)
settings = GenerateService.ALGORITHMS[0].getDefaultSettings();
else
settings = data;
final AreaData ad = new AreaData(x1, x2, y1, y2, sizex, sizey,
settings.getMax(), settings.getParallel(), settings.getTaskSize(), settings.getAlgorithm(), displayid);
DisplayPanel.this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
calculating = true;
repaint();
if(manservice!=null)
{
manservice.getGenerateService()
.addResultListener(new SwingResultListener(new IResultListener()
{
public void resultAvailable(IGenerateService gs)
{
gs.generateArea(ad).addResultListener(new SwingDefaultResultListener()
{
public void customResultAvailable(AreaData result)
{
DisplayPanel.this.setResults(result);
}
public void customExceptionOccurred(Exception exception)
{
calculating = false;
DisplayPanel.this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
super.customExceptionOccurred(exception);
}
});
}
public void exceptionOccurred(Exception exception)
{
// Service not found -> ignore
calculating = false;
DisplayPanel.this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
}));
}
else
{
agent.scheduleStep(new IComponentStep()
{
public IFuture execute(IInternalAccess ia)
{
ia.getComponentFeature(IRequiredServicesFeature.class).getRequiredService("generateservice")
.addResultListener(new SwingResultListener(new IResultListener()
{
public void resultAvailable(Object result)
{
IGenerateService gs = (IGenerateService)result;
gs.generateArea(ad).addResultListener(new SwingDefaultResultListener()
{
public void customResultAvailable(AreaData result)
{
DisplayPanel.this.setResults(result);
}
public void customExceptionOccurred(Exception exception)
{
calculating = false;
DisplayPanel.this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
super.customExceptionOccurred(exception);
}
});
}
public void exceptionOccurred(Exception exception)
{
// Service not found -> ignore
calculating = false;
DisplayPanel.this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
}));
return IFuture.DONE;
}
});
}
}
}