package agg.gui.editor; import java.awt.BorderLayout; import java.awt.Cursor; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.Insets; import java.util.Enumeration; import java.util.Iterator; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JSplitPane; import javax.swing.JButton; import javax.swing.ImageIcon; import agg.attribute.impl.ContextView; import agg.editor.impl.EdArc; import agg.editor.impl.EdGraph; import agg.editor.impl.EdNode; import agg.gui.saveload.GraphicsExportJPEG; import agg.ruleappl.ObjectFlow; import agg.xt_basis.Arc; import agg.xt_basis.BadMappingException; import agg.xt_basis.Node; import agg.xt_basis.OrdinaryMorphism; import agg.xt_basis.GraphObject; /** * This class specifies a graph morphism editor which allows to set mappings * of an morphism. * * @author $Author: olga $ */ @SuppressWarnings("serial") public class GraphMorphismEditor extends JPanel { private final GraphMorphismEditorMouseAdapter mouseAdapter; private final GraphMorphismEditorMouseMotionAdapter mouseMotionAdapter; /** * Creates a graph morphism editor. */ public GraphMorphismEditor(final JFrame parentFrame) { super(new BorderLayout()); this.applFrame = parentFrame; this.mainPanel = this; this.mouseAdapter = new GraphMorphismEditorMouseAdapter(this); this.mouseMotionAdapter = new GraphMorphismEditorMouseMotionAdapter(this); this.leftPanel = new GraphPanel(this); this.leftPanel.setName("Source Graph"); final JPanel lPanel = new JPanel(new BorderLayout()); lPanel.setPreferredSize(new Dimension(250, 150)); lPanel.add(this.leftPanel, BorderLayout.CENTER); this.rightPanel = new GraphPanel(this); this.rightPanel.setName("Target Graph"); final JPanel rPanel = new JPanel(new BorderLayout()); rPanel.setPreferredSize(new Dimension(500, 150)); rPanel.add(this.rightPanel, BorderLayout.CENTER); this.splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, lPanel, rPanel); this.splitPane.setDividerSize(10); this.splitPane.setContinuousLayout(true); this.splitPane.setOneTouchExpandable(true); this.dividerLocation = 250; this.splitPane.setDividerLocation(this.dividerLocation); final JPanel morphPanel = new JPanel(new BorderLayout()); morphPanel.setPreferredSize(new Dimension(500, 150)); this.title = new JLabel(" "); this.exportJPEGButton = createExportJPEGButton(); final JPanel titlePanel = new JPanel(new BorderLayout()); titlePanel.add(this.title, BorderLayout.CENTER); if (this.exportJPEGButton != null) titlePanel.add(this.exportJPEGButton, BorderLayout.EAST); morphPanel.add(titlePanel, BorderLayout.NORTH); morphPanel.add(this.splitPane, BorderLayout.CENTER); add(morphPanel, BorderLayout.CENTER); this.leftPanel.getCanvas().addMouseListener(this.mouseAdapter); this.rightPanel.getCanvas().addMouseListener(this.mouseAdapter); this.leftPanel.getCanvas().addMouseMotionListener(this.mouseMotionAdapter); this.rightPanel.getCanvas().addMouseMotionListener(this.mouseMotionAdapter); String tooltipLeft = "Connect: click object left and object right."; String tooltipRight = "Disconnect: click object left and background right."; this.leftPanel.getCanvas().setToolTipText(tooltipLeft); this.rightPanel.getCanvas().setToolTipText(tooltipRight); } // public JFrame getApplFrame() { // return this.applFrame; // } private JButton createExportJPEGButton() { java.net.URL url = ClassLoader.getSystemClassLoader() .getResource("agg/lib/icons/print.gif"); if (url != null) { ImageIcon image = new ImageIcon(url); // System.out.println(image); JButton b = new JButton(image); b.setToolTipText("Export JPEG"); b.setMargin(new Insets(-5, 0, -5, 0)); b.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (GraphMorphismEditor.this.exportJPEG != null) GraphMorphismEditor.this.exportJPEG.save(GraphMorphismEditor.this.mainPanel); } }); b.setEnabled(false); return b; } return null; } public void setMorphism(final OrdinaryMorphism morph) { this.morphism = morph; } public void setIsoMorphismLeft(final OrdinaryMorphism isoLeft) { this.isoLeft = isoLeft; } public void setIsoMorphismRight(final OrdinaryMorphism isoRight) { this.isoRight = isoRight; } public void setObjectFlow(final ObjectFlow objFlow) { this.objFlow = objFlow; } public ObjectFlow getObjectFlow() { return this.objFlow; } public boolean addMapping(final GraphObject leftobj, final GraphObject rightobj) { if (this.morphism.getInverseImage(rightobj).hasMoreElements()) { if (this.morphism.getInverseImage(rightobj).nextElement() != leftobj) removeMapping(this.morphism.getInverseImage(rightobj).nextElement()); else return true; } boolean mapOK = false; if (leftobj != null && rightobj != null) { int currentlyAllowedMapping = ((ContextView) this.morphism.getAttrContext()).getAllowedMapping(); // System.out.println(leftobj+" "+rightobj+" "+leftobj.getType().isParentOf(rightobj.getType())); try { if (leftobj.getType().isParentOf(rightobj.getType()) && !rightobj.isAttrMemConstantValDifferent(leftobj)) { this.morphism.addMapping(leftobj, rightobj); mapOK = true; } else if (leftobj.getType().isChildOf(rightobj.getType()) && !rightobj.isAttrMemConstantValDifferent(leftobj)){ this.morphism.addChild2ParentMapping(leftobj, rightobj); mapOK = true; } } catch (BadMappingException ex) { System.out.println("add mapping of object flow: FAILED! "+ex.getMessage()); mapOK = false; } if (mapOK) { if (this.isoLeft != null && this.isoRight != null) { this.objFlow.addMapping( this.isoLeft.getInverseImage(leftobj).nextElement(), this.isoRight.getInverseImage(rightobj).nextElement()); } else { this.objFlow.addMapping(leftobj, rightobj); } if (((ContextView) this.morphism.getAttrContext()).getAllowedMapping() != currentlyAllowedMapping) ((ContextView) this.morphism.getAttrContext()).changeAllowedMapping(currentlyAllowedMapping); } } return mapOK; } private void removeNodeMapping(GraphObject obj) { // remove mappings of arcs if needed Iterator<Arc> arcs = ((Node)obj).getOutgoingArcs(); while (arcs.hasNext()) { this.removeArcMapping(arcs.next()); } arcs = ((Node)obj).getIncomingArcs(); while (arcs.hasNext()) { this.removeArcMapping(arcs.next()); } // remove node mapping this.morphism.removeMapping(obj); if (this.isoLeft != null && this.isoRight != null) { this.objFlow.removeMapping( this.isoLeft.getInverseImage(obj).nextElement()); } else { this.objFlow.removeMapping(obj); } } private void removeArcMapping(GraphObject obj) { this.morphism.removeMapping(obj); if (this.isoLeft != null && this.isoRight != null) { this.objFlow.removeMapping( this.isoLeft.getInverseImage(obj).nextElement()); } else { this.objFlow.removeMapping(obj); } } public boolean removeMapping(GraphObject obj) { if (obj != null) { if (obj.isNode()) removeNodeMapping(obj); else removeArcMapping(obj);; return true; } return false; } public void removeAllMappings() { this.morphism.removeAllMappings(); this.objFlow.getMapping().clear(); } /** Get minimum dimension */ public Dimension getMinimumSize() { return new Dimension(100, 100); } /** Get preferred dimension */ public Dimension getPreferredSize() { return new Dimension(500, 200); } public String getTitle() { return this.title.getText(); } /** Set title */ public void setTitle(String str) { this.title.setText(" " + str); } public void setLeftTitle(String str) { this.leftPanel.setName(" " + str); this.leftPanel.getCanvas().setName(" " + str); } public void setRightTitle(String str) { this.rightPanel.setName(" " + str); } /** Return left panel */ public GraphPanel getLeftPanel() { return this.leftPanel; } /** Return right panel */ public GraphPanel getRightPanel() { return this.rightPanel; } /** Return active panel */ public GraphPanel getActivePanel() { return this.activePanel; } /** Returns my mode */ public int getEditMode() { return this.leftPanel.getEditMode(); } /** Returns left graph */ public EdGraph getLeftGraph() { return this.leftGraph; } /** Return right graph */ public EdGraph getRightGraph() { return this.rightGraph; } public void setLeftGraph(EdGraph g) { this.leftGraph = g; if (this.leftGraph == null) { setLeftTitle(" "); this.leftPanel.setGraph(null); // this.rightPanel.setGraph(null); // if (this.exportJPEGButton != null) // this.exportJPEGButton.setEnabled(false); return; } this.leftPanel.setGraph(g, true); // if (this.exportJPEGButton != null // && this.exportJPEG != null) { // this.exportJPEGButton.setEnabled(true); // } } public void setRightGraph(EdGraph g) { this.rightGraph = g; if (this.rightGraph == null) { setRightTitle(" "); // this.leftPanel.setGraph(null); this.rightPanel.setGraph(null); // if (this.exportJPEGButton != null) // this.exportJPEGButton.setEnabled(false); return; } this.rightPanel.setGraph(g, true); // if (this.exportJPEGButton != null // && this.exportJPEG != null) { // this.exportJPEGButton.setEnabled(true); // } } public int getDividerLocation() { return this.dividerLocation; } public void setDividerLocation(int i) { this.splitPane.setDividerLocation(i); } /** * Updates layout of the LHS and RHS along the morphism. */ public void updateGraphs() { this.getLeftGraph().clearMarks(); this.getRightGraph().clearMarks(); EdNode enL = null; EdNode enR = null; EdArc eaL = null; EdArc eaR = null; if (this.morphism == null) return; Enumeration<GraphObject> domain = this.morphism.getDomain(); while (domain.hasMoreElements()) { GraphObject bOrig = domain.nextElement(); GraphObject bImage = this.morphism.getImage(bOrig); enL = this.getLeftGraph().findNode(bOrig); if (enL != null) { if (enL.isMorphismMarkEmpty()) enL.addMorphismMark(enL.getMyKey()); enR = this.getRightGraph().findNode(bImage); if (enR != null) enR.addMorphismMark(enL.getMorphismMark()); else enL.clearMorphismMark(); } eaL = this.getLeftGraph().findArc(bOrig); if (eaL != null) { if (eaL.isMorphismMarkEmpty()) eaL.addMorphismMark(eaL.getMyKey()); eaR = this.getRightGraph().findArc(bImage); if (eaR != null) eaR.addMorphismMark(eaL.getMorphismMark()); else eaL.clearMorphismMark(); } } } /** Update graphics of my left and right panels */ public void updateGraphics() { synchronized(this) { this.leftPanel.updateGraphics(); this.rightPanel.updateGraphics(); } } /** Update graphics of my left and right graph panels */ public void updateGraphics(boolean graphDimensionCheck) { synchronized(this) { this.leftPanel.updateGraphics(graphDimensionCheck); this.rightPanel.updateGraphics(graphDimensionCheck); } } /** Clear graph panels. */ public void clear() { setLeftGraph(null); setRightGraph(null); updateGraphics(); } /** Set current mode. */ public void setEditMode(int mode) { switch (mode) { case EditorConstants.MAP: mapModeProc(); break; case EditorConstants.UNMAP: unmapModeProc(); break; case EditorConstants.VIEW: viewModeProc(); break; default: break; } } /** Return current mode */ public int getMode() { return this.leftPanel.getEditMode(); } /** Set cursor specified by the Cursor cur */ public void setEditCursor(Cursor cur) { this.leftPanel.setEditCursor(cur); this.rightPanel.setEditCursor(cur); } private void mapModeProc() { setPanelEditMode(EditorConstants.MAP); setEditCursor(new Cursor(Cursor.HAND_CURSOR)); if (this.applFrame != null) this.applFrame.setCursor(new Cursor(Cursor.HAND_CURSOR)); // msg = "Click on a source object and a target object to get a mapping."; } private void unmapModeProc() { setPanelEditMode(EditorConstants.UNMAP); setEditCursor(new Cursor(Cursor.HAND_CURSOR)); if (this.applFrame != null) this.applFrame.setCursor(new Cursor(Cursor.HAND_CURSOR)); // this.msg = "Click on the source of the mapping to destroy it."; } private void viewModeProc() { this.leftPanel.setEditMode(EditorConstants.VIEW); this.rightPanel.setEditMode(EditorConstants.VIEW); } public void setExportJPEG(GraphicsExportJPEG jpg) { this.exportJPEG = jpg; } public GraphPanel setActivePanel(Object src) { if (src instanceof GraphCanvas) this.activePanel = ((GraphCanvas) src).getViewport(); else this.activePanel = null; return this.activePanel; } private void setPanelEditMode(int mode) { this.leftPanel.setEditMode(mode); this.rightPanel.setEditMode(mode); } private final JFrame applFrame; final JPanel mainPanel; private final JLabel title; private final JSplitPane splitPane; private int dividerLocation; private final GraphPanel leftPanel; private final GraphPanel rightPanel; private GraphPanel activePanel; // private String msg = ""; private EdGraph leftGraph, rightGraph; private OrdinaryMorphism morphism; private OrdinaryMorphism isoLeft, isoRight; private ObjectFlow objFlow; GraphicsExportJPEG exportJPEG; private final JButton exportJPEGButton; }