Clover coverage report - Maven Clover report
Coverage timestamp: Thu Oct 11 2007 08:41:48 CEST
file stats: LOC: 438   Methods: 27
NCLOC: 371   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
LinkItem.java 66.7% 83.3% 88.9% 80.3%
coverage coverage
 1    /*
 2    * Copyright (C) 2007 Eric MIGNOT - mignots.eric@free.fr
 3    *
 4    * This library is free software; you can redistribute it and/or
 5    * modify it under the terms of the GNU Lesser General Public
 6    * License as published by the Free Software Foundation; either
 7    * version 2.1 of the License, or (at your option) any later version.
 8    *
 9    * This library is distributed in the hope that it will be useful,
 10    * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 12    * Lesser General Public License for more details.
 13    *
 14    * You should have received a copy of the GNU Lesser General Public
 15    * License along with this library; if not, write to the Free Software
 16    * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 17    */
 18    package org.ericmignot.modeler.gui.workarea;
 19   
 20    import java.awt.Color;
 21    import java.awt.Dimension;
 22    import java.awt.Font;
 23    import java.awt.Graphics;
 24    import java.awt.Graphics2D;
 25    import java.awt.GridLayout;
 26    import java.awt.Point;
 27    import java.awt.Rectangle;
 28    import java.awt.RenderingHints;
 29   
 30    import javax.swing.JLabel;
 31    import javax.swing.JPanel;
 32    import javax.swing.SwingConstants;
 33   
 34    import org.ericmignot.modeler.action.DeleteAction;
 35    import org.ericmignot.modeler.data.BusinessObject;
 36    import org.ericmignot.modeler.data.Link;
 37    import org.ericmignot.modeler.data.SimplePoint;
 38    import org.ericmignot.modeler.gui.Controller;
 39    import org.ericmignot.modeler.gui.StaticValues;
 40    import org.ericmignot.modeler.gui.palette.LinkUpdatePanel;
 41    import org.ericmignot.modeler.gui.palette.UpdatePanel;
 42    import org.ericmignot.modeler.util.action.NotifyableAction;
 43    import org.ericmignot.modeler.util.graphic.GraphicHelper;
 44    import org.ericmignot.modeler.util.graphic.RoundedLineBorder;
 45   
 46    public class LinkItem extends Item implements Deletable, Updatable
 47    {
 48    protected JPanel infoPanel;
 49    protected JLabel linkLabel;
 50    protected Font font;
 51   
 52    private Item linkStart;
 53    private Item linkEnd;
 54    private ExtremityStrategy extremityStrategy;
 55   
 56  94 public LinkItem()
 57    {
 58  94 this.setOpaque(false);
 59  94 this.setLayout(null);
 60  94 this.setExtremityStrategy(new DefaultExtremityStrategy());
 61   
 62  94 this.infoPanel = new JPanel();
 63  94 this.infoPanel.setLayout(new GridLayout(0, 1));
 64  94 this.infoPanel.setOpaque(true);
 65  94 this.infoPanel.setSize(0, 0);
 66  94 this.infoPanel.setBackground(GraphicHelper.buildColor(StaticValues.getInstance().get("Design.Link.BackgroundColor", "236, 233, 216")));
 67   
 68  94 this.linkLabel = new JLabel();
 69  94 this.linkLabel.setText(null);
 70  94 this.linkLabel.setHorizontalAlignment(SwingConstants.CENTER);
 71  94 this.infoPanel.add(this.linkLabel);
 72   
 73  94 this.add(this.infoPanel);
 74    }
 75   
 76  346 public Link getLink()
 77    {
 78  346 return (Link) this.getBusinessObject();
 79    }
 80   
 81  0 public JPanel getInfoPanel()
 82    {
 83  0 return this.infoPanel;
 84    }
 85  2 public ExtremityStrategy getExtremityStrategy()
 86    {
 87  2 return extremityStrategy;
 88    }
 89   
 90  312 public void setExtremityStrategy(ExtremityStrategy extremityStrategy)
 91    {
 92  312 this.extremityStrategy = extremityStrategy;
 93    }
 94  4697 public Item getLinkEnd()
 95    {
 96  4697 return linkEnd;
 97    }
 98   
 99  103 public void setLinkEnd(Item linkEnd)
 100    {
 101  103 if (this.linkEnd != null)
 102    {
 103  10 this.linkEnd.getBusinessObject().removeListener(this);
 104    }
 105  103 this.linkEnd = linkEnd;
 106  103 linkEnd.getBusinessObject().addListener(this);
 107  103 if (this.getLink() != null)
 108    {
 109  79 this.setExtremityStrategy(new ExtremityFactory().buildExtremityStrategy(this.getLink()));
 110    }
 111    }
 112   
 113  4588 public Item getLinkStart()
 114    {
 115  4588 return linkStart;
 116    }
 117   
 118  94 public void setLinkStart(Item linkStart)
 119    {
 120  94 if (this.linkStart != null)
 121    {
 122  1 this.linkStart.getBusinessObject().removeListener(this);
 123    }
 124  94 this.linkStart = linkStart;
 125  94 linkStart.getBusinessObject().addListener(this);
 126  94 if (this.getLink() != null)
 127    {
 128  70 this.setExtremityStrategy(new ExtremityFactory().buildExtremityStrategy(this.getLink()));
 129    }
 130    }
 131   
 132  93 public void doLayout()
 133    {
 134  93 this.updateInfoPanelLocation();
 135  93 super.doLayout();
 136    }
 137   
 138  271 public Point getZoomedLocation(double zoomFactor)
 139    {
 140  271 Point startCenter = this.getLinkStart().getBusinessObject().getCenter();
 141  271 Dimension startHalfSize = this.getLinkStart().getBusinessObject().getHalfSize();
 142  271 Point endCenter = this.getLinkEnd().getBusinessObject().getCenter();
 143  271 Dimension endHalfSize = this.getLinkEnd().getBusinessObject().getHalfSize();
 144   
 145  271 int x = Math.min(startCenter.x-startHalfSize.width, endCenter.x-endHalfSize.width);
 146  271 int y = Math.min(startCenter.y-startHalfSize.height, endCenter.y-endHalfSize.height);
 147   
 148  271 Point coreZoomedLocation = new Point((int) (x * zoomFactor), (int) (y * zoomFactor));
 149   
 150  271 Dimension coreZoomedSize = this.getCoreZoomedSize(zoomFactor);
 151  271 Dimension zoomedSize = this.getZoomedSize(zoomFactor);
 152  271 int deltaX = 0;
 153  271 if (zoomedSize.width > coreZoomedSize.width)
 154    {
 155  0 deltaX = (zoomedSize.width - coreZoomedSize.width) /2;
 156    }
 157  271 int deltaY = 0;
 158  271 if (zoomedSize.height > coreZoomedSize.height)
 159    {
 160  0 deltaY = (zoomedSize.height - coreZoomedSize.height) /2;
 161    }
 162  271 Point toReturn = new Point(
 163    coreZoomedLocation.x - deltaX,
 164    coreZoomedLocation.y - deltaY
 165    );
 166  271 return toReturn;
 167    }
 168   
 169  542 public Dimension getZoomedSize(double zoomFactor)
 170    {
 171  542 Dimension coreSize = getCoreZoomedSize(zoomFactor);
 172   
 173  542 Dimension infoPanelSize = this.infoPanel.getSize();
 174  542 Dimension toReturn = new Dimension(
 175    Math.max(coreSize.width, infoPanelSize.width),
 176    Math.max(coreSize.height, infoPanelSize.height)
 177    );
 178  542 return toReturn;
 179    }
 180   
 181  813 private Dimension getCoreZoomedSize(double zoomFactor)
 182    {
 183  813 Point startCenter = this.getLinkStart().getBusinessObject().getCenter();
 184  813 Dimension startHalfSize = this.getLinkStart().getBusinessObject().getHalfSize();
 185  813 Point endCenter = this.getLinkEnd().getBusinessObject().getCenter();
 186  813 Dimension endHalfSize = this.getLinkEnd().getBusinessObject().getHalfSize();
 187   
 188  813 int minx = Math.min(startCenter.x-startHalfSize.width, endCenter.x-endHalfSize.width);
 189  813 int miny = Math.min(startCenter.y-startHalfSize.height, endCenter.y-endHalfSize.height);
 190  813 int maxx = Math.max(startCenter.x+startHalfSize.width, endCenter.x+endHalfSize.width);
 191  813 int maxy = Math.max(startCenter.y+startHalfSize.height, endCenter.y+endHalfSize.height);
 192   
 193  813 Dimension coreSize = new Dimension((int) (zoomFactor*(maxx-minx)), (int) (zoomFactor*(maxy-miny)));
 194  813 return coreSize;
 195    }
 196   
 197  93 public Font buildZoomedFont()
 198    {
 199  93 int nominalSize = Integer.parseInt(StaticValues.getInstance().get("Design.Link.PoliceSize", "12"));
 200  93 int fontSize = (int) (nominalSize * this.getWorkArea().getZoomFactor());
 201   
 202  93 String fontName = StaticValues.getInstance().get("Design.Link.PoliceName", "Arial");
 203  93 Font font = new Font(fontName, Font.PLAIN, fontSize);
 204  93 return font;
 205    }
 206   
 207   
 208  338 protected void updateInfoPanelLocation()
 209    {
 210  338 Point startExtremity = this.extremityStrategy.getStartExtremity(this);
 211  338 Point endExtremity = this.extremityStrategy.getEndExtremity(this);
 212  338 Point panelCenter;
 213  338 if (startExtremity==null || endExtremity==null)
 214    {
 215  174 panelCenter = GraphicHelper.getPanelCenter(this);
 216    }
 217    else
 218    {
 219  164 panelCenter = new Point((startExtremity.x+endExtremity.x)/2,
 220    (startExtremity.y+endExtremity.y)/2);
 221    }
 222  338 Dimension size = this.infoPanel.getSize();
 223  338 this.infoPanel.setLocation(panelCenter.x-size.width/2-this.getX(),
 224    panelCenter.y-size.height/2-this.getY());
 225    }
 226   
 227  93 public void zoomChanged()
 228    {
 229  93 this.font = this.buildZoomedFont();
 230  93 this.linkLabel.setFont(this.font);
 231   
 232  93 this.infoPanel.setSize(this.infoPanel.getPreferredSize());
 233  93 this.updateInfoPanelLocation();
 234  93 repaint();
 235    }
 236   
 237  104 protected void adjustExtremitiesFromLink(Link link)
 238    {
 239  104 if (this.getLinkStart()!= null
 240    && link.getLinkStart() != this.getLinkStart().getBusinessObject())
 241    {
 242  1 Item newStartItem = this.getWorkArea().getItemByBusinessObject(link.getLinkStart());
 243  1 this.setLinkStart(newStartItem);
 244    }
 245  104 if (this.getLinkEnd()!= null
 246    && link.getLinkEnd() != this.getLinkEnd().getBusinessObject())
 247    {
 248  10 Item newEndItem = this.getWorkArea().getItemByBusinessObject(link.getLinkEnd());
 249  10 this.setLinkEnd(newEndItem);
 250    }
 251    }
 252   
 253  152 public void businessObjectUpdatedImpl(BusinessObject businessObject)
 254    {
 255  152 if (businessObject instanceof Link)
 256    {
 257  104 Link link = (Link) businessObject;
 258  104 this.adjustExtremitiesFromLink(link);
 259   
 260  104 if (link.getLabel()!=null)
 261    {
 262  0 this.linkLabel.setText(" " + link.getLabel() + " ");
 263    }
 264    else
 265    {
 266  104 this.linkLabel.setText(null);
 267    }
 268  104 if (link.getLabel()==null)
 269    {
 270  104 this.infoPanel.setSize(0, 0);
 271  104 this.infoPanel.setBorder(null);
 272    }
 273    else
 274    {
 275  0 this.infoPanel.setSize(this.infoPanel.getPreferredSize());
 276  0 this.infoPanel.setBorder(new RoundedLineBorder(GraphicHelper.buildColor(StaticValues.getInstance().get("Design.Transition.ForegroundColor", "0, 0, 0"))));
 277    }
 278    }
 279  152 this.updateInfoPanelLocation();
 280  152 this.repaint();
 281    }
 282   
 283  3 public boolean isLinkVisible()
 284    {
 285  0 if (this.getLinkStart()==null || this.getLinkEnd()==null) return false;
 286   
 287  3 Rectangle startBounds = this.getLinkStart().getBounds();
 288  3 Rectangle endBounds = this.getLinkEnd().getBounds();
 289  3 return !startBounds.intersects(endBounds);
 290    }
 291   
 292  384 public Point getStartCenterInterEndItem()
 293    {
 294  384 if (this.getLinkEnd()==null || this.getLinkStart()==null)
 295    {
 296  69 return null;
 297    }
 298  315 Point startCenter = null;
 299  315 if (this.getLinkStart() instanceof Linkable)
 300    {
 301  315 startCenter = ((Linkable) this.getLinkStart()).getLinkTarget();
 302    }
 303  315 Point endCenter = null;
 304  315 if (this.getLinkEnd() instanceof Linkable)
 305    {
 306  315 endCenter = ((Linkable) this.getLinkEnd()).getLinkTarget();
 307    }
 308  315 return GraphicHelper.getLineRectangleIntersection(
 309    startCenter,
 310    endCenter,
 311    this.getLinkEnd().getBounds()
 312    );
 313    }
 314  378 public Point getEndCenterInterStartItem()
 315    {
 316  378 if (this.getLinkEnd()==null || this.getLinkStart()==null)
 317    {
 318  69 return null;
 319    }
 320  309 Point startCenter = null;
 321  309 if (this.getLinkStart() instanceof Linkable)
 322    {
 323  309 startCenter = ((Linkable) this.getLinkStart()).getLinkTarget();
 324    }
 325  309 Point endCenter = null;
 326  309 if (this.getLinkEnd() instanceof Linkable)
 327    {
 328  309 endCenter = ((Linkable) this.getLinkEnd()).getLinkTarget();
 329    }
 330  309 return GraphicHelper.getLineRectangleIntersection(
 331    endCenter,
 332    startCenter,
 333    this.getLinkStart().getBounds()
 334    );
 335    }
 336   
 337  0 public void paintComponent(Graphics g)
 338    {
 339  0 if (isLinkVisible())
 340    {
 341  0 Point location = getLocation();
 342  0 g.translate(-location.x, -location.y);
 343  0 Color oldColor= g.getColor();
 344  0 g.setColor(GraphicHelper.buildColor(StaticValues.getInstance().get("Design.Link.ForegroundColor", "0, 0, 0")));
 345   
 346  0 Graphics2D g2d = (Graphics2D) g;
 347  0 g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
 348   
 349  0 Point startExtremity = this.extremityStrategy.getStartExtremity(this);
 350  0 Point endExtremity = this.extremityStrategy.getEndExtremity(this);
 351  0 if (endExtremity!=null && startExtremity!=null)
 352    {
 353  0 g.drawLine(startExtremity.x, startExtremity.y, endExtremity.x, endExtremity.y);
 354  0 if (this.extremityStrategy.shouldDrawArrow())
 355    {
 356  0 GraphicHelper.drawArrow(g, startExtremity, endExtremity, this.getWorkArea().getZoomFactor());
 357    }
 358    }
 359   
 360  0 g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_DEFAULT);
 361  0 g.setColor(oldColor);
 362  0 g.translate(location.x, location.y);
 363   
 364  0 super.paintChildren(g);
 365    }
 366    }
 367   
 368  67 public boolean acceptPointForUserInteraction(int x, int y)
 369    {
 370  67 int gap = 2;
 371   
 372  67 Point s = getStartCenterInterEndItem();
 373  67 Point e = getEndCenterInterStartItem();
 374  67 double d = GraphicHelper.getLineDistance(e, s, new Point(x, y));
 375   
 376  67 int minX = Math.min(s.x, e.x);
 377  67 int minY = Math.min(s.y, e.y);
 378  67 int maxX = Math.max(s.x, e.x);
 379  67 int maxY = Math.max(s.y, e.y);
 380  67 boolean beetween = false;
 381  67 if (maxX-minX > gap)
 382    {
 383  67 beetween = (x>=minX && x<=maxX);
 384    }
 385    else
 386    {
 387  0 beetween = (y>=minY && y<=maxY);
 388    }
 389  67 boolean interactionOnLine = (d>= 0 && d <= gap && beetween);
 390  67 if (interactionOnLine)
 391    {
 392  24 return true;
 393    }
 394    else
 395    {
 396  43 Rectangle bounds = this.infoPanel.getBounds();
 397  43 if (bounds.contains(x-this.getX(), y-this.getY()))
 398    {
 399  0 return true;
 400    }
 401    else
 402    {
 403  43 return false;
 404    }
 405    }
 406    }
 407   
 408  33 public boolean acceptDelete(int x, int y)
 409    {
 410  33 if (this.getLinkStart().getBusinessObject() instanceof SimplePoint
 411    || this.getLinkEnd().getBusinessObject() instanceof SimplePoint
 412    )
 413    {
 414  1 return false;
 415    }
 416  32 return this.acceptPointForUserInteraction(x, y);
 417    }
 418   
 419  29 public boolean acceptUpdate(int x, int y)
 420    {
 421  29 if (this.getLinkStart().getBusinessObject() instanceof SimplePoint)
 422    {
 423  0 return false;
 424    }
 425  29 return this.acceptPointForUserInteraction(x, y);
 426    }
 427  0 public UpdatePanel createUpdatePanel()
 428    {
 429  0 return new LinkUpdatePanel();
 430    }
 431   
 432  2 public NotifyableAction buildDeleteAction(BusinessObject target, Controller controller)
 433    {
 434  2 return new DeleteAction(target, controller.getModel());
 435    }
 436   
 437   
 438    }