我正在编写一个包含端口对象和目标对象的实用程序。我希望它具有以下特征:
我想使用Swing这样做,但我可以接受其他建议。
Here's an SO thread that gets me part of the way there in Swing
我的问题是
答案 0 :(得分:2)
“如何使线条可点击”
你应该使用抽象。创建一个SelectableLine
类,其中包含Line2D
和isSelected
等属性。在MouseListener
中获取Point
中的MouseEvent
。您可能希望从该点创建一个小矩形区域,这样您就不必完全单击该行。使用Rectangle
查看行intersects()
。如果是,setSelected
上的SelectableRectangle
。您可以选择使用isSelected
行执行任何操作。在下面的示例中,我只是更改颜色以显示它已被选中。
这是一个例子(注意:有很多方法可以实现这一点。这只是我“在10分钟内把东西放在一起”版本)
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);
}
}
}
另一方面,这不是一项微不足道的任务(即我不能在十分钟内完成任务)。您可能希望在行尾创建某种锚点。也许在每个终点添加一个小“如何让'成长'线条突然出现”
Rectangle
。拖动矩形时,该行将跟随它。对于捕捉矩形,您需要一个算法来确定要将其锚定到的形状边缘的最近点。松开鼠标时,将其卡入到位。
您可能想要查看一些编码想法的资源。
参见Dr.John.B.Matthews的GraphPanel(从this SO answer获得的链接)
中@MadProgrammer的回答