Как я могу принести мою форму, которую я нарисовал с помощью paintComponent и щелкнул мышью вперед? - PullRequest
1 голос
/ 02 апреля 2020

У меня есть программа, которая нарисовала три разные фигуры (круг, треугольник и квадрат), и я пытаюсь перетащить их мышью. То, что я хочу сделать, это вывести на передний план ту форму, которая нажата. Могу ли я передать аргумент вместе с repaint (), чтобы сообщить программе, что, например, выбранный круг должен быть нарисован последним, или можно создать три различных метода рисования, чтобы отслеживать порядок рисования?

Другой вопрос - это мой if-l oop, он прекрасно работает, чтобы перетаскивать квадрат через круг и треугольник, но круг и треугольник берут квадрат вместе с ними, если мышь находится в той же области. Можно ли отключить прослушивание мыши для других фигур, пока я перетаскиваю их?

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Rectangle2D;
import java.awt.geom.Ellipse2D;
import java.awt.Polygon;
import javax.swing.JFrame;
import javax.swing.JPanel;


public class MouseMoveScale extends JPanel {

    public boolean first;

private Rectangle2D.Float myRect = new Rectangle2D.Float(50, 50, 100, 100);
private Ellipse2D.Float myCr = new Ellipse2D.Float(10,10, 100, 100);
private Polygon myTr   = new Polygon(new int []  {120, 60, 240}, new int[] {150, 200, 200}, 3);

MovingAdapter ma = new MovingAdapter();

public MouseMoveScale() {
    addMouseMotionListener(ma);
    addMouseListener(ma);
}
public void paintComponent( Graphics g ) {

}
public void paint(Graphics g) {

    super.paint(g);
    Graphics2D square = (Graphics2D) g;
    Graphics2D triangle = (Graphics2D) g;
    Graphics2D circle = (Graphics2D) g;

    square.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    square.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
    square.setColor(new Color(0, 0, 200));
    square.fill(myRect);

    triangle.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    triangle.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
    triangle.setColor(new Color(139, 89, 255));
    triangle.fill(myTr);

    circle.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    circle.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
    circle.setColor(new Color(0, 0, 117));
    circle.fill(myCr);
}

class MovingAdapter extends MouseAdapter {

    private int x;
    private int y;

    public void mousePressed(MouseEvent e) {
        x = e.getX();
        y = e.getY();
    }

    public void mouseDragged(MouseEvent e) {
        int dx = e.getX() - x;
        int dy = e.getY() - y;

        if (myRect.contains(x, y)) {
            myRect.x += dx;
            myRect.y += dy;
            repaint();
        }

        else if (myTr.contains(x, y)) {
          myTr.translate(dx, dy);
            repaint();
       }
        else if (myCr.contains(x, y)) {
            myCr.x += dx;
            myCr.y += dy;
            repaint();
        }
        x += dx;
        y += dy;
    }
    }



    public static void main(String[] args) {
    JFrame frame = new JFrame("Shapes World");
    MouseMoveScale m = new MouseMoveScale();
    m.setDoubleBuffered(true);
    frame.add(m);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(300, 300);
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
   }
   }

1 Ответ

3 голосов
/ 02 апреля 2020

Предложения:

  1. Поместите все фигуры в List<Shape>
  2. Итерируйте по списку вперед в paintComponent, рисуя каждую фигуру. Последний нарисованный будет сверху.
  3. В прослушивателе / ​​адаптере мыши, итерируйте список фигур в обратном направлении , чтобы узнать, какая фигура была нажата, и выйдите из l oop как как только какая-либо форма была найдена. Сделайте это в обратном порядке, чтобы сначала проверяли верхний элемент.
  4. Когда фигура найдена, удалите ее из списка, а затем повторно добавьте ее и вызовите repaint(). Это будет нарисовано сверху.

Например:

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.Shape;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;

@SuppressWarnings("serial")
public class DragShapes extends JPanel {
    private static final Color Background = Color.WHITE;
    private int panelWidth;
    private int panelHeight;
    private List<ColorShape> shapes = new ArrayList<>();

    public DragShapes(int width, int height, int diskCount) {
        this.panelWidth = width;
        this.panelHeight = height;
        setBackground(Background);

        MyMouse myMouse = new MyMouse();
        addMouseListener(myMouse);
        addMouseMotionListener(myMouse);

        double satVariance = 0.4;
        for (int i = 0; i < diskCount; i++) {           
            // create some semi-random colors
            float hue = ((float) i) / (float) diskCount;
            float brightness = (float) (satVariance * Math.random() + 1 - satVariance);
            float saturation = (float) (satVariance * Math.random() + 1 - satVariance);
            Color color = Color.getHSBColor(hue, saturation, brightness);

            // create random placement
            int x = (int) (Math.random() * (width - ColorShape.WIDTH) + ColorShape.WIDTH / 2);
            int y = (int) (Math.random() * (height - ColorShape.WIDTH) + ColorShape.WIDTH / 2);

            // create random Color Shapes using the above locations and colors
            shapes.add(new ColorShape(color, x, y));
        }
    }

    @Override
    protected void paintComponent(Graphics g) {
        // do JPanel house-keeping painting
        super.paintComponent(g);

        // create smooth curves
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        // iterate through the shapes list, drawing each shape
        for (ColorShape colorShape : shapes) {
            colorShape.draw(g2);
        }
    }

    // size the JPanel appropriately
    @Override
    public Dimension getPreferredSize() {
        Dimension prefSize = super.getPreferredSize();
        if (isPreferredSizeSet()) {
            return prefSize;
        }
        int w = Math.max(prefSize.width, panelWidth);
        int h = Math.max(prefSize.height, panelHeight);
        return new Dimension(w, h);
    }

    // combination mouse listener and mouse motion listener
    private class MyMouse extends MouseAdapter {
        private ColorShape colorShape; // the current color shape that we're dragging
        private Point p; // previous location of the color shape

        @Override
        public void mousePressed(MouseEvent e) {
            // iterate *backward* through the list
            for (int i = shapes.size() - 1; i >= 0; i--) {
                // get the shape in the list
                ColorShape colorShape = shapes.get(i);
                // if it contains the current point, we've got it!
                if (colorShape.contains(e.getPoint())) {
                    // set the mouse adapter colorShape field with this shape
                    this.colorShape = colorShape;
                    // set the current point, p
                    this.p = e.getPoint();

                    // *remove* the shape from the list
                    shapes.remove(colorShape);

                    // re-add it so it is now the last shape in the list
                    shapes.add(colorShape);

                    // draw all shapes
                    repaint();
                    return;  // we're done
                }
            }
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            moveShape(e); // move the dragged shape
            colorShape = null;  // and release the reference to it
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            moveShape(e); // move the dragged shape
        }

        private void moveShape(MouseEvent e) {
            // if we are not currently dragging a shape
            if (colorShape == null) {
                return;  // get out of here
            }

            // otherwise translate this shape using the 2 points
            colorShape.translate(p, e.getPoint());          
            repaint();

            // re-set the current point
            p = e.getPoint();
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            int width = 1000;
            int height = 800;
            int diskCount = 40;
            JFrame frame = new JFrame("Drag Shapes");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(new DragShapes(width, height, diskCount));
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }
}
class ColorShape {
    public static final int WIDTH = 100;
    private Color color;
    private int x;
    private int y;

    // path 2d objects are Shape objects that can be translated
    // easily using an affine transform
    private Path2D path;

    public ColorShape(Color color, int x, int y) {
        super();
        this.color = color;
        this.x = x;
        this.y = y;

        // create an ellipse (circle) and make a Path2D object with it
        Shape shape = new Ellipse2D.Double(x - WIDTH / 2, y - WIDTH / 2, WIDTH, WIDTH);
        path = new Path2D.Double(shape);
    }

    // test if the point is contained by this shape
    public boolean contains(Point p) {
        return path.contains(p);
    }

    // draw our shape
    public void draw(Graphics2D g2) {
        g2.setColor(color);
        g2.fill(path);
        g2.setColor(Color.BLACK);
        g2.draw(path);
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    public static int getWidth() {
        return WIDTH;
    }

    public Color getColor() {
        return color;
    }

    // the magic of affine transforms 
    public void translate(Point p0, Point p1) {
        int tx = p1.x - p0.x;
        int ty = p1.y - p0.y;
        path.transform(AffineTransform.getTranslateInstance(tx, ty));
    }

}
...