Java 用鼠标调整形状大小

标签 java swing resize mouseevent mouselistener

我可以绘制、选择和移动矩形和椭圆形等形状。

我还想让用户调整他的形状大小。

我的MouseEvents代码:

public void mousePressed(MouseEvent e)
    {
    start = new Point(e.getX(), e.getY());
    end = start;
        if(buttonState == 5)
        {   
            for(int i = 0; i <shapes.size(); i++)
            {
                if(shapes.get(i).contains(start))
                {
                    shapeNumber = i;
                    if(shapes.get(i) instanceof Rectangle2D)
                    {   

                        handleRect = shapes.get(i).getBounds2D();
                        handleShape = handleRect;

                    }
                    else if(shapes.get(i) instanceof Ellipse2D)
                    {   
                        handleCircle = new Ellipse2D.Double(shapes.get(i).getBounds2D().getX(), shapes.get(i).getBounds2D().getY(), 
                        shapes.get(i).getBounds2D().getWidth(), shapes.get(i).getBounds2D().getHeight());
                        handleShape = handleCircle;

                    }

                    delta = new Point(e.getX() - (int)handleShape.getBounds2D().getX(), e.getY() - (int)handleShape.getBounds2D().getY());

                }
            }
             repaint();
        }
    }
    public void mouseReleased(MouseEvent e)
    {    
            Shape aShape = null;

            if (buttonState == 1)
            {
                aShape = drawCircle(start.x, start.y,e.getX(), e.getY());
            } 
            else 

            if (buttonState == 2)
            {
                aShape = drawRectangle(start.x, start.y,e.getX(), e.getY());
            }


            if(aShape !=null)
            {
              shapes.add(aShape);

            }

          start = null;
          end = null;
          handleShape = null;


          repaint();
     }
  } );

this.addMouseMotionListener(new MouseMotionAdapter()
{
  public void mouseDragged(MouseEvent e)
  {
    end = new Point(e.getX(), e.getY());
    if(buttonState == 5)
    {
       int x = e.getX() - delta.x;
       int y = e.getY() - delta.y;

       if(handleShape instanceof Rectangle2D)
       {
          handleRect.setRect(x, y, handleShape.getBounds2D().getWidth(), handleShape.getBounds().getHeight());
          handleShape = handleRect;
       }
       else if(handleShape instanceof Ellipse2D)
       {    
           handleCircle.setFrame(x, y, handleShape.getBounds2D().getWidth(), handleShape.getBounds().getHeight());
           handleShape = handleCircle;
       }

    }
    repaint();
  }
});

我知道我必须向 MousePressedMouseDragged 添加一些内容,以获取所选形状的点。这样我就可以拖动它来使形状变小或变大。

有人可以帮我解决这个问题吗?提前致谢。

最佳答案

引用此link中的代码,我在下面的代码中解决了两个缺点。您还需要考虑更多因素来适应您的使用:

  • 您使用多个 2D 形状(您提到了矩形和椭圆形)。但这里的代码显示了其中的一个。您需要努力才能同时支持多个人。
  • 以下解决方案适用于单个象限中的形状移动。因此,需要有关边界等的额外工作。
  • 此解决方案显示椭圆。您只需更改一行即可轻松支持矩形: Rectangle2D s = new Rectangle2D.Double();

下面是带有增强功能和注释的工作代码:

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class ResizeRectangle extends JPanel {
  private int SIZE = 8;
  //Below are 3 points, points[0] and [1] and top-left and bottom-right of the shape.
  // points[2] is the center of the shape
  private Rectangle2D[] points = { new Rectangle2D.Double(50, 50,SIZE, SIZE), 
                                   new Rectangle2D.Double(150, 100,SIZE, SIZE),
                                   new Rectangle2D.Double(100, 75,SIZE, SIZE)};
  Ellipse2D s = new Ellipse2D.Double();

  ShapeResizeHandler ada = new ShapeResizeHandler();

  public ResizeRectangle() {
    addMouseListener(ada);
    addMouseMotionListener(ada);
  }

  public void paintComponent(Graphics g) {
    super.paintComponent(g);

    Graphics2D g2 = (Graphics2D) g;

    for (int i = 0; i < points.length; i++) {
      g2.fill(points[i]);
    }
    s.setFrame(points[0].getCenterX(), points[0].getCenterY(),
        Math.abs(points[1].getCenterX()-points[0].getCenterX()),
        Math.abs(points[1].getCenterY()- points[0].getCenterY()));
    g2.draw(s);
  }

  class ShapeResizeHandler extends MouseAdapter {

    private Point2D[] lastPoints = new Point2D[3];
    private int pos = -1;
    public void mousePressed(MouseEvent event) {
      Point p = event.getPoint();

      for (int i = 0; i < points.length; i++) {
        if (points[i].contains(p)) {
          pos = i;
          // initialize preDrag points
          for(int j = 0; j < 3; j++){
              lastPoints[j] = new Point2D.Double(points[j].getX(), points[j].getY());
          }
          return;
        }
      }
    }

    public void mouseReleased(MouseEvent event) {
      pos = -1;
    }

    public void mouseDragged(MouseEvent event) {
      if (pos == -1)
        return;
      if(pos != 2){ //if 2, it's a shape drag
          points[pos].setRect(event.getPoint().x,event.getPoint().y,points[pos].getWidth(),
              points[pos].getHeight());
          int otherEnd = (pos==1)?2:1; //Get the end other than what is being dragged (top-left or bottom-right)
          //Get the x,y of the centre of the line joining the 2 new diagonal vertices, which will be new points[2]
          double newPoint2X = points[otherEnd].getX() + (points[pos].getX() - points[otherEnd].getX())/2;
          double newPoint2Y = points[otherEnd].getY() + (points[pos].getY() - points[otherEnd].getY())/2;
          points[2].setRect(newPoint2X, newPoint2Y, points[2].getWidth(), points[2].getHeight());
      }
      else{ //Shape drag, 1,2,3 points/marker rects need to move equal amounts
          Double deltaX = event.getPoint().x - lastPoints[2].getX();
          Double deltaY = event.getPoint().y - lastPoints[2].getY();
          for(int j = 0; j < 3; j++)
              points[j].setRect((lastPoints[j].getX() + deltaX),(lastPoints[j].getY() + deltaY),points[j].getWidth(),
                  points[j].getHeight());

      }
      repaint();
    }
  }

  public static void main(String[] args) {

    JFrame frame = new JFrame("Resize Shape2D");

    frame.add(new ResizeRectangle());
    frame.setSize(300, 300);
    frame.setLocationRelativeTo(null);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
  }
}

希望这有帮助。

关于Java 用鼠标调整形状大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49752737/

相关文章:

java - 是否有用于 varargs 数组的 Mockito eq 匹配器?

java - 有没有办法从 JFrame 返回特定元素?

java - 在actionperformed监听器中创建jpanel?

c# - C# 中垂直(仅)可调整大小的窗口窗体

java - 出现错误 无法解析类型 java.util.Map$Entry

java - 我们如何使用 java sql 将数组传递给 IN 参数并从 OUT 参数检索数组

java - 使用java RSA加密并使用BigInteger解密

java - 如何查看事件线程上运行的所有内容

Java Odd pack() 行为

javascript - 根据浏览器窗口的大小动态调整 div 的大小