在做一个小东西,在两个组件中有多条直线连接,
我是直接在一个Jpanel中调用paint()方法实现的
例如:
public void paint(Graphics g) {
                …………省略
                g.drawLine(x1,y1,x1+15,y1);
                g.drawLine(x1+15,y1,x2-20,y2);
                g.drawLine(x2-20,y2,x2,y2);
            }但是这样做,直线是画出来了,但是画出来的直线却是不能够被鼠标选中,不能够监听鼠标事件的,
因为Paint()方法画出来的直线不是一个组件,
要怎么解决这个问题呢???
急啊,搞了2天了,就卡在这儿了。

解决方案 »

  1.   

    private boolean search(Vector v, int x, int y) //看是否选中线
    {
    int dl = 2;
    boolean isSelected = false;
    for (int j = 0; j < v.size(); j++) //一次只能有一个选中的,把原来选中的标志isselected清空
    {
    LinePara p = (LinePara) v.elementAt(j);
    p.isSelected = false;
    }
    for (int j = 0; j < v.size(); j++)
    {
    LinePara p = (LinePara) v.elementAt(j);
    if (p.isDelete != true)
    {
    if (p.x1 == p.x2)
    {
    //垂直线
    int maxY = p.y1 > p.y2 ? p.y1 : p.y2;
    int minY = p.y1 < p.y2 ? p.y1 : p.y2;
    isSelected = (Math.abs(x - p.x1) <= dl) && (y >= minY) && (y <= maxY);
    }
    else if (p.y1 == p.y2)
    {
    //水平线
    int maxX = p.x1 > p.x2 ? p.x1 : p.x2;
    int minX = p.x1 < p.x2 ? p.x1 : p.x2;
    isSelected = (Math.abs(y - p.y1) <= dl) && (x >= minX) && (x <= maxX);
    }
    else
    {
    //y = a * x + b
    float a = (float) (p.y2 - p.y1) / (p.x2 - p.x1);
    float b = p.y1 - a * p.x1;
    float py = y;
    float px = (y - b) / a;
    double r = Math.atan(1 / a);
    double cos = Math.cos(r);
    float dis = (float) (Math.abs(x - px) * cos);
    double dx = (dis * cos);
    float distance = dis;
    int maxX;
    int minX;
    maxX = p.x1 > p.x2 ? p.x1 : p.x2;
    minX = p.x1 < p.x2 ? p.x1 : p.x2;
    isSelected = (distance <= dl && maxX > (x - dx) && minX < (x - dx));
    }
    }
    if (isSelected == true)
    {
    p.isSelected = true;
    gds = j;
    break;
    }
    }
    return isSelected;
    }
      

  2.   

    其实这个问题的需求还是比较简单的:
    就是有一组直线,
    当鼠标移动到直线的某个范围(就是voxer(voxer) 说得矩形了)内的时候,
    点击鼠标左键,所选中的直线就改变成别的颜色,
    就可以对这条线进行删除,修改等操作了。我本来想是能不能够自己写一个直线的"组件"出来,
    按照楼上几位朋友的意思,好像需要进行多次的遍历直线,判断坐标,重画所有直线了,程序开销大,逻辑也有点复杂(我是新人,觉得还比较负责,大牛不要笑话我啊)。
    不过如果有一个“直线组件”的话,就能够直接对这个直线组件进行鼠标事件响应了,不用去遍历直线,判断坐标,重画所有直线了,
    好像我的想法有点幼稚啊!
      

  3.   

    下面这个方法可以判断是否选中直线
    private boolean insideSegment(int x, int y, int x0, int y0, int x1, int y1) {
        if (x1 == x0)
          return (x == x0) && (y >= Math.min(y0, y1)) && (y <= Math.max(y0, y1));
        Rectangle bounds = new Rectangle(x0, y0, 1, 1);
        int fudge = (int) Math.round(2.5);
        bounds.add(x1, y1);
        bounds.grow(fudge, fudge);
        if (!bounds.contains(x, y))
          return false;
        double slope = (double) (y1 - y0) / (double) (x1 - x0);
        double fx = (slope * (double) (x - x0)) + (double) y0;
        return Math.abs(fx - (double) y) < insideTolerance(slope);
      } int x, int y, int x0, int y0, int x1, int y1 这里x,y 是鼠标的点 x0,y0,x1,y1就是那条直线