+++ /dev/null
-/**
- *
- */
-package fr.orsay.lri.varna.applications.templateEditor;
-
-import java.awt.BasicStroke;
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.Point;
-import java.awt.Polygon;
-import java.awt.Rectangle;
-import java.awt.RenderingHints;
-import java.awt.Stroke;
-import java.awt.geom.Point2D;
-import java.io.File;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Stack;
-
-import javax.swing.JOptionPane;
-import javax.swing.JPanel;
-import javax.swing.undo.UndoManager;
-
-import fr.orsay.lri.varna.applications.templateEditor.GraphicalTemplateElement.RelativePosition;
-import fr.orsay.lri.varna.controlers.ControleurMolette;
-import fr.orsay.lri.varna.exceptions.ExceptionInvalidRNATemplate;
-import fr.orsay.lri.varna.exceptions.ExceptionXmlLoading;
-import fr.orsay.lri.varna.models.templates.RNATemplate;
-import fr.orsay.lri.varna.models.templates.RNATemplate.RNATemplateElement;
-import fr.orsay.lri.varna.models.templates.RNATemplate.RNATemplateHelix;
-import fr.orsay.lri.varna.models.templates.RNATemplate.RNATemplateUnpairedSequence;
-import fr.orsay.lri.varna.models.templates.RNATemplate.RNATemplateElement.EdgeEndPoint;
-
-
-
-
-/**
- * @author ponty
- *
- */
-public class TemplatePanel extends JPanel {
- /**
- *
- */
- private static final long serialVersionUID = 3162771335587335679L;
-
-
- private ArrayList<GraphicalTemplateElement> _RNAComponents;
- private ArrayList<Connection> _RNAConnections;
- private Hashtable<Couple<GraphicalTemplateElement,GraphicalTemplateElement.RelativePosition>,Connection> _helixToConnection;
- private TemplateEditorPanelUI _ui;
-
- private RNATemplate _template;
-
-
- private static Color[] BackgroundColors = {Color.blue,Color.red,Color.cyan,Color.green,Color.lightGray,Color.magenta,Color.PINK};
-
- private int _nextBackgroundColor = 0;
-
- private static double scaleFactorDefault = 0.7;
- private double scaleFactor = scaleFactorDefault;
-
-
- private TemplateEditor _editor;
-
-
- public double getScaleFactor() {
- return scaleFactor;
- }
-
- public void setScaleFactor(double scaleFactor) {
- this.scaleFactor = scaleFactor;
- }
-
- public Color nextBackgroundColor()
- {
- Color c = BackgroundColors[_nextBackgroundColor++];
- _nextBackgroundColor = _nextBackgroundColor % BackgroundColors.length;
- return new Color(c.getRed(),c.getBlue(),c.getGreen(),50);
- }
-
- public TemplatePanel(TemplateEditor parent)
- {
- _editor = parent;
- init();
- }
-
- public RNATemplate getTemplate()
- {
- return _template;
- }
-
- List<GraphicalTemplateElement> getRNAComponents() {
- return _RNAComponents;
- }
-
- private void init()
- {
- _ui = new TemplateEditorPanelUI(this);
-
- _RNAComponents = new ArrayList<GraphicalTemplateElement>();
- _RNAConnections = new ArrayList<Connection>();
- _helixToConnection = new Hashtable<Couple<GraphicalTemplateElement,GraphicalTemplateElement.RelativePosition>,Connection>();
-
- _template = new RNATemplate();
-
- setBackground(Color.WHITE);
- MouseControler mc = new MouseControler(this,_ui);
- addMouseListener(mc);
- addMouseMotionListener(mc);
- addMouseWheelListener(mc);
- _solidStroke = new BasicStroke(1.5f, BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND, 3.0f);
- float[] dash = { 5.0f, 5.0f };
- _dashedStroke = new BasicStroke(1.5f, BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND, 3.0f, dash, 0);
- }
-
- public void addUndoableEditListener(UndoManager manager)
- {
- _ui.addUndoableEditListener(manager);
- }
-
- public TemplateEditorPanelUI getTemplateUI()
- {
- return _ui;
- }
-
-
- public void flip(Helix h)
- {
- h.toggleFlipped();
- }
-
- public void addElement(GraphicalTemplateElement h)
- {
- _RNAComponents.add(h);
- }
-
- public void removeElement(GraphicalTemplateElement h)
- {
- _RNAComponents.remove(h);
- try {
- _template.removeElement(h.getTemplateElement());
- } catch (ExceptionInvalidRNATemplate e) {
- //e.printStackTrace();
- }
- }
-
- private GraphicalTemplateElement _selected = null;
-
- public GraphicalTemplateElement getSelected()
- {
- return _selected;
- }
-
- public void setSelected(GraphicalTemplateElement sel)
- {
- _selected = sel;
- if (_selected instanceof Helix) {
- _editor.flipButtonEnable();
- } else {
- _editor.flipButtonDisable();
- }
- }
-
- Helix.RelativePosition _relpos = Helix.RelativePosition.RP_OUTER;
-
- public void setSelectedEdge(Helix.RelativePosition rel)
- {
- _relpos = rel;
- }
-
- public void unselectEdge(Helix.RelativePosition rel)
- {
- _relpos = rel;
- }
-
- Point2D.Double _mousePos = new Point2D.Double();
-
- public void setPointerPos(Point2D.Double p)
- {
- _mousePos = p;
- }
-
- public void Unselect()
- {
- _editor.flipButtonDisable();
- _selected = null;
- }
-
- public GraphicalTemplateElement getElement(RNATemplateElement t)
- {
- for(GraphicalTemplateElement t2: _RNAComponents)
- if (t==t2.getTemplateElement())
- return t2;
- return null;
- }
-
-
- public GraphicalTemplateElement getElementAt(double x, double y)
- {
- return getElementAt(x, y, null);
- }
- public GraphicalTemplateElement getElementAt(double x, double y, GraphicalTemplateElement excluded)
- {
- GraphicalTemplateElement h = null;
- for (int i=0; i<_RNAComponents.size();i++)
- {
- GraphicalTemplateElement h2 = _RNAComponents.get(i);
- if ((
- (h2.getRelativePosition(x, y)== Helix.RelativePosition.RP_CONNECT_END3)
- || (h2.getRelativePosition(x, y)== Helix.RelativePosition.RP_CONNECT_END5)
- || (h2.getRelativePosition(x, y)== Helix.RelativePosition.RP_CONNECT_START3)
- || (h2.getRelativePosition(x, y)== Helix.RelativePosition.RP_CONNECT_START5))
- && (excluded!=h2))
- {
- h = h2;
- }
- }
- if (h==null)
- { h = getElementCloseTo(x, y, excluded);};
- return h;
- }
-
- public GraphicalTemplateElement getElementCloseTo(double x, double y)
- {
- return getElementCloseTo(x, y, null);
- }
- public GraphicalTemplateElement getElementCloseTo(double x, double y, GraphicalTemplateElement excluded)
- {
- GraphicalTemplateElement h = null;
- for (int i=0; i<_RNAComponents.size();i++)
- {
- GraphicalTemplateElement h2 = _RNAComponents.get(i);
- if ((h2.getRelativePosition(x, y) != Helix.RelativePosition.RP_OUTER)
- && (excluded!=h2))
- {
- h = h2;
- }
- }
- return h;
- }
-
- public void addConnection(Connection c)
- {
- _RNAConnections.add(c);
- _helixToConnection.put(new Couple<GraphicalTemplateElement,GraphicalTemplateElement.RelativePosition>(c._h1,c._edge1), c);
- _helixToConnection.put(new Couple<GraphicalTemplateElement,GraphicalTemplateElement.RelativePosition>(c._h2,c._edge2), c);
- try {
- c._h1.attach(c._h2, c._edge1, c._edge2);
- c._h2.attach(c._h1, c._edge2, c._edge1);
- } catch (ExceptionInvalidRNATemplate e) {
- System.out.println(e.toString());// TODO Auto-generated catch block
- }
-
- }
-
- public Connection addConnection(GraphicalTemplateElement h1, GraphicalTemplateElement.RelativePosition edge1,GraphicalTemplateElement h2, GraphicalTemplateElement.RelativePosition edge2)
- {
- if ((h1!=h2)&&(getPartner(h1,edge1)==null)&&(getPartner(h2,edge2)==null))
- {
- Connection c = new Connection(h1,edge1,h2,edge2);
- addConnection(c);
- return c;
- }
- return null;
- }
-
- /**
- * When there is already a connection in the underlying RNATemplate
- * and we want to create one at the graphical level.
- */
- public void addGraphicalConnection(GraphicalTemplateElement h1, GraphicalTemplateElement.RelativePosition edge1,GraphicalTemplateElement h2, GraphicalTemplateElement.RelativePosition edge2) {
- //System.out.println("Connecting " + h1 + " " + edge1 + " to " + h2 + " " + edge2);
- Connection c = new Connection(h1,edge1,h2,edge2);
- _RNAConnections.add(c);
- _helixToConnection.put(new Couple<GraphicalTemplateElement,GraphicalTemplateElement.RelativePosition>(c._h1,c._edge1), c);
- _helixToConnection.put(new Couple<GraphicalTemplateElement,GraphicalTemplateElement.RelativePosition>(c._h2,c._edge2), c);
- c._h1.graphicalAttach(c._h2, c._edge1, c._edge2);
- c._h2.graphicalAttach(c._h1, c._edge2, c._edge1);
- }
-
-
- public void removeConnection(Connection c)
- {
- _RNAConnections.remove(c);
- _helixToConnection.remove(new Couple<GraphicalTemplateElement,GraphicalTemplateElement.RelativePosition>(c._h1,c._edge1));
- _helixToConnection.remove(new Couple<GraphicalTemplateElement,GraphicalTemplateElement.RelativePosition>(c._h2,c._edge2));
- System.out.println("[A]"+c);
- c._h1.detach(c._edge1);
- }
-
- public boolean isInCycle(GraphicalTemplateElement el, GraphicalTemplateElement.RelativePosition edge)
- {
- Stack<Couple<GraphicalTemplateElement,GraphicalTemplateElement.RelativePosition> > p = new Stack<Couple<GraphicalTemplateElement,GraphicalTemplateElement.RelativePosition>>();
- Hashtable<Couple<GraphicalTemplateElement,GraphicalTemplateElement.RelativePosition>,Integer> alreadySeen = new Hashtable<Couple<GraphicalTemplateElement,GraphicalTemplateElement.RelativePosition>,Integer>();
- p.add(new Couple<GraphicalTemplateElement,GraphicalTemplateElement.RelativePosition>(el,edge));
- while(!p.empty())
- {
- Couple<GraphicalTemplateElement,GraphicalTemplateElement.RelativePosition> c2 = p.pop();
- if (alreadySeen.containsKey(c2))
- {
- return true;
- }
- else
- {
- alreadySeen.put(c2, new Integer(1));
- }
- GraphicalTemplateElement.RelativePosition next = c2.first.getConnectedEdge(c2.second);
- Couple<GraphicalTemplateElement,GraphicalTemplateElement.RelativePosition> otherEnd = new Couple<GraphicalTemplateElement,GraphicalTemplateElement.RelativePosition>(c2.first,next);
- if (!alreadySeen.containsKey(otherEnd))
- {
- p.push(otherEnd);
- }
- else
- {
- Couple<GraphicalTemplateElement,GraphicalTemplateElement.RelativePosition> child = getPartner(c2.first,c2.second);
- if (child!=null)
- {
- p.push(child);
- }
- }
-
- }
-
- return false;
- }
-
- private static Color[] _colors = {Color.gray,Color.pink,Color.cyan,Color.RED,Color.green,Color.orange};
-
- public static Color getIndexedColor(int n)
- {
- return _colors[n%_colors.length];
- }
-
- public HashMap<Couple<GraphicalTemplateElement,GraphicalTemplateElement.RelativePosition>,Integer> buildConnectedComponents()
- {
- HashMap<Couple<GraphicalTemplateElement,GraphicalTemplateElement.RelativePosition>,Integer> alreadySeen = new HashMap<Couple<GraphicalTemplateElement,GraphicalTemplateElement.RelativePosition>,Integer>();
- int numConnectedComponents = 0;
- for (GraphicalTemplateElement el : this._RNAComponents)
- {
- for (GraphicalTemplateElement.RelativePosition edge : el.getConnectedEdges())
- {
- Couple<GraphicalTemplateElement,GraphicalTemplateElement.RelativePosition> c = new Couple<GraphicalTemplateElement,GraphicalTemplateElement.RelativePosition>(el,edge);
- if (!alreadySeen.containsKey(c))
- {
- Stack<Couple<GraphicalTemplateElement,GraphicalTemplateElement.RelativePosition> > p = new Stack<Couple<GraphicalTemplateElement,GraphicalTemplateElement.RelativePosition>>();
- p.add(c);
- p.add(new Couple<GraphicalTemplateElement,GraphicalTemplateElement.RelativePosition>(el,el.getConnectedEdge(edge)));
- while(!p.empty())
- {
- Couple<GraphicalTemplateElement,GraphicalTemplateElement.RelativePosition> c2 = p.pop();
- if (!alreadySeen.containsKey(c2))
- {
- //System.out.println(" "+numConnectedComponents+" "+c2);
- c2.first.setMainColor(c2.second, getIndexedColor(numConnectedComponents));
- alreadySeen.put(c2, new Integer(numConnectedComponents));
- GraphicalTemplateElement.RelativePosition next = c2.first.getConnectedEdge(c2.second);
- Couple<GraphicalTemplateElement,GraphicalTemplateElement.RelativePosition> otherEnd = new Couple<GraphicalTemplateElement,GraphicalTemplateElement.RelativePosition>(c2.first,next);
- p.push(otherEnd);
- Couple<GraphicalTemplateElement,GraphicalTemplateElement.RelativePosition> child = getPartner(c2.first,c2.second);
- if (child!=null)
- { p.push(child); }
- }
- }
- numConnectedComponents += 1;
- }
- }
- }
- return alreadySeen;
- }
-
- public boolean isInCycle(Connection c)
- {
- return isInCycle(c._h1,c._edge1);
- }
-
- public Couple<GraphicalTemplateElement,GraphicalTemplateElement.RelativePosition> getPartner(GraphicalTemplateElement h, GraphicalTemplateElement.RelativePosition edge)
- {
- Connection c = getConnection(h, edge);
- if (c != null)
- {
- if ((c._h1==h)&&(c._edge1==edge))
- { return new Couple<GraphicalTemplateElement,GraphicalTemplateElement.RelativePosition>(c._h2,c._edge2); }
- else
- { return new Couple<GraphicalTemplateElement,GraphicalTemplateElement.RelativePosition>(c._h1,c._edge1); }
- }
- else
- {
- return null;
- }
- }
-
- public Connection getConnection(GraphicalTemplateElement h, Helix.RelativePosition edge)
- {
- Couple<GraphicalTemplateElement,GraphicalTemplateElement.RelativePosition> target = new Couple<GraphicalTemplateElement,GraphicalTemplateElement.RelativePosition>(h,edge);
- if (_helixToConnection.containsKey(target))
- {
- return _helixToConnection.get(target);
- }
- else
- { return null; }
- }
-
- private boolean isConnected(Helix h, GraphicalTemplateElement.RelativePosition edge)
- {
- Couple<GraphicalTemplateElement,GraphicalTemplateElement.RelativePosition> partner = getPartner(h,edge);
- return partner!=null;
- }
-
-
- // Aspects graphiques
-
- private static final Color CYCLE_COLOR = Color.red;
- private static final Color NON_EXISTANT_COLOR = Color.gray.brighter();
- private static final Color CONTROL_COLOR = Color.gray.darker();
- private static final Color BACKGROUND_COLOR = Color.white;
-
- private Stroke _solidStroke;
- private Stroke _dashedStroke;
-
-
-
-
- private void drawConnections(Graphics2D g2d, Connection c)
- {
- GraphicalTemplateElement h1 = c._h1;
- GraphicalTemplateElement.RelativePosition edge1 = c._edge1;
- Point2D.Double p1 = h1.getEdgePosition(edge1);
- GraphicalTemplateElement h2 = c._h2;
- GraphicalTemplateElement.RelativePosition edge2 = c._edge2;
- Point2D.Double p2 = h2.getEdgePosition(edge2);
- if (isInCycle(c))
- {
- g2d.setColor(CYCLE_COLOR);
- }
- else
- {
- g2d.setColor(GraphicalTemplateElement.BACKBONE_COLOR);
- }
- g2d.drawLine((int)p1.x,(int)p1.y,(int)p2.x,(int)p2.y);
- }
-
-
- public void paintComponent(Graphics g)
- {
- //rescale();
-
- // Debug code to show drawing area
-// g.setColor(Color.red);
-// g.fillRect(0,0,getWidth(),getHeight());
-// g.setColor(Color.white);
-// g.fillRect(10,10,getWidth()-20,getHeight()-20);
-
- g.setColor(Color.white);
- g.fillRect(0,0,getWidth(),getHeight());
-
- Graphics2D g2d = (Graphics2D) g;
- g2d.scale(scaleFactor, scaleFactor);
- g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
- RenderingHints.VALUE_ANTIALIAS_ON);
- removeAll();
- //super.paintComponent(g2d);
-
- buildConnectedComponents();
-
- if (_selected!=null)
- {
- if (_relpos != GraphicalTemplateElement.RelativePosition.RP_OUTER)
- {
- Point2D.Double p = _selected.getEdgePosition(_relpos);
- g2d.setStroke(_solidStroke);
- g2d.drawLine((int)_mousePos.x, (int)_mousePos.y, (int)p.x, (int)p.y);
- }
- }
- for (int i=0;i<_RNAConnections.size();i++)
- {
- Connection c = _RNAConnections.get(i);
- drawConnections(g2d,c);
- }
- for (int i=0;i<_RNAComponents.size();i++)
- {
- GraphicalTemplateElement elem = _RNAComponents.get(i);
- //g2d.setColor(elem.getDominantColor());
- //g2d.fill(elem.getArea());
- if (_selected == elem)
- {
- elem.draw(g2d,true);
- }
- else
- { elem.draw(g2d,false); }
- }
- }
-
- /**
- * Get the bounding rectangle of the RNA components, always including the origin (0,0).
- */
- public Rectangle getBoundingRectange() {
- int minX = 0;
- int maxX = 0;
- int minY = 0;
- int maxY = 0;
- for(int i=0;i<this._RNAComponents.size();i++)
- {
- GraphicalTemplateElement h = _RNAComponents.get(i);
- Polygon p = h.getBoundingPolygon();
- Rectangle r = p.getBounds();
- minX = Math.min(minX,r.x);
- maxX = Math.max(maxX,r.x+r.width);
- minY = Math.min(minY,r.y);
- maxY = Math.max(maxY,r.y+r.height);
- }
- Rectangle res = new Rectangle();
- res.x = minX;
- res.y = minY;
- res.width = maxX - minX;
- res.height = maxY - minY;
- return res;
- }
-
- public void rescale()
- {
- Rectangle rect = getBoundingRectange();
-
- if (rect.x < 0 || rect.y < 0) {
- for(int i=0;i<this._RNAComponents.size();i++)
- {
- GraphicalTemplateElement h = _RNAComponents.get(i);
- h.translate(rect.x<0 ? -rect.x : 0, rect.y<0 ? -rect.y : 0);
- }
- rect = getBoundingRectange();
- }
-
- // areaW and H are width and height, in pixels, of the drawing area
- // including the "outside" parts available with scrolling
- int areaW = (int) ((rect.width + 100) * scaleFactor);
- int areaH = (int) ((rect.height + 100) * scaleFactor);
- // make it cover at least the space visible in the window
- //areaW = Math.max(areaW, (int) (_editor.getJp().getViewport().getViewSize().width));
- //areaH = Math.max(areaH, (int) (_editor.getJp().getViewport().getViewSize().height));
- //System.out.println(areaW + " x " + areaH);
- setPreferredSize(new Dimension(areaW, areaH));
- revalidate();
- }
-
- public void clearTemplate() {
- loadTemplate(new RNATemplate());
- }
-
- /**
- * Load an existing RNATemplate object in this panel.
- */
- public void loadTemplate(RNATemplate template) {
- _template = template;
- _RNAComponents.clear();
- _RNAConnections.clear();
- _helixToConnection.clear();
-
- // We need a template element -> graphical template element mapping
- Map<RNATemplateElement, GraphicalTemplateElement> map = new HashMap<RNATemplateElement, GraphicalTemplateElement>();
-
- // First, we load elements
- {
- Iterator<RNATemplateElement> iter = template.classicIterator();
- while (iter.hasNext()) {
- RNATemplateElement templateElement = iter.next();
- if (templateElement instanceof RNATemplateHelix) {
- RNATemplateHelix templateHelix = (RNATemplateHelix) templateElement;
- Helix graphicalHelix = new Helix(templateHelix);
- graphicalHelix.setDominantColor(nextBackgroundColor());
- _RNAComponents.add(graphicalHelix);
- map.put(templateHelix, graphicalHelix);
- } else if (templateElement instanceof RNATemplateUnpairedSequence) {
- RNATemplateUnpairedSequence templateSequence = (RNATemplateUnpairedSequence) templateElement;
- UnpairedRegion graphicalSequence = new UnpairedRegion(templateSequence);
- graphicalSequence.setDominantColor(nextBackgroundColor());
- _RNAComponents.add(graphicalSequence);
- map.put(templateSequence, graphicalSequence);
- }
- }
- }
-
- // Now, we load edges
- {
- Iterator<EdgeEndPoint> iter = template.makeEdgeList().iterator();
- while (iter.hasNext()) {
- EdgeEndPoint v1 = iter.next();
- EdgeEndPoint v2 = v1.getOtherEndPoint();
- GraphicalTemplateElement gte1 = map.get(v1.getElement());
- GraphicalTemplateElement gte2 = map.get(v2.getElement());
- RelativePosition rp1 = gte1.relativePositionFromEdgeEndPointPosition(v1.getPosition());
- RelativePosition rp2 = gte2.relativePositionFromEdgeEndPointPosition(v2.getPosition());
- addGraphicalConnection(gte1, rp1, gte2, rp2);
- }
- }
-
- zoomFit();
- //repaint();
- }
-
- /**
- * Load a template from an XML file.
- */
- public void loadFromXmlFile(File filename) {
- try {
- RNATemplate newTemplate = RNATemplate.fromXMLFile(filename);
- loadTemplate(newTemplate);
- } catch (ExceptionXmlLoading e) {
- e.printStackTrace();
- JOptionPane.showMessageDialog(this, e.getMessage(), "Template loading error", JOptionPane.ERROR_MESSAGE);
- }
- }
-
- private void zoomFinish() {
- rescale();
- repaint();
- }
-
- public void zoomIn() {
- scaleFactor *= 1.2;
- zoomFinish();
- }
-
- public void zoomOut() {
- scaleFactor /= 1.2;
- zoomFinish();
- }
-
- public void zoomReset() {
- scaleFactor = scaleFactorDefault;
- zoomFinish();
- }
-
- public void zoomFit() {
- if (_RNAComponents.isEmpty()) {
- zoomReset();
- } else {
- Rectangle rect = getBoundingRectange();
- double areaW = (rect.width + 100);
- double areaH = (rect.height + 100);
- // make it cover at least the space visible in the window
- scaleFactor = 1;
- scaleFactor = Math.min(scaleFactor, _editor.getJp().getViewport().getSize().width / areaW);
- scaleFactor = Math.min(scaleFactor, _editor.getJp().getViewport().getSize().height / areaH);
- zoomFinish();
- }
- }
-
- public void translateView(Point trans) {
- int newX = _editor.getJp().getHorizontalScrollBar().getValue() - trans.x;
- int newY = _editor.getJp().getVerticalScrollBar().getValue() - trans.y;
- newX = Math.max(0, Math.min(newX, _editor.getJp().getHorizontalScrollBar().getMaximum()));
- newY = Math.max(0, Math.min(newY, _editor.getJp().getVerticalScrollBar().getMaximum()));
- _editor.getJp().getHorizontalScrollBar().setValue(newX);
- _editor.getJp().getVerticalScrollBar().setValue(newY);
- }
-}