"how to make lines clickable"
You should use an abstraction. Create say a SelectableLine
class where you have attributes like Line2D
and isSelected
. In a MouseListener
get the Point
from the MouseEvent
. You may want to created a small rectangle region from the point just so you don't have to click the line exactly. Use that Rectangle
to see if the line intersects()
. If it does, setSelected
on the SelectableRectangle
. You can choose to do whatever you wish to with the line that isSelected
. In the example below, I just change the color to show it's selected.
Here's an example (Note: there are many ways to accomplish this. This is just my "put something together in 10 minutes" version)

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class SelectLineDemo {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new SelectLineDemo();
}
});
}
public SelectLineDemo() {
JFrame frame = new JFrame();
frame.add(new SelectLinePanel());
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
class SelectableLine {
boolean selected = false;
Line2D line;
public SelectableLine(Line2D line) {
this.line = line;
}
public boolean intersects(Rectangle rectangle) {
return line.intersects(rectangle);
}
public void setSelected(boolean selected) {
this.selected = selected;
}
public boolean isSelected() {
return selected;
}
public Line2D getLine() {
return line;
}
}
class SelectLinePanel extends JPanel {
private int selectionRadius = 5;
private final Color SELECTED_COLOR = Color.BLUE;
private final Color UNSELECTED_COLOR = Color.BLACK;
private final Stroke STROKE = new BasicStroke(5.0f);
private List<SelectableLine> lines = new ArrayList<SelectableLine>();
public SelectLinePanel() {
initLines();
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
Point p = e.getPoint();
Rectangle selectionRect = getRectangleFromPoint(p);
checkIfLinesAreSelected(selectionRect);
repaint();
}
});
}
private void checkIfLinesAreSelected(Rectangle rectangle) {
for (SelectableLine line : lines) {
if (line.intersects(rectangle)) {
line.setSelected(true);
} else {
line.setSelected(false);
}
}
}
private Rectangle getRectangleFromPoint(Point p) {
int x = p.x - selectionRadius;
int y = p.y - selectionRadius;
int size = selectionRadius * 2;
Rectangle selectionRect = new Rectangle(x, y, size, size);
return selectionRect;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setStroke(STROKE);
for (SelectableLine line : lines) {
if (line.isSelected()) {
g2d.setColor(SELECTED_COLOR);
} else {
g2d.setColor(UNSELECTED_COLOR);
}
g2d.draw(line.getLine());
}
}
private void initLines() {
for (int i = 50; i <= 350; i += 50) {
lines.add(new SelectableLine(new Line2D.Double(50, i, 350, i)));
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
}
}
"how to have 'growing' lines that snap into place"
This on the other hand is not such a trivial task (i.e. not something I could whip up in ten minutes). You might want to create some kind of anchor point at the end of the line. Maybe add a small Rectangle
at each end point. As you drag the rectangle, the line will follow it. As far as snapping the rectangle, you'll need an algorithm to determine the nearest point of the edge of the shape you want to anchor it to. When you release the mouse, snap it in place.
Some resource you may want to look at for some coding idea.
See GraphPanel from Dr.John.B.Matthews (link obtained from this SO answer)

See answer from @MadProgrammer in Move an Oval in java
