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 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
| public class GridMagDrawDemo extends JPanel {
private final List<Line2D> lines; // pour stocker les lignes dessinées
private final Rectangle size; // la taille de la zone à dessiner (qui englobe toutes les lignes)
private final int hGridStep; // le pas horizontal de la grille
private final int vGridStep; // le pas vertical de la grille
private Point point; // le point correspondant à la souris
private Line2D line; // le ligne en cours de dessin
private Rectangle tmpsize;
public GridMagDrawDemo(int hGridStep, int vGridStep) {
super(true);
lines=new ArrayList<Line2D>();
size=new Rectangle();
this.hGridStep=hGridStep;
this.vGridStep=vGridStep;
setBackground(Color.BLACK);
// pour gérer l'interactivité
MouseAdapter mouseListener = new MouseAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
point = magnetize(e.getPoint());
repaint();
}
@Override
public void mouseExited(MouseEvent e) {
point = null;
repaint();
}
@Override
public void mousePressed(MouseEvent e) {
line = new Line2D.Double(point, point);
repaint();
}
@Override
public void mouseDragged(MouseEvent e) {
line.setLine(line.getP1(), magnetize(e.getPoint()));
tmpsize = new Rectangle(size);
updateSize(line, tmpsize);
revalidate();
repaint();
}
@Override
public void mouseReleased(MouseEvent e) {
if ( line!=null ) {
if ( !line.getP1().equals(line.getP2()) ) {
lines.add(line);
updateSize(line, size);
}
line=null;
tmpsize=null;
repaint();
}
}
};
addMouseListener(mouseListener);
addMouseMotionListener(mouseListener);
}
private void updateSize(Line2D line, Rectangle size) {
Rectangle bounds = line.getBounds();
bounds.setFrame(bounds.x-hGridStep, bounds.y-vGridStep, bounds.width+hGridStep*2, bounds.height+vGridStep*2);
size.setFrame(size.union(bounds));
size.setFrame(0, 0, size.width+size.x, size.height+size.y);
revalidate();
}
// simule une grille
private Point magnetize(Point point) {
int x = (point.x/hGridStep) * hGridStep;
int y = (point.y/vGridStep) * vGridStep;
point.x = nearest(point.x, x, x+hGridStep);
point.y = nearest(point.y, y, y+vGridStep);
return point;
}
// détermine la coordonnée la plus proche
private int nearest(int current, int pos1, int pos2 ) {
if ( current-pos1< pos2-current ) {
return pos1;
}
else {
return pos2;
}
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
drawGrid(g); // on dessine la grille
drawLines((Graphics2D)g); // on dessine les lignes
drawMouse((Graphics2D)g); // on dessine le résultat du dessin courant
}
private void drawGrid(Graphics g) {
g.setColor(Color.GRAY); // on dessine la grille en gris
int width = Math.max(getWidth(), size.width) + hGridStep;
int height = Math.max(getHeight(), size.height) + vGridStep;
int xs = size.x - hGridStep;
int y=size.y-hGridStep;
while( y<=height ) {
int x=xs;
while( x<=width ) {
drawPoint(g, x, y);
x+=hGridStep;
}
y+=vGridStep;
}
}
private void drawLines(Graphics2D g) {
g.setColor(Color.WHITE); // on dessine les lignes en blanc
for(Line2D line : lines) {
drawLine(g, line);
}
}
private void drawMouse(Graphics2D g) {
if ( point!=null ) {
g.setColor(Color.YELLOW);
fillPoint(g, point.x, point.y);
}
if ( line!=null && !line.getP1().equals(line.getP2()) ) {
g.setColor(Color.CYAN);
drawLine(g, line);
}
}
private void drawLine(Graphics2D g, Line2D line) {
fillPoint(g, (int)line.getX1(), (int)line.getY1());
fillPoint(g, (int)line.getX2(), (int)line.getY2());
g.draw(line);
}
private void drawPoint(Graphics g, int x, int y) {
g.drawOval(x-2,y-2,4,4); // on représente un point par un cercle
}
private void fillPoint(Graphics g, int x, int y) {
g.fillOval(x-2,y-2,4,4); // on représente un point par un cercle
}
// pour dimension le panel( nécessaire pour l'adaptation du scrollpane
@Override
public Dimension getPreferredSize() {
if( tmpsize!=null ) return tmpsize.getSize();
return size.getSize();
}
public static void main(String[] args) {
JFrame frame = new JFrame("Démo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new JScrollPane(new GridMagDrawDemo(25,25)));
frame.setSize(300, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
} |
Partager