Drawing a movable line on a JPanel

假如想象 提交于 2019-12-04 19:28:47

Why not create an ArrayList of your control points, or perhaps even better, Ellipse2D objects centered on the control points? Then you can test if the mouse is pressed in an Ellipse to determine what its behavior should be, and you could use the List of Ellipse2D objects to obtain the line end points when drawing in the paintComponent(...) method.

Note that your code does not compile nor run for us, and so makes it difficult for us to fully analyze, test, and modify it. For better more specific help, consider condensing your code to the smallest possible code that still compiles, runs and is able to reproduce your problem, an sscce.

For example:

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.RenderingHints;
import java.awt.Stroke;
import java.awt.event.*;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;

import javax.swing.*;

@SuppressWarnings("serial")
public class Floor2 extends JPanel {
   private static final Color BACKGROUND = new Color(0, 0, 0, 0);
   private static final Color INITIAL_COLOUR = Color.BLACK;
   private static final int BORDER_WIDTH = 5;
   private static final Color LINE_DRAWING_COLOR = new Color(200, 200, 255);
   private static final Color LINE_COLOR = Color.blue;
   private static final Stroke DRAWING_LINE_STROKE = new BasicStroke((float)BORDER_WIDTH);
   public static final int ELLIPSE_DIAMETER = 10;
   private MouseState mouseState = MouseState.IDLE;
   private BufferedImage bufImage = null;
   private int width;
   private int height;
   private int gridDivisions;
   private List<List<Ellipse2D>> ellipseList = new ArrayList<List<Ellipse2D>>();
   private Line2D drawingLine = null;

   public enum MouseState {
      IDLE, DRAGGING
   }

   public Floor2(int width, int height, int gridDivisions) {
      this.width = width;
      this.height = height;
      this.gridDivisions = gridDivisions;
      setBackground(Color.white);
      setBorder(BorderFactory.createLineBorder(Color.black, BORDER_WIDTH));

      MyMouseAdapter mouseAdapter = new MyMouseAdapter();
      addMouseListener(mouseAdapter);
      addMouseMotionListener(mouseAdapter);
   }

   private static void createAndShowGui() {
      int w = 600;
      int h = w;
      int gridDiv = 20;
      Floor2 mainPanel = new Floor2(w, h, gridDiv);

      JFrame frame = new JFrame("Floor2");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(width, height);
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      if (bufImage == null) {
         bufImage = createGridImage();
      }

      Graphics2D g2 = (Graphics2D) g;
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);

      Stroke initStroke = g2.getStroke();
      g2.setStroke(DRAWING_LINE_STROKE);
      if (mouseState == MouseState.DRAGGING && drawingLine != null) {
         g2.setColor(LINE_DRAWING_COLOR);
         g2.draw(drawingLine);
      }

      g2.setColor(LINE_COLOR);
      for (List<Ellipse2D> ellipses : ellipseList) {
         Point2D p2d1 = new Point2D.Double(ellipses.get(0).getCenterX(), ellipses.get(0).getCenterY());
         Point2D p2d2 = new Point2D.Double(ellipses.get(1).getCenterX(), ellipses.get(1).getCenterY());
         Line2D line = new Line2D.Double(p2d1, p2d2);
         g2.draw(line);
      }

      g.drawImage(bufImage, 0, 0, this);
      g2.setStroke(initStroke);
   }

   private BufferedImage createGridImage() {
      BufferedImage gridImage = new BufferedImage(width, height,
            BufferedImage.TYPE_INT_ARGB);
      Graphics2D g2 = gridImage.createGraphics();
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
      g2.setBackground(BACKGROUND);
      g2.clearRect(0, 0, width, height);

      int divisionSize = width / gridDivisions;
      int grid = width * height;
      g2.setColor(Color.lightGray);
      for (int i = 1; i < grid; i++) {
         int x = i * divisionSize;
         g2.drawLine(x, 0, x, getSize().height);
      }
      for (int i = 1; i < grid; i++) {
         int y = i * divisionSize;
         g2.drawLine(0, y, getSize().width, y);
      }

      g2.dispose();
      return gridImage;
   }

   private class MyMouseAdapter extends MouseAdapter {
      private Point p1;

      @Override
      public void mousePressed(MouseEvent e) {
         if (e.getButton() != MouseEvent.BUTTON1) {
            return;
         }

         for (List<Ellipse2D> endPts : ellipseList) {
            // check if one of the ellipses has been selected
            // if so, remove it from elipseList
            // set drawingLine == to end points
            // setdragging = true
            // repaint
            // return
         }
         mouseState = MouseState.DRAGGING;
         p1 = e.getPoint();
      }

      @Override
      public void mouseDragged(MouseEvent e) {
         if (mouseState != MouseState.DRAGGING) {
            return;
         }
         drawingLine = new Line2D.Double(p1, e.getPoint());
         repaint();
      }

      @Override
      public void mouseReleased(MouseEvent e) {
         if (drawingLine != null) {
            List<Ellipse2D> newEndPoints = new ArrayList<Ellipse2D>();

            double x1 = drawingLine.getX1() - ELLIPSE_DIAMETER / 2;
            double y1 = drawingLine.getY1() - ELLIPSE_DIAMETER / 2;
            Ellipse2D ellipse1 = new Ellipse2D.Double(x1, y1, ELLIPSE_DIAMETER, ELLIPSE_DIAMETER);
            x1 = drawingLine.getX2() - ELLIPSE_DIAMETER / 2;
            y1 = drawingLine.getY2() - ELLIPSE_DIAMETER / 2;
            Ellipse2D ellipse2 = new Ellipse2D.Double(x1, y1, ELLIPSE_DIAMETER, ELLIPSE_DIAMETER);
            newEndPoints.add(ellipse1);
            newEndPoints.add(ellipse2);
            ellipseList.add(newEndPoints);
            repaint();
         }

         mouseState = MouseState.IDLE;
         drawingLine = null;
      }
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

edit: mousePressed method change:

private class MyMouseAdapter extends MouseAdapter {
  private Point2D p1;

  @Override
  public void mousePressed(MouseEvent e) {
     if (e.getButton() != MouseEvent.BUTTON1) {
        return;
     }

     for (List<Ellipse2D> endPts : ellipseList) {
        for (int i = 0; i < endPts.size(); i++) {
           Ellipse2D endPt = endPts.get(i);
           if (endPt.contains(e.getPoint())) {
              Ellipse2D endPt2 = endPts.get(Math.abs(i - 1));
              ellipseList.remove(endPts);

              Point2D p2 = new Point2D.Double(endPt.getCenterX(), endPt.getCenterY());
              p1 = new Point2D.Double(endPt2.getCenterX(), endPt2.getCenterY());
              drawingLine = new Line2D.Double(p1, p2);
              mouseState = MouseState.DRAGGING;
              repaint();
              return;
           }
        }
     }
     mouseState = MouseState.DRAGGING;
     p1 = e.getPoint();
  }

  @Override
  public void mouseDragged(MouseEvent e) {
     if (mouseState != MouseState.DRAGGING) {
        return;
     }
     drawingLine = new Line2D.Double(p1, e.getPoint());
     repaint();
  }

  @Override
  public void mouseReleased(MouseEvent e) {
     if (drawingLine != null) {
        List<Ellipse2D> newEndPoints = new ArrayList<Ellipse2D>();

        double x1 = drawingLine.getX1() - ELLIPSE_DIAMETER / 2;
        double y1 = drawingLine.getY1() - ELLIPSE_DIAMETER / 2;
        Ellipse2D ellipse1 = new Ellipse2D.Double(x1, y1, ELLIPSE_DIAMETER, ELLIPSE_DIAMETER);
        x1 = drawingLine.getX2() - ELLIPSE_DIAMETER / 2;
        y1 = drawingLine.getY2() - ELLIPSE_DIAMETER / 2;
        Ellipse2D ellipse2 = new Ellipse2D.Double(x1, y1, ELLIPSE_DIAMETER, ELLIPSE_DIAMETER);
        newEndPoints.add(ellipse1);
        newEndPoints.add(ellipse2);
        ellipseList.add(newEndPoints);
        repaint();
     }

     mouseState = MouseState.IDLE;
     drawingLine = null;
  }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!