package bluej.pkgmgr;

import java.util.Comparator;

import bluej.pkgmgr.dependency.*;
import bluej.pkgmgr.target.*;
import threadchecker.OnThread;
import threadchecker.Tag;


| An ordering on targets to make layout nicer (reduce line intersections, etc.). This | class defines an ordering between any two Dependency objects "A" and "B", relative |* to a third "central" Dependency. The ordering determines the relative position of * each dependency line as it enters the side (top, left, bottom, right) of the central * Dependency. * * <p>The area around the central dependency is divided into 4 quadrants: | | <pre> | 0 | 1 | ----[+]---- | 2 | 3 | </pre> | | If the two dependencies being compared, A and B, are in different quadrants qA and qB, | then A < B iff qA < qB and vice versa. On the other hand if qA == qB then the ordering | depends on whether we are drawing lines in to the central Dependency or out of it | ("in" lines come into either side of the Target, "out" lines go from the top or bottom; |* in either case the line goes into the edge which is closest to the target from which it * is drawn, and the ordering is only important between dependencies into/out of the same | edge). | | So, if qA == qB, then: | For "in" dependencies, A < B if Ax < Bx and vice versa;<br> |* For "out" dependencies, A < B if Ay < By and vice versa.<br> * However, for quadrant 0 and 3 the ordering is reversed; because arrow lines drawn * to/from quadrants 0 and 3 turn the opposite way to those in adjacent quadrants | (1 and 2), the order must change to avoid those lines from crossing. | | @author Michael Cahill | @OnThread(Tag.FXPlatform) public class LayoutComparer implements Comparator<Dependency>{ DependentTarget centre; boolean in; public LayoutComparer(DependentTarget centre, boolean in) { this.centre = centre; this.in = in; }
| Order <a> and <b> depending on their relative positions | and their positions relative to the centre | | Note: this is designed to reduce intersections when drawing lines. | @Override @OnThread(value = Tag.FXPlatform, ignoreParent = true) public int compare(Dependency a, Dependency b) { DependentTarget ta = in ? a.getFrom() : a.getTo(); DependentTarget tb = in ? b.getFrom() : b.getTo(); int ax = ta.getX() + ta.getWidth()/2; int ay = ta.getY() + ta.getHeight()/2; int bx = tb.getX() + tb.getWidth()/2; int by = tb.getY() + tb.getHeight()/2; if ((ax == bx) && (ay == by)) return 0; int cx = centre.getX() + centre.getWidth()/2; int cy = centre.getY() + centre.getHeight()/2; return compare(ax, ay, bx, by, cx, cy); }
| Separate method to allow testing: | protected int compare(int ax, int ay, int bx, int by, int cx, int cy) { if ((ax == bx) && (ay == by)) return 0; boolean a_above = (ay < cy); boolean a_left = (ax < cx); int a_quad = (a_above ? 0 : 2) + (a_left ? 0 : 1); boolean b_above = (by < cy); boolean b_left = (bx < cx); int b_quad = (b_above ? 0 : 2) + (b_left ? 0 : 1); if (a_quad != b_quad) return (a_quad > b_quad) ? 1 : -1; int result = in ? compareInt(ax,bx) : compareInt(ay, by); return (a_above == a_left) ? -result : result; }
| Compare two integers and return a result indicating that the first is less than (-1), | equal to (0) or greater than (1) the second. | private int compareInt(int a, int b) { if (a == b) { return 0; } return (a < b) ? -1 : 1; } }

.   LayoutComparer
.   compare
.   compare
.   compareInt




86 neLoCode + 23 LoComm