/* * This file is part of the OSMembrane project. * More informations under www.osmembrane.de * * The project is licensed under the GNU GENERAL PUBLIC LICENSE 3.0. * for more details about the license see http://www.osmembrane.de/license/ * * Source: $HeadURL$ ($Revision$) * Last changed: $Date$ */ package de.osmembrane.view.panels; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Image; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.util.ArrayList; import java.util.List; import javax.swing.ImageIcon; import javax.swing.SwingUtilities; import de.osmembrane.model.pipeline.AbstractConnector; import de.osmembrane.model.pipeline.Connector; import de.osmembrane.resources.Constants; /** * Represents a function connector, i.e. {@link AbstractConnector} in the View * and the pipeline ({@link PipelinePanel}). * * @author tobias_kuhn * */ public class PipelineConnector extends DisplayTemplatePanel { private static final long serialVersionUID = -3777471525969957175L; /** * The {@link ImageIcon} resource that keeps an image template used to * prerender the actual image that will be drawn on this connector */ protected static ImageIcon displayTemplate = new ImageIcon( PipelineConnector.class .getResource("/de/osmembrane/resources/images/connector.png")); /** * The model {@link Connector} associated with this connector */ private AbstractConnector modelConnector; /** * The parent {@link PipelineFunction} associated with this connector */ private PipelineFunction parentFunction; /** * {@link PipelinePanel} this connector is drawn on. */ private PipelinePanel pipeline; /** * The image to use for display */ private Image display; /** * Whether this is an outpipes connector (true) or an inpipes connector * (false) */ private boolean isOutpipes; /** * the id this connector has in a group of connectors. one group of * connectors is all the in- or out-connectors of a function */ private int id; /** * amount of the connectors in the group of connectors. one group of * connectors is all the in- or out-connectors of a function */ private int amount; /** * list of {@link PipelineLink}s going from this connector to other * connectors */ private List<PipelineLink> outLinks; /** * lists of {@link PipelineLink}s coming in from other connectors to this * connector */ private List<PipelineLink> inLinks; /** * Creates a new connector for a model {@link Connector} on a * {@link PipelineFunction}. * * @param modelConnector * connector in the model which is represented * @param parentFunction * the function this connector belongs to * @param pipeline * Pipeline this connector is drawn on * @param isOutpipes * true, if this is an outpipes connector, false if this is an * inpipes connector * @param id * unique id for this connector starting by 0 < ofCount * @param amount * the amount of this kind of connectors (out or in) on the * specific function they are created for */ public PipelineConnector(AbstractConnector modelConnector, final PipelineFunction parentFunction, final PipelinePanel pipeline, boolean isOutpipes, int id, int amount) { this.modelConnector = modelConnector; setPreferredSize(new Dimension( (int) (displayTemplate.getIconWidth() * Constants.DEFAULT_SIZE_FACTOR), (int) (displayTemplate.getIconHeight() * Constants.DEFAULT_SIZE_FACTOR))); this.pipeline = pipeline; this.parentFunction = parentFunction; this.isOutpipes = isOutpipes; this.id = id; this.amount = amount; this.outLinks = new ArrayList<PipelineLink>(); this.inLinks = new ArrayList<PipelineLink>(); this.addMouseListener(new MouseListener() { @Override public void mouseReleased(MouseEvent e) { MouseEvent pipelineEvent = SwingUtilities.convertMouseEvent( PipelineConnector.this, e, pipeline); if (pipeline.getActiveTool() != Tool.DEFAULT_MAGIC_TOOL) { pipeline.dispatchEvent(pipelineEvent); } } @Override public void mousePressed(MouseEvent e) { MouseEvent pipelineEvent = SwingUtilities.convertMouseEvent( PipelineConnector.this, e, pipeline); if (pipeline.getActiveTool() == Tool.DEFAULT_MAGIC_TOOL) { pipeline.connect(parentFunction); } else { pipeline.dispatchEvent(pipelineEvent); } } @Override public void mouseExited(MouseEvent e) { } @Override public void mouseEntered(MouseEvent e) { } @Override public void mouseClicked(MouseEvent e) { } }); this.addMouseMotionListener(new MouseMotionListener() { @Override public void mouseMoved(MouseEvent e) { MouseEvent pipelineEvent = SwingUtilities.convertMouseEvent( PipelineConnector.this, e, pipeline); pipeline.dispatchEvent(pipelineEvent); } @Override public void mouseDragged(MouseEvent e) { MouseEvent pipelineEvent = SwingUtilities.convertMouseEvent( PipelineConnector.this, e, pipeline); switch (pipeline.getActiveTool()) { case VIEW_TOOL: pipeline.dispatchEvent(pipelineEvent); break; } } }); /* * use DisplayTemplatePanel prerender capabilites in this case we store * it for *CONNECTOR TYPES ONLY* if you ever want images/connector, * change this */ List<Image> prerender = DisplayTemplatePanel .givePrerender(modelConnector.getType()); if (prerender != null) { // prender exists, use it display = prerender.get(0); } else { // find right color Color color = modelConnector.getType().getColor(); // create it display = DisplayTemplatePanel.prerenderDisplay( modelConnector.getType(), displayTemplate, color, null); } this.setOpaque(false); /* * do not create outLinks here already, we don't know if we are done * with all other connectors yet */ } /** * Generates all outLinks that the model maintains */ public void generateLinksFromModel() { if (isOutpipes) { createLinks(); } } /** * Creates all the outflowing {@link PipelineLink}s from this connector. */ private void createLinks() { for (AbstractConnector ac : modelConnector.getConnections()) { PipelineConnector toCon = pipeline.findConnector(ac); PipelineLink pl = new PipelineLink(pipeline, this, toCon); // out link here outLinks.add(pl); // in link there toCon.inLinks.add(pl); } } /** * Arranges all {@link PipelineLink}s to conform to this connector */ public void arrangeLinks() { for (PipelineLink pl : outLinks) { PipelineConnector dest = pl.getLinkDestination(); /* set size, set location */ if (this.getX() < dest.getX()) { // arrow goes like -----> if (this.getY() < dest.getY()) { // left top to right bottom pl.setLocation(this.getX(), this.getY()); pl.setSize(dest.getWidth() + dest.getX() - this.getX(), dest.getHeight() + dest.getY() - this.getY()); } else { // left bottom to right top pl.setLocation(this.getX(), dest.getY()); pl.setSize(dest.getWidth() + dest.getX() - this.getX(), this.getHeight() + this.getY() - dest.getY()); } } else { // arrow goes like <----- if (this.getY() < dest.getY()) { // right top to left bottom pl.setLocation(dest.getX(), this.getY()); pl.setSize(this.getWidth() + this.getX() - dest.getX(), dest.getHeight() + dest.getY() - this.getY()); } else { // right bottom to left top pl.setLocation(dest.getX(), dest.getY()); pl.setSize(this.getWidth() + this.getX() - dest.getX(), this.getHeight() + this.getY() - dest.getY()); } } pl.regenerateLine(); } } @Override protected void paintComponent(Graphics g) { g.drawImage(display, 0, 0, getWidth(), getHeight(), this); } /** * @return the model {@link Connector} represented by this */ public AbstractConnector getModelConnector() { return this.modelConnector; } /** * @return whether this connector represents in pipes or out pipes */ public boolean isOutpipes() { return this.isOutpipes; } /** * @return the id this connector has in a group of connectors. one group of * connectors is all the in- or out-connectors of a function */ public int getId() { return this.id; } /** * @return amount of the connectors in the group of connectors. one group of * connectors is all the in- or out-connectors of a function */ public int getAmount() { return this.amount; } /** * @return the list of {@link PipelineLink}s flowing out from this connector */ public List<PipelineLink> getOutLinks() { return this.outLinks; } /** * @return the list of {@link PipelineLink}s coming in to this connector */ public List<PipelineLink> getInLinks() { return this.inLinks; } /** * Creates a new {@link PipelineLink} to toConnector and returns it. * * @param toConnector * the target of the connection from here * @return the newly created link */ public PipelineLink addLinkTo(PipelineConnector toConnector) { PipelineLink pl = new PipelineLink(pipeline, this, toConnector); outLinks.add(pl); toConnector.inLinks.add(pl); return pl; } /** * Removes the {@link PipelineLink} to toConnector and returns it. * * @param toConnector * the target of the connection from here * @return the removed link, or null if none found */ public PipelineLink removeLinkTo(PipelineConnector toConnector) { PipelineLink result = null; // out from here for (int i = 0; i < outLinks.size(); i++) { result = outLinks.get(i); if (result.doesLink(this, toConnector)) { outLinks.remove(i); break; } } // in to there for (int i = 0; i < toConnector.inLinks.size(); i++) { if (toConnector.inLinks.get(i).equals(result)) { toConnector.inLinks.remove(i); break; } } return result; } /** * @return the parent {@link PipelineFunction} this connector belongs to */ public PipelineFunction getParentFunction() { return this.parentFunction; } }