在JPanel上检测用户的鼠标在Path2D形状的边缘上

时间:2014-10-19 01:43:27

标签: java swing hover jpanel shapes

所以,我正在尝试为矩形实现拖动调整大小功能。

所以,我想要的是当用户将鼠标悬停在矩形的右下角上时,将光标更改为双向箭头。 (就像你调整Chrome的大小一样)我不知道该怎么做。

这是该程序的简化版本,只是在屏幕中心添加一个方块。任何人对我如何实现这一点有任何想法?感谢

更新

我几乎拥有它,但当我在矩形的右上角时,光标也在变化。我只想在右下角才想要这个。我究竟做错了什么?谢谢!

public void mouseMoved(MouseEvent e) {
        int mouseX = e.getX();
        int mouseY = e.getY();
        Path2D hitShape = null;
        for (Path2D shape : shapes) {

            Rectangle bounds = shape.getBounds();
            if (mouseY >= bounds.y && mouseY <= bounds.y + getHeight()) {
                int lowerX = bounds.x + bounds.width - 2;
                int upperX = lowerX + 4;
                if (mouseX >= lowerX && mouseX <= upperX) {
                    hitShape = shape;
                    System.out.println("Hit");
                    Cursor cursor = Cursor
                            .getPredefinedCursor(Cursor.SE_RESIZE_CURSOR);
                    setCursor(cursor);
                    break;
                } else {
                    Cursor cursor = Cursor
                            .getPredefinedCursor(Cursor.DEFAULT_CURSOR);
                    setCursor(cursor);
                }
            }

        }
    }

完整代码

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
import javax.swing.*;

public class UMLEditor {

    public static void main(String[] args) {

        JFrame frame = new UMLWindow();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setBounds(30, 30, 1000, 700);
        frame.getContentPane().setBackground(Color.white);
        frame.setVisible(true);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

class UMLWindow extends JFrame {
    Shapes shapeList = new Shapes();
    Panel panel;

    private static final long serialVersionUID = 1L;

    public UMLWindow() {
        addMenus();
        panel = new Panel();
    }

    public void addMenus() {

        getContentPane().add(shapeList);

        setSize(300, 200);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        shapeList.addSquare(100, 100);
    }
}

// Shapes class, used to draw the shapes on the panel
// as well as implements the MouseListener for dragging
class Shapes extends JPanel {
    private static final long serialVersionUID = 1L;

    private List<Path2D> shapes = new ArrayList<Path2D>();
    int currentIndex;

    public Shapes() {
        MyMouseAdapter myMouseAdapter = new MyMouseAdapter();
        addMouseListener(myMouseAdapter);
        addMouseMotionListener(myMouseAdapter);
    }

    public void addSquare(int width, int height) {
        Path2D rect2 = new Path2D.Double();
        rect2.append(new Rectangle(442, 269, width, height), true);

        shapes.add(rect2);
        repaint();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        Graphics2D g2 = (Graphics2D) g;
        g2.setStroke(new BasicStroke(2));
        for (Path2D shape : shapes) {
            g2.draw(shape);
        }
    }

    class MyMouseAdapter extends MouseAdapter {

        @Override
        public void mousePressed(MouseEvent e) {

        }

        @Override
        public void mouseDragged(MouseEvent e) {
        }

        @Override
        public void mouseReleased(MouseEvent e) {
        }

        @Override
        public void mouseMoved(MouseEvent e) {
            int mouseX = e.getX();
            int mouseY = e.getY();
            Path2D hitShape = null;
            for (Path2D shape : shapes) {

                Rectangle bounds = shape.getBounds();
                if (mouseY >= bounds.y && mouseY <= bounds.y + bounds.getHeight()) {
                    int lowerX = bounds.x + bounds.width - 2;
                    int upperX = lowerX + 4;
                    if (mouseX >= lowerX && mouseX <= upperX) {
                        hitShape = shape;
                        System.out.println("Hit");
                        Cursor cursor = Cursor
                                .getPredefinedCursor(Cursor.SE_RESIZE_CURSOR);
                        setCursor(cursor);
                        break;
                    } else {
                        Cursor cursor = Cursor
                                .getPredefinedCursor(Cursor.DEFAULT_CURSOR);
                        setCursor(cursor);
                    }
                }

            }
        }
    }
}

1 个答案:

答案 0 :(得分:5)

像...一样的东西。

int mouseX = e.getX();
int mouseY = e.getY();
Path2D hitShape = null;
for (Path2D shape : shapes) {

    Rectangle bounds = shape.getBounds();
    if (mouseY >= bounds.y && mouseY <= bounds.y + height) {
        int lowerX = bounds.x + bounds.width - 2;
        int upperX = lowerX + 4;
        if (mouseX >= lowerX && mouseX <= upperX) {
            hitShape = shape;
            break;
        }
    }

}

// Deal with the shape you just hit...

您可能还有兴趣查看MouseMotionListener并根据光标的位置更改光标/形状...

更新了右上角检测

右角需要匹配鼠标的x和y位置,因为你应该允许点周围的一些“边距”,你可以简单地使用mouseY >= bounds.y - margin && mouseY <= bounds.y + margin,然后你将确定鼠标的哪一边上...

int mouseX = e.getX();
int mouseY = e.getY();
Path2D hitShape = null;
for (Path2D shape : shapes) {

    Rectangle bounds = shape.getBounds();
    // Upper edge...with buffer...
    if (mouseY >= bounds.y - 4 && mouseY <= bounds.y + 4) {
        int lowerX = bounds.x + bounds.width - 2;
        int upperX = lowerX + 4;
        // Right corner....
        if (mouseX >= lowerX && mouseX <= upperX) {
            hitShape = shape;
            break;
        }
    }

}

现在,我将创建至少4种方法,isWithinTopEdgeisWithinBottomEdgeisWithInLeftEdgeisWithInRightEdge,将采用路径的边界,鼠标Point和保证金值,将返回truefalse。这样您就可以按照您想要的任何顺序混合支票。

您也可以使用Path2D#contains来简化检查,但您需要考虑软糖因素,但这只是一个想法......