1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
| public class OrthogonalFrame extends JPanel {
private final int horizontalIncrement;
private final int verticalIncrement;
private final int strokeLength;
private final Set<Point> points = new HashSet<>(); // pour stocker les points
private Color pointColor;
public OrthogonalFrame(int increment) {
this(increment, 2);
}
public OrthogonalFrame(int increment, int strokeLength) {
this(increment, increment, strokeLength);
}
public OrthogonalFrame(int horizontalIncrement, int verticalIncrement, int strokeLength) {
this.horizontalIncrement=Math.max(0,horizontalIncrement); // le max empêche d'avoir des valeurs négatives
this.verticalIncrement=Math.max(0,verticalIncrement);
this.strokeLength=Math.max(0,strokeLength);
}
public void addPoint(int x, int y) {
Point point = createPoint(x, y);
if ( points.add(point) ) {
repaint();
}
}
public void removePoint(int x, int y) {
removePoint( createPoint(x,y) );
}
public void removePoint(Point point) {
if ( points.remove(point) ) {
repaint();
}
}
public boolean containsPoint(int x, int y) {
final Point point = createPoint(x,y);
return points.contains(point);
}
public Optional<Point> getNearestPoint(int x, int y, double dist) {
final Point fpoint = createPoint(x,y);
for(Point point : points) {
if ( point.distance(fpoint)<dist ) {
return Optional.of(point);
}
}
return Optional.empty();
}
private Point createPoint(int x, int y) {
return new Point(x-getWidth()/2,y-getHeight()/2);
}
public void setPointColor(Color color) {
this.pointColor=color;
repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
final int width = getWidth()/2;
final int height = getHeight()/2;
// on translate au centre pour simplifier
g.translate(width, height);
// on dessine les axes
g.setColor(getForeground());
g.drawLine(-width, 0, width, 0);
g.drawLine(0, -height, 0, height);
// on dessine les incréemnts si nécessaire
if( strokeLength>0 ) {
if ( horizontalIncrement>0 ) {
for(int i=0; i<width; i+=horizontalIncrement) {
g.drawLine(i, -strokeLength, i, strokeLength);
g.drawLine(-i, -strokeLength, -i, strokeLength);
}
}
if ( verticalIncrement>0 ) {
for(int i=0; i<height; i+=verticalIncrement) {
g.drawLine(-strokeLength, i, strokeLength, i);
g.drawLine(-strokeLength, -i, strokeLength, -i);
}
}
}
// on dessine les points
if ( pointColor!=null ) {
g.setColor(pointColor);
}
for(Point point : points) {
dessinePoint(g, point.x, point.y, strokeLength);
}
}
/**
* On peut redéfinir cette méthode pour changer la forme du point
* @param x
* @param y
* @param strokeLength
*/
protected void dessinePoint(Graphics g, final int x, final int y, final int strokeLength) {
final int strokeLength2 = strokeLength*2;
final int minx=x-strokeLength2;
final int maxx=x+strokeLength2;
final int miny=y-strokeLength2;
final int maxy=y+strokeLength2;
// dessin en croix
g.drawLine(minx, miny, maxx, maxy);
g.drawLine(minx, maxy, maxx, miny);
}
public static void main(String[] args) {
JFrame frame = new JFrame("Démo");
final OrthogonalFrame repere = new OrthogonalFrame(25, 2);
repere.setBackground(Color.BLACK);
repere.setForeground(Color.WHITE);
repere.setPointColor(Color.YELLOW);
frame.add( repere );
repere.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if ( (e.getModifiersEx() & InputEvent.CTRL_DOWN_MASK) != 0 ) {
// ctrl-clic pour effacer
repere.getNearestPoint(e.getX(), e.getY(),3).ifPresent(p-> repere.removePoint(p));
}
else {
repere.addPoint(e.getX(), e.getY());
}
}
});
frame.setSize(600, 400);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
} |