【问题标题】:Java Graphics: connect dots through a 2D lineJava Graphics:通过二维线连接点
【发布时间】:2021-12-22 05:08:36
【问题描述】:

我是 Java 新手,我想创建一个非常简单的绘图 GUI,用户可以在其中绘制简单的表单,点击面板,当鼠标在一个位置按下并在另一个位置释放时用一条线连接不同的点(拖放)。点和线应存储在两个 ArrayList 中。 单击时,我设法在面板上找到了点,但是每次放下鼠标并创建另一个点时,该线都会改变坐标。我尝试了很多次,但我不知道如何让线条保留在面板上并“跟踪”拖放活动。

提前感谢您的每一个提示!


import java.util.ArrayList;
import java.util.Arrays;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.Line2D;
import java.awt.geom.Line2D.Double;

import javax.swing.JPanel;

public class PaintPanel extends JPanel {

    private ArrayList<Point> pointList;
    private ArrayList<Line2D.Double> lineList;
    private Point point1, point2;
    private Line2D line;
    public PaintPanel() {

        pointList = new ArrayList<Point>();
        lineList = new ArrayList<Line2D.Double>();
        addMouseListener(new PaintListener());

    }

    //takes as parameter objekt of Class Graphics
    public void paintComponent(Graphics g) {
        // calls constructor of SuperClass 
        super.paintComponent(g);

        this.setBackground(Color.white);
        // color to draw
        g.setColor(Color.black);

        for(Point spot : pointList) {
            g.fillOval(spot.x,spot.y, 10, 10);
            if(point1 != null & point2 !=null) {
                Graphics2D g2 =(Graphics2D) g;
                line = new Line2D.Double(point1.getX(), point1.getY(), point2.getX(), point2.getY());
                lineList.add((Double) line);
                g2.draw(line);
            }


        }

    }


    private class PaintListener implements MouseListener{

        @Override
        public void mouseClicked(MouseEvent e) {
        }

        @Override
        public void mousePressed(MouseEvent e) {
            point1 = e.getPoint();
            pointList.add(point1);
            repaint();

        }
        public void mouseDragged(MouseEvent e) {

        }

        @Override
        public void mouseReleased(MouseEvent e) {
            point2 = e.getPoint();
            pointList.add(point2);
            repaint();
        }

        @Override
        public void mouseEntered(MouseEvent e) {
            // TODO Auto-generated method stub

        }

        @Override
        public void mouseExited(MouseEvent e) {
            // TODO Auto-generated method stub

        }



    }

}

【问题讨论】:

  • point1point2 是否意味着代表一行?要存储更多行吗?
  • 您的代码中似乎有几个问题:1)您没有在列表中存储任何点,也没有存储任何行。 2)您为列表中的每个点绘制相同的线(假设有一些)。你应该做什么:当鼠标被释放时,检查你是否需要添加一个点(鼠标在按下后没有或几乎没有移动)或一条线(更大的鼠标移动)。然后仅使用列表(单点和线)进行绘制。
  • 如果要绘制鼠标拖动的线,请在mouseDraggedmouseMoved 中更新point2(如果已经有point1)并绘制单个 point1point2 之间的线,如果两者都不为空。在mouseReleased 中,如上所述添加点或线,然后将两个点都设置为 null 以指示没有活动的“拖动线” .
  • 如果您想深入了解 Java 图形编程,请查看 LibGDX 等游戏引擎框架。会容易很多。
  • 签出:Custom Painting ApproachesDrawOnComonent 示例显示了如何在拖动鼠标时绘制矩形。拖动鼠标时会动态绘制矩形。当鼠标被释放时,矩形被保存。您应该能够修改概念以绘制一条线并保存它。

标签: java swing paintcomponent mouselistener


【解决方案1】:

我已经重新创建了您正在尝试做的事情,我添加了代码 cmets 来帮助您完成整个过程。

程序从一组点开始,您可以用线连接这些点,您也可以通过右键单击添加更多点。

您需要与 MouseListener 一起实现 MouseMotionListener(如下所示),因为这将允许您跟踪所有鼠标的操作。

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.ArrayList;
import javax.swing.*;
    
public class PaintPanel extends JPanel implements MouseListener, MouseMotionListener {

//ARRAYLIST OF ALL POINTS
public ArrayList<Point2D.Double> points = new ArrayList<Point2D.Double>();

//ARRAYLIST OF ALL LINES
public ArrayList<Line2D.Double> lines = new ArrayList<Line2D.Double>();

//START POINT OF A NEW LINE
public Point2D.Double startPoint;

//CURRENT MOUSE LOCATION
public Point2D.Double mouse = null;

//TRUE IF USER IS DRAGGING
public boolean dragging = false;

//THE SIZE OF THE POINTS
public int pointSize = 20;

public static void main(String[] args) {
    JFrame frame = new JFrame();
    PaintPanel stage = new PaintPanel();
    stage.setBackground(new Color(47, 47, 47));
    stage.setPreferredSize(new Dimension(1000, 1000));
    stage.addMouseListener(stage);
    stage.addMouseMotionListener(stage);
    frame.setContentPane(stage);
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
}

public PaintPanel() {

    //ADDING POINTS TO THE CANVAS
    for (int i = 1; i < 10; i++)
        for (int j = 1; j < 10; j++)
            points.add(new Point2D.Double(100 * i, j * 100));

}

public void paintComponent(Graphics graphics) {
    super.paintComponent(graphics);
    Graphics2D g2 = (Graphics2D) graphics;
    
    //MAKING IT LOOK NICER
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g2.setStroke(new BasicStroke(2));

    //DRAWING CURRENTLY DRAGGING LINE
    if (dragging && startPoint != null) {
        g2.setColor(Color.WHITE);
        g2.drawLine((int) startPoint.x, (int) startPoint.y, (int) mouse.x, (int) mouse.y);
    }
    
    //DRAWING ALL THE LINES
    for (int i = 0; i < lines.size(); i++) {
        g2.setColor(Color.WHITE);
        Line2D l = lines.get(i);
        g2.drawLine((int) l.getX1(), (int) l.getY1(), (int) l.getX2(), (int) l.getY2());
    }
    
    //DRAWING ALL THE POINTS
    for (int i = 0; i < points.size(); i++) {
        Point2D.Double p = points.get(i);
        g2.setColor(Color.WHITE);
        g2.fillRoundRect((int) (p.x - (pointSize / 2)), (int) (p.y - (pointSize / 2)), pointSize, pointSize, pointSize, pointSize);
    }
}

@Override
public void mousePressed(MouseEvent e) {
    
    //ADD POINTS WITH RIGHT CLICK
    if (SwingUtilities.isRightMouseButton(e)) {
        mouse = new Point2D.Double(e.getX(), e.getY());
        points.add(new Point2D.Double(e.getX(), e.getY()));
    }
    repaint();
}

@Override
public void mouseReleased(MouseEvent e) {
    if (SwingUtilities.isLeftMouseButton(e)) {
        mouse = new Point2D.Double(e.getX(), e.getY());
        
        //IF THE USER HAS BEEN DRAGGING WHEN MOUSE RELEASED...
        if (dragging) {
            for (int i = 0; i < points.size(); i++) {
                Point2D.Double p = points.get(i);
                //IF THE USER FINISHED DRAGGING AT A POINT...
                if (p.distance(mouse) < pointSize / 2) {
                    lines.add(new Line2D.Double(startPoint, p));
                }
            }
        }
        startPoint = null;
        dragging = false;
    }
    repaint();
}

@Override
public void mouseDragged(MouseEvent e) {
    if (SwingUtilities.isLeftMouseButton(e)) {
        mouse = new Point2D.Double(e.getX(), e.getY());
        dragging = true;
        for (int i = 0; i < points.size(); i++) {
            Point2D.Double p = points.get(i);
            //IF THE USER STARTED DRAGGING ON A POINT...
            if (p.distance(mouse) < pointSize / 2 && startPoint == null) {
                startPoint = p;
            }
        }
    }
    repaint();
}

//UNUSED METHODS
@Override
public void mouseMoved(MouseEvent e) {}
@Override
public void mouseClicked(MouseEvent e) {}
@Override
public void mouseEntered(MouseEvent e) {}
@Override
public void mouseExited(MouseEvent e) {}

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-15
    • 2023-01-25
    • 2014-11-10
    • 2022-01-25
    • 2011-08-15
    • 1970-01-01
    • 2013-04-08
    • 2010-12-12
    相关资源
    最近更新 更多