Java 图形:通过二维线连接点
Java Graphics: connect dots through a 2D line
我是 Java 的新手,我想创建一个非常简单的绘图 GUI,用户可以在其中绘制简单的表格,单击面板并在按下鼠标时用一条线连接不同的点一个位置并在另一个位置释放(拖放)。点和线应存储在两个 ArrayList 中。
单击时我设法在面板上找到了点,但是每次放下鼠标并创建另一个点时,线都会改变坐标。我尝试了很多次,但我不知道如何让线条保留在面板上并“跟踪”拖放-activity.
提前感谢您的每一个提示!
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
}
}
}
我已经重新创建了您尝试执行的操作,我添加了代码注释以帮助您完成整个过程。
程序以一组点开始,您可以用线连接这些点,也可以通过右键单击添加更多点。
您需要将 MouseMotionListener 与 MouseListener(如下所示)一起实施,因为这将允许您跟踪鼠标的所有动作。
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) {}
}
我是 Java 的新手,我想创建一个非常简单的绘图 GUI,用户可以在其中绘制简单的表格,单击面板并在按下鼠标时用一条线连接不同的点一个位置并在另一个位置释放(拖放)。点和线应存储在两个 ArrayList 中。 单击时我设法在面板上找到了点,但是每次放下鼠标并创建另一个点时,线都会改变坐标。我尝试了很多次,但我不知道如何让线条保留在面板上并“跟踪”拖放-activity.
提前感谢您的每一个提示!
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
}
}
}
我已经重新创建了您尝试执行的操作,我添加了代码注释以帮助您完成整个过程。
程序以一组点开始,您可以用线连接这些点,也可以通过右键单击添加更多点。
您需要将 MouseMotionListener 与 MouseListener(如下所示)一起实施,因为这将允许您跟踪鼠标的所有动作。
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) {}
}