/******************************************************************************** * * * (c) Copyright 2010 Verizon Communications USA and The Open University UK * * * * This software is freely distributed in accordance with * * the GNU Lesser General Public (LGPL) license, version 3 or later * * as published by the Free Software Foundation. * * For details see LGPL: http://www.fsf.org/licensing/licenses/lgpl.html * * and GPL: http://www.fsf.org/licensing/licenses/gpl-3.0.html * * * * This software is provided by the copyright holders and contributors "as is" * * and any express or implied warranties, including, but not limited to, the * * implied warranties of merchantability and fitness for a particular purpose * * are disclaimed. In no event shall the copyright owner or contributors be * * liable for any direct, indirect, incidental, special, exemplary, or * * consequential damages (including, but not limited to, procurement of * * substitute goods or services; loss of use, data, or profits; or business * * interruption) however caused and on any theory of liability, whether in * * contract, strict liability, or tort (including negligence or otherwise) * * arising in any way out of the use of this software, even if advised of the * * possibility of such damage. * * * ********************************************************************************/ package com.compendium.ui; import java.awt.Color; import java.awt.Container; import java.awt.Font; import java.awt.Point; import java.awt.Rectangle; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.awt.geom.AffineTransform; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.sql.SQLException; import javax.help.CSH; import javax.swing.JComponent; import javax.swing.JLayeredPane; import javax.swing.UIDefaults; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.compendium.LanguageProperties; import com.compendium.ProjectCompendium; import com.compendium.core.ICoreConstants; import com.compendium.core.datamodel.Link; import com.compendium.core.datamodel.LinkProperties; import com.compendium.core.datamodel.View; import com.compendium.ui.dialogs.UILinkContentDialog; import com.compendium.ui.linkgroups.UILinkType; import com.compendium.ui.plaf.LinkUI; import com.compendium.ui.popups.UILinkPopupMenu; /** * The main class that handles information for a map link. * * @author Mohammed Sajid Ali / Michelle Bachler */ public class UILink extends UILine implements PropertyChangeListener { /** * class's own logger */ final Logger log = LoggerFactory.getLogger(getClass()); // LINK NAMES /** Holds a string representation of the RESPONDS_TO_LINK type*/ public final static String sRESPONDSTOLINK = "Responds To Link"; //$NON-NLS-1$ /** Holds a string representation of the SUPPORTS_LINK type*/ public final static String sSUPPORTSLINK = "Supports Link"; //$NON-NLS-1$ /** Holds a string representation of the OBJECTS_TO_LINK type*/ public final static String sOBJECTSTOLINK = "Objects To Link"; //$NON-NLS-1$ /** Holds a string representation of the CHALLENGES_LINK type*/ public final static String sCHALLENGESLINK = "Challenges Link"; //$NON-NLS-1$ /** Holds a string representation of the SPECIALIZES_LINK type*/ public final static String sSPECIALIZESLINK = "Specializes Link"; //$NON-NLS-1$ /** Holds a string representation of the EXPANDS_ON_LINK type*/ public final static String sEXPANDSONLINK = "Expands On Link"; //$NON-NLS-1$ /** Holds a string representation of the RELATED_TO_LINK type*/ public final static String sRELATEDTOLINK = "Related To Link"; //$NON-NLS-1$ /** Holds a string representation of the ABOUT_LINK type*/ public final static String sABOUTLINK = "About Link"; //$NON-NLS-1$ /** Holds a string representation of the RESOLVES_LINK type*/ public final static String sRESOLVESLINK = "Resolves Link"; //$NON-NLS-1$ /** Holds a string representation of the default link type - currently the RELATED_TO_LINK.*/ public final static String sDEFAULTLINK = "Responds To Link"; //$NON-NLS-1$ // LINK LABELS /** Holds a string representation of the RESPONDS_TO_LINK type*/ public final static String sRESPONDSTOLINKLABEL = "Responds To"; //$NON-NLS-1$ /** Holds a string representation of the SUPPORTS_LINK type*/ public final static String sSUPPORTSLINKLABEL = "Supports"; //$NON-NLS-1$ /** Holds a string representation of the OBJECTS_TO_LINK type*/ public final static String sOBJECTSTOLINKLABEL = "Objects To"; //$NON-NLS-1$ /** Holds a string representation of the CHALLENGES_LINK type*/ public final static String sCHALLENGESLINKLABEL = "Challenges"; //$NON-NLS-1$ /** Holds a string representation of the SPECIALIZES_LINK type*/ public final static String sSPECIALIZESLINKLABEL = "Specializes"; //$NON-NLS-1$ /** Holds a string representation of the EXPANDS_ON_LINK type*/ public final static String sEXPANDSONLINKLABEL = "Expands On"; //$NON-NLS-1$ /** Holds a string representation of the RELATED_TO_LINK type*/ public final static String sRELATEDTOLINKLABEL = "Related To"; //$NON-NLS-1$ /** Holds a string representation of the ABOUT_LINK type*/ public final static String sABOUTLINKLABEL = "About"; //$NON-NLS-1$ /** Holds a string representation of the RESOLVES_LINK type*/ public final static String sRESOLVESLINKLABEL = "Resolves"; //$NON-NLS-1$ /** A reference to the label property for PropertyChangeEvents.*/ public static final String LABEL_PROPERTY = "linktext"; //$NON-NLS-1$ /** A reference to the link type property for PropertyChangeEvents.*/ public static final String TYPE_PROPERTY = "linktype"; //$NON-NLS-1$ /** The selection color to use for this link.*/ private static final Color SELECTED_COLOR = Color.yellow; //basic yellow for white bg /** The associated Link datamodel object.*/ protected Link oLink = null; /** The associated LinkProperties object that holds the formatting data.*/ protected LinkProperties oLinkProperties = null; /** The originating UINode for this link.*/ protected UINode oFromNode = null; /** The destination UINode for this link.*/ protected UINode oToNode = null; /** The value of the label.*/ protected String sText =""; //$NON-NLS-1$ /** * Constructor. Creates a new instance of UILink with the given parameters. * @param link the associated Link datamodel object. * @param props the associated LinkProperties object that holds the link formatting data. * @param fromNode the originating UINode for this link. * @param toNode the destination UINode for this link. */ public UILink(Link link, LinkProperties props, UINode fromNode, UINode toNode) { oLink = link; oLink.addPropertyChangeListener(this); setLinkProps(props); CSH.setHelpIDString(this,"node.links"); //$NON-NLS-1$ // line coordinates will be absolute setCoordinateType(UILine.ABSOLUTE); // set minimum width to 12 to allow for display of rollover indicator setMinWidth(12); // set selected color; setSelectedColor(SELECTED_COLOR); // set the nodes that are linked with this link setFromNode(fromNode); setToNode(toNode); //setBorder(new LineBorder(Color.red, 1)); //remove all returns and tabs which show up in the GUI as evil black char String label = ""; //$NON-NLS-1$ label = oLink.getLabel(); if (label == null || label.equals(ICoreConstants.NOLABEL_STRING)) label = ""; //$NON-NLS-1$ label = label.replace('\n',' '); label = label.replace('\r',' '); label = label.replace('\t',' '); setText(label); updateUI(); addFocusListener( new FocusListener() { public void focusGained(FocusEvent e) { repaint(); } public void focusLost(FocusEvent e) { ((LinkUI)getUI()).resetEditing(); repaint(); } }); } /** * Set the local link properties based on the passed properties. * @param props */ private void setLinkProps(LinkProperties props) { if (oLinkProperties != null) { oLinkProperties.removePropertyChangeListener(this); } oLinkProperties = props; props.addPropertyChangeListener(this); setArrow(props.getArrowType()); // set line color //It will be zero only on update from version 1.5.2, so needs updating to the correct Colour. //the RGB for black actually comes out as a minus number and not zero as expected. //So zero is safe to represent an unset colour. if (props.getLinkColour() == 0) { Color col = this.getLinkColor(oLink.getType()); props.setLinkColour(col.getRGB()); } setForeground(new Color(props.getLinkColour())); setLineThickness(props.getLinkWeight()); // set the font based on the link properties setDefaultFont(); } /** * Constructor. Creates a new instance of UILink with the given parameters. * <p>Used for creating dummy link when creating a new link in ui. * <p> * @param link com.compendium.core.datamodel.Link, the associated Link datamodel object. * @param fromNode com.compendium.ui.UINode, the originating UINode for this link. * @param toNode com.compendium.ui.UINode, the destination UINode for this link. * @param type, the link type for this link. */ public UILink(UINode fromNode, UINode toNode, String type) { setFont(ProjectCompendiumFrame.currentDefaultFont); // line coordinates will be absolute setCoordinateType(UILine.ABSOLUTE); // arrow will be pointing to to-node setArrow(ICoreConstants.ARROW_TO); // set minimum width to 12 to allow for display of rollover indicator setMinWidth(12); // set line color if (type.equals(ICoreConstants.DEFAULT_LINK)) setForeground(Color.gray); else if (type.equals(ICoreConstants.SUPPORTS_LINK)) setForeground(Color.green); else if (type.equals(ICoreConstants.OBJECTS_TO_LINK)) setForeground(Color.red); // set selected color; setSelectedColor(SELECTED_COLOR); // set the nodes that are linked with this link setFromNode(fromNode); setToNode(toNode); updateUI(); addFocusListener( new FocusListener() { public void focusGained(FocusEvent e) { repaint(); } public void focusLost(FocusEvent e) { ((LinkUI)getUI()).resetEditing(); repaint(); } }); } /** * Increase the font size displayed by one point. * This does not change the setting in the database. * @return the new size. */ public int increaseFontSize() { Font font = getFont(); int newSize = font.getSize()+1; Font newFont = new Font(font.getName(), font.getStyle(), font.getSize()+1); super.setFont(newFont); ((LinkUI)getUI()).getPreferredSize(this); repaint(10); return newSize; } /** * Decrease the font size displayed by one point. * This does not change the setting in the database. * @return the new size. */ public int decreaseFontSize() { Font font = getFont(); int newSize = font.getSize()-1; Font newFont = new Font(font.getName(), font.getStyle(), font.getSize()-1); super.setFont(newFont); ((LinkUI)getUI()).getPreferredSize(this); repaint(10); return newSize; } /** * Restore the font to the default settings. * */ public void setDefaultFont() { Font labelFont = new Font(oLinkProperties.getFontFace(), oLinkProperties.getFontStyle(), oLinkProperties.getFontSize()); setFont(labelFont); ((LinkUI)getUI()).getPreferredSize(this); repaint(10); } /** * Returns the text string that the link displays. * <p> * @return String, the text string that the link displays. * @see #setText */ public String getText() { return sText; } /** * Defines the label text this component will display. * <p> * @param text, the new text to display as the link label. */ public void setText(String text) { String oldValue = sText; try { if (oLink != null) { oLink.setLabel(text); sText = text; firePropertyChange(LABEL_PROPERTY, oldValue, sText); repaint(); } } catch(Exception io) { io.printStackTrace(); ProjectCompendium.APP.displayError("Error: (UILink.setText) "+LanguageProperties.getString(LanguageProperties.UI_GENERAL_BUNDLE, "UILink.unableToUpdateLabel")+"\n\n"+io.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } } /** * Returns the Link object. * @return Link. */ public Link getLink() { return oLink; } /** * Returns LinkProperties object associated with this link. * @return LinkProperties object associated with this link. */ public LinkProperties getLinkProperties() { return oLinkProperties; } /** * Notification from the UIFactory that the L&F has changed. * * @see JComponent#updateUI */ public void updateUI() { //setUI((LinkUI)UIManager.getUI(this)); setUI(new LinkUI()); invalidate(); } /** * Returns a string that specifies the name of the l&f class * that renders this component. * * @return String "LinkUI" * * @see JComponent#getUIClassID * @see UIDefaults#getUI */ public String getUIClassID() { return "LinkUI"; //$NON-NLS-1$ } /** * Return the originating UINode for this link. * @return com.compendium.ui.UINode, the originating UINode for this link. */ public UINode getFromNode() { return oFromNode; } /** * Set the originating node for this link. Fires a property change event. * @param node com.compendium.ui.UINode, the originating UINode for this link. */ public void setFromNode(UINode node) { UINode oldValue = oFromNode; oFromNode = node; firePropertyChange("fromnode", oldValue, oFromNode); //$NON-NLS-1$ updateConnectionPoints(); } /** * Return the destination UINode for this link. * @return com.compendium.ui.UINode, the destination UINode for this link. */ public UINode getToNode() { return oToNode; } /** * Set the destination node for this link. Fires a property change event. * @param node com.compendium.ui.UINode, the destination UINode for this link. */ public void setToNode(UINode node) { UINode oldValue = oToNode; oToNode = node; firePropertyChange("tonode", oldValue, oToNode); //$NON-NLS-1$ updateConnectionPoints(); } /** * Convenience method that searchs the anscestor heirarchy for a UIViewPane instance. * @return com.compendium.ui.UIViewPane, the parent pane for this link. */ public UIViewPane getViewPane() { Container p; // Search upward for viewpane p = getParent(); while (p != null && !(p instanceof UIViewPane)) p = p.getParent(); return (UIViewPane)p; } /** * Set the absolute from and to points for this link based on the position * of the from and to nodes. */ public void updateConnectionPoints() { UINode from = getFromNode(); UINode to = getToNode(); Rectangle rFrom = new Rectangle(); Rectangle rTo = new Rectangle(); if (from == null || to == null) return; // get the bounds for each node rFrom = from.getBounds(); rTo = to.getBounds(); // calculate the center for each node, used as basis for drawing line // between nodes. Point ptFromCenter = new Point(rFrom.x+(rFrom.width/2), rFrom.y+(rFrom.height/2)); Point ptToCenter = new Point(rTo.x+(rTo.width/2), rTo.y+(rTo.height/2)); // calculate the intersecting point between the bounds of the node and // the connecting line. We only want the line to draw to the boundary // of the node, not to the center of the node //log.info("PTS FROM " + rFrom + "," + ptFromCenter + "," + ptToCenter); //log.info("PTS TO " + rTo + "," + ptFromCenter + "," + ptToCenter); Point[] pts1 = UILine.intersectionWithRectangle(rFrom, ptFromCenter, ptToCenter); Point[] pts2 = UILine.intersectionWithRectangle(rTo, ptFromCenter, ptToCenter); //this is a patch. //if both the rectangles have the same center point, then this above //2 array of points has null. if ( (ptFromCenter.x == ptToCenter.x) && (ptFromCenter.y == ptToCenter.y) ) { if (rFrom.y > rTo.y) { pts1[0] = new Point(rFrom.x + rFrom.width, rFrom.y); pts1[1] = pts1[0]; pts2[0] = new Point(rTo.x + rTo.width, rFrom.y); pts2[1] = pts2[0]; } else { pts1[0] = new Point(rFrom.x + rFrom.width, rTo.y); pts1[1] = pts1[0]; pts2[0] = new Point(rTo.x + rTo.width, rTo.y); pts2[1] = pts2[0]; } } // figure out which points to use setFrom(getClosestPoint(pts1[0], pts1[1], ptToCenter)); setTo(getClosestPoint(pts2[0], pts2[1], ptFromCenter)); setBounds(getPreferredBounds()); // swing calls repaint from setBounds. } /** * Given two points and a center point, return the point closest to the * center point. * * @param p1, the first point to check. * @param p2, the second point to check. * @param cp, the centerpoint to check. * @return Point, the point closest to the center point. */ private Point getClosestPoint(Point p1, Point p2, Point cp) { if (p1 == null) return p2; if (p2 == null) return p1; double hypo1 = Math.sqrt((cp.x-p1.x)*(cp.x-p1.x)+(cp.y-p1.y)*(cp.y-p1.y)); double hypo2 = Math.sqrt((cp.x-p2.x)*(cp.x-p2.x)+(cp.y-p2.y)*(cp.y-p2.y)); if (hypo1 <= hypo2) return p1; else return p2; } /** * Open a popup menu for this link. * @param linkui, the ui instance to pass to the popup menu. * @param x, the x position for the popup menu. * @param y, the y position for this popup menu. */ public void showPopupMenu(LinkUI linkui, int x, int y) { String userID = ProjectCompendium.APP.getModel().getUserProfile().getId(); UILinkPopupMenu pop = new UILinkPopupMenu("Popup menu", linkui, userID); //$NON-NLS-1$ pop.setViewPane(getViewPane()); pop.show(this,x,y); } /** * Open a UILinkDialog instance on the contents tab. */ public void showEditDialog() { UILinkContentDialog dlg = new UILinkContentDialog(ProjectCompendium.APP, this, UILinkContentDialog.CONTENTS_TAB); UIUtilities.centerComponent(dlg, ProjectCompendium.APP); dlg.setVisible(true); } /** * Open a UILinkDialog instance on the properties tab. */ public void showPropertiesDialog() { UILinkContentDialog dlg = new UILinkContentDialog(ProjectCompendium.APP, this, UILinkContentDialog.PROPERTIES_TAB); UIUtilities.centerComponent(dlg, ProjectCompendium.APP); dlg.setVisible(true); } /** * Convenience method that moves this component to position 0 if it's * parent is a JLayeredPane. */ public void moveToFront() { if (getParent() != null && getParent() instanceof JLayeredPane) { JLayeredPane l = (JLayeredPane)getParent(); l.moveToFront(this); } } /** * Convenience method that moves this component to position -1 if it's * parent is a JLayeredPane. */ public void moveToBack() { if (getParent() != null && getParent() instanceof JLayeredPane) { JLayeredPane l = (JLayeredPane)getParent(); l.moveToBack(this); } } /** * Set the arrow head style for this link. * @param arrow, the arrow head style for this link. */ public void setArrow(int arrow) { super.setArrow(arrow); } /** * Update the arrow head style for this link. * @param arrow the arrow head style for this link. */ private void updateArrow(int arrow) { try { setArrow(arrow); double currentScale = this.getViewPane().getZoom(); AffineTransform trans=new AffineTransform(); trans.setToScale(currentScale, currentScale); scaleLink(trans); } catch(Exception ex) { ProjectCompendium.APP.displayError("Error: (UILink.updateArrow) "+LanguageProperties.getString(LanguageProperties.UI_GENERAL_BUNDLE, "UILink.unableToUpdateArrow")+"\n\n"+ex.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } } /** * Set the link type for this link. * @param type, the link type for this link. */ public void setLinkType(String type) { String oldValue = oLink.getType(); if (oldValue == type) { return; } try { oLink.setType(type); //update all LinkProperties to the ones for the chosen link type LinkProperties props = UIUtilities.getLinkProperties(type); UIViewPane pane = getViewPane(); try { View view = pane.getView(); if (view != null) { LinkProperties newProps = (LinkProperties)view.updateLinkFormatting(oLink.getId(), props); if (newProps != null) { setLinkProps(newProps); } else { log.info("Failed to update LinkProperties after set type due to newProps being null"); //$NON-NLS-1$ } } } catch (SQLException ex) { log.info("Failed to update LinkProperties after set type due to:"+ex.getMessage()); //$NON-NLS-1$ } firePropertyChange(TYPE_PROPERTY, oldValue, type); repaint(); } catch(Exception ex) { log.error("Error...", ex); ProjectCompendium.APP.displayError("Error: (UILink.setLinkType) "+LanguageProperties.getString(LanguageProperties.UI_GENERAL_BUNDLE, "UILink.unableToUpdateLink")+"\n\n"+ex.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } } /** * Get the link type for this link. * @return String, the link type for this link. */ public String getLinkType() { return oLink.getType(); } /** * Returns the Link type for the given link type description * @param type, the link type description to return the link type for. * @param int, the link type assoicated with the given description. */ public static String getLinkType(String type) { String linkType = ""; //$NON-NLS-1$ if(type.equals(UILink.sRESPONDSTOLINK)) { linkType = ICoreConstants.RESPONDS_TO_LINK; } else if(type.equals(UILink.sSUPPORTSLINK)) { linkType = ICoreConstants.SUPPORTS_LINK; } else if(type.equals(UILink.sOBJECTSTOLINK)) { linkType = ICoreConstants.OBJECTS_TO_LINK; } else if(type.equals(UILink.sCHALLENGESLINK)) { linkType = ICoreConstants.CHALLENGES_LINK; } else if(type.equals(UILink.sSPECIALIZESLINK)) { linkType = ICoreConstants.SPECIALIZES_LINK; } else if(type.equals(UILink.sEXPANDSONLINK)) { linkType = ICoreConstants.EXPANDS_ON_LINK; } else if(type.equals(UILink.sRELATEDTOLINK)) { linkType = ICoreConstants.RELATED_TO_LINK; } else if(type.equals(UILink.sABOUTLINK)) { linkType = ICoreConstants.ABOUT_LINK; } else if(type.equals(UILink.sRESOLVESLINK)) { linkType = ICoreConstants.RESOLVES_LINK; } else { linkType = ICoreConstants.DEFAULT_LINK; } return linkType; } /** * Get the link type description for the given link type. * @param type, the link type to return the description for. * @return String, the description for the given link type. */ /* public static String getLinkTypeName(String type) { String linkType = ""; Color linkColor = null; UILinkType oLinktype = ProjectCompendium.APP.oLinkGroupManager.getLinkType(type); if (oLinktype == null) { int nType = 0; try { nType = new Integer(type).intValue(); catch(NumberFormatException ex) { nType = -1; } switch (nType) { case ICoreConstants.RESPONDS_TO_LINK: { linkType = ICoreConstants.sRESPONDSTOLINK; break; } case ICoreConstants.SUPPORTS_LINK: { linkType = ICoreConstants.sSUPPORTSLINK; break; } case ICoreConstants.OBJECTS_TO_LINK: { linkType = ICoreConstants.sOBJECTSTOLINK; break; } case ICoreConstants.CHALLENGES_LINK: { linkType = ICoreConstants.sCHALLENGESLINK; break; } case ICoreConstants.SPECIALIZES_LINK: { linkType = ICoreConstants.sSPECIALIZESLINK; break; } case ICoreConstants.EXPANDS_ON_LINK: { linkType = ICoreConstants.sEXPANDSONLINK; break; } case ICoreConstants.RELATED_TO_LINK: { linkType = ICoreConstants.sRELATEDTOLINK; break; } case ICoreConstants.ABOUT_LINK: { linkType = ICoreConstants.sABOUTLINK; break; } case ICoreConstants.RESOLVES_LINK: { linkType = ICoreConstants.sRESOLVESLINK; break; } default : { linkType = ICoreConstants.sDEFAULTLINK; break; } } } else { return oLinktype.getName(); } return linkType; } */ /** * Get the link type label for the given link type. * @param type, the link type to return the description for. * @return String, the description for the given link type. */ public static String getLinkTypeLabel(String type) { UILinkType oLinktype = ProjectCompendium.APP.oLinkGroupManager.getLinkType(type); String linkType = ""; //$NON-NLS-1$ if (oLinktype == null) { if (type.equals(ICoreConstants.RESPONDS_TO_LINK)) linkType = UILink.sRESPONDSTOLINKLABEL; else if (type.equals(ICoreConstants.SUPPORTS_LINK)) linkType = UILink.sSUPPORTSLINKLABEL; else if (type.equals(ICoreConstants.OBJECTS_TO_LINK)) linkType = UILink.sOBJECTSTOLINKLABEL; else if (type.equals(ICoreConstants.CHALLENGES_LINK)) linkType = UILink.sCHALLENGESLINKLABEL; else if (type.equals(ICoreConstants.SPECIALIZES_LINK)) linkType = UILink.sSPECIALIZESLINKLABEL; else if (type.equals(ICoreConstants.EXPANDS_ON_LINK)) linkType = UILink.sEXPANDSONLINKLABEL; else if (type.equals(ICoreConstants.RELATED_TO_LINK)) linkType = UILink.sRELATEDTOLINKLABEL; else if (type.equals(ICoreConstants.ABOUT_LINK)) linkType = UILink.sABOUTLINKLABEL; else if (type.equals(ICoreConstants.RESOLVES_LINK)) linkType = UILink.sRESOLVESLINKLABEL; else linkType = LanguageProperties.getString(LanguageProperties.UI_GENERAL_BUNDLE, "UILink.unknown"); //$NON-NLS-1$ } else { return oLinktype.getName(); } return linkType; } /** * Get the link color based on its type. * @param type, the link type to return the color for. * @return Color, the color for the given link type. */ public static Color getLinkColor(String type) { Color linkColor = null; UILinkType oLinktype = ProjectCompendium.APP.oLinkGroupManager.getLinkType(type); if (oLinktype == null) { if (type.equals(ICoreConstants.RESPONDS_TO_LINK)) linkColor = Color.magenta; else if (type.equals(ICoreConstants.SUPPORTS_LINK)) linkColor = Color.green; else if (type.equals(ICoreConstants.OBJECTS_TO_LINK)) linkColor = Color.red; else if (type.equals(ICoreConstants.CHALLENGES_LINK)) linkColor = Color.pink; else if (type.equals(ICoreConstants.SPECIALIZES_LINK)) linkColor = Color.blue; else if (type.equals(ICoreConstants.EXPANDS_ON_LINK)) linkColor = Color.orange; else if (type.equals(ICoreConstants.RELATED_TO_LINK)) linkColor = Color.black; else if (type.equals(ICoreConstants.ABOUT_LINK)) linkColor = Color.cyan; else if (type.equals(ICoreConstants.RESOLVES_LINK)) linkColor = Color.gray; else linkColor = Color.black; } else linkColor = oLinktype.getColour(); return linkColor; } /** * Toggle selection. */ public void controlClick() { if(this.isSelected()) { //deselect from the group setSelected(false); getViewPane().removeLink(this); } else { //select and add to the group setSelected(true); getViewPane().setSelectedLink(this,ICoreConstants.MULTISELECT); moveToFront(); } } /** * Scale the arrow and line thickness with with the given transform. * @param trans, the transform to use when scaling. */ public void scaleLink(AffineTransform trans) { if (trans == null) { nCurrentArrowWidth = nArrowWidth; nCurrentThickness = nThickness; } else { Point p1 = new Point(nArrowWidth, nArrowWidth); try { p1 = (Point)trans.transform(p1, new Point(0, 0)); } catch(Exception e) { log.info("can't convert arrow width\n\n"+e.getMessage()); //$NON-NLS-1$ } if (p1.x < 7) p1.x = p1.x+1; nCurrentArrowWidth = p1.x; Point p2 = new Point(nThickness, nThickness); try { p2 = (Point)trans.transform(p2, new Point(0, 0)); } catch(Exception e) { log.info("can't convert line thickness\n\n"+e.getMessage()); //$NON-NLS-1$ } if (p2.x < 1) p2.x = 1; nCurrentThickness = p2.x; } } /** * Sets the font used to display the link's text. * * @param font The font to use. */ public void setFont(Font font) { super.setFont(font); ((LinkUI)getUI()).refreshBounds(); } /** * Handle a PropertyChangeEvent. * @param evt, the associated PropertyChangeEvent to handle. */ public void propertyChange(PropertyChangeEvent evt) { String prop = evt.getPropertyName(); Object newvalue = evt.getNewValue(); if (prop.equals(Link.LABEL_PROPERTY)) { setText((String)evt.getNewValue()); } else if (prop.equals(Link.TYPE_PROPERTY)) { setLinkType( (String)evt.getNewValue() ); } else if (prop.equals(LinkProperties.FONTFACE_PROPERTY)) { Font font = getFont(); Font newFont = new Font((String)newvalue, font.getStyle(), font.getSize()); setFont(newFont); } else if (prop.equals(LinkProperties.FONTSTYLE_PROPERTY)) { Font font = getFont(); Font newFont = new Font(font.getName(), ((Integer)newvalue).intValue(), font.getSize()); setFont(newFont); } else if (prop.equals(LinkProperties.FONTSIZE_PROPERTY)) { Font font = getFont(); int newsize = ((Integer)newvalue).intValue(); Font newFont = new Font(font.getName(), font.getStyle(), newsize); setFont(newFont); //scales int adjustment = ProjectCompendium.APP.getToolBarManager().getTextZoom(); font = getFont(); Font adjustedFont = new Font(font.getName(), font.getStyle(), font.getSize()+adjustment); super.setFont(adjustedFont); } else if (prop.equals(LinkProperties.TEXT_FOREGROUND_PROPERTY)) { ((LinkUI)getUI()).refreshBounds(); } else if (prop.equals(LinkProperties.TEXT_BACKGROUND_PROPERTY)) { ((LinkUI)getUI()).refreshBounds(); } else if (prop.equals(LinkProperties.WRAP_WIDTH_PROPERTY)) { ((LinkUI)getUI()).refreshBounds(); } else if (prop.equals(LinkProperties.ARROWTYPE_PROPERTY)) { updateArrow( ((Integer)evt.getNewValue()).intValue() ); ((LinkUI)getUI()).refreshBounds(); } else if (prop.equals(LinkProperties.LINKDASHED_PROPERTY)) { ((LinkUI)getUI()).refreshBounds(); } else if (prop.equals(LinkProperties.LINKSTYLE_PROPERTY)) { ((LinkUI)getUI()).refreshBounds(); } else if (prop.equals(LinkProperties.LINKCOLOUR_PROPERTY)) { setForeground(new Color(oLinkProperties.getLinkColour())); if ((LinkUI)getUI() != null) { ((LinkUI)getUI()).refreshBounds(); } } else if (prop.equals(LinkProperties.LINKWEIGHT_PROPERTY)) { setLineThickness(oLinkProperties.getLinkWeight()); double currentScale = this.getViewPane().getZoom(); AffineTransform trans=new AffineTransform(); trans.setToScale(currentScale, currentScale); scaleLink(trans); ((LinkUI)getUI()).refreshBounds(); } repaint(); } }