当用户从 a 点拖动到 b 点时,在椭圆之间创建一条线

Create a line between ellipses when the user drags from point a to point b

我有 6 个顶点,如果用户拖动鼠标,例如从顶点 1 到顶点 2,用户应该能够创建一条线。如果用户释放鼠标并且鼠标没有结束顶点之一,它不会创建一条线。

我该怎么做?

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Ellipse2D;
import javax.swing.JComponent;
import javax.swing.JFrame;

public class DijkstraUI extends JComponent implements MouseListener {
    String zero = "0";
    String one = "1";
    String two = "2";
    String three = "3";
    String four = "4";
    String five = "5";

    Ellipse2D zeroOval = new Ellipse2D.Double(50,120,50,50);
    Ellipse2D oneOval = new Ellipse2D.Double(150,45,50,50);
    Ellipse2D twoOval = new Ellipse2D.Double(150,150,50,50);
    Ellipse2D threeOval = new Ellipse2D.Double(260,120,50,50);
    Ellipse2D fourOval = new Ellipse2D.Double(100,240,50,50);
    Ellipse2D fiveOval = new Ellipse2D.Double(200,250,50,50);

    Point pointStart = null;
    Point pointEnd = null;

    public DijkstraUI(){
    }

    public static void main(String args[]) {
        JFrame frame = new JFrame("Dijkstra: Finding the shortest path");
        DijkstraUI dj = new DijkstraUI();
        frame.getContentPane().add(dj);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400, 400);
        frame.setVisible(true);
        frame.setResizable(false);
    }

    @Override
    public void paint(Graphics g){
        Graphics2D g2d = (Graphics2D) g;
        g2d.setPaint(Color.WHITE);
        g2d.fill(zeroOval);
        g2d.fill(oneOval);
        g2d.fill(twoOval);
        g2d.fill(threeOval);
        g2d.fill(fourOval);
        g2d.fill(fiveOval);
        g2d.setPaint(Color.BLACK);
        g2d.drawString(zero,70,150);
        g2d.drawString(one,170,75);
        g2d.drawString(two,170,180);
        g2d.drawString(three,280,150);
        g2d.drawString(four,120,270);
        g2d.drawString(five,220,280);

        super.paint(g);
        if(pointStart != null)
            g2d.drawLine(pointStart.x, pointStart.y, pointEnd.x, pointEnd.y);
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        if((e.getButton() == 1) || zeroOval.contains(e.getX(), e.getY())){
            System.out.print("test");
        }
    }

    @Override
    public void mousePressed(MouseEvent e) {
        pointStart = e.getPoint();
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        pointStart = null;
    }

    public void mouseMoved(MouseEvent e) {
        pointEnd = e.getPoint();
    }

    public void mouseDragged(MouseEvent e) {
        pointEnd = e.getPoint();
        repaint();
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public void mouseExited(MouseEvent e) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }
}

花了一些时间,但我画了你的台词。

我对您的代码进行了以下主要更改。

  1. 我把JFrame的创建代码放在一个Runnable中,用Runnable调用SwingUtilities的invokeLater方法,把Swing组件的创建和使用放在Event Dispatch thread中。 Oracle 和我坚持认为所有 Swing 应用程序都在事件调度线程上启动。

  2. 我创建了一个 GUI 模型 class,DijkstraModel。 DijkstraModel class 包含一个椭圆列表和一个直线列表。

  3. 我创建了一个椭圆 class,MyEllipse,用来保存 Ellipse2D 信息和椭圆标签。每当您发现自己试图使两个列表保持同步时,请考虑创建一个 Java getter / setter class 来保存字段。

  4. 我创建了一条线 class,MyLine 用来保存线的端点。

  5. paintComponent 方法因 GUI 模型而得到简化。我添加了对超级 paintComponent 方法的调用。

  6. 我创建了一个单独的 MouseListener class,MyMouseListener,因为当它是单独的时,在静态上下文中处理侦听器更容易。

这是修改后的代码。

package com.ggl.testing;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class DijkstraUI extends JComponent {
    private static final long serialVersionUID = 8838700175925828779L;

    private static MyMouseListener listener;

    private DijkstraModel model;

    public DijkstraUI() {
        this.model = new DijkstraModel();
        listener = new MyMouseListener(this, model);
    }

    public static void main(String args[]) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame("Dijkstra: Finding the shortest path");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                DijkstraUI dj = new DijkstraUI();
                dj.addMouseListener(listener);
                frame.getContentPane().add(dj);

                frame.setSize(400, 400);
                frame.setResizable(false);
                frame.setVisible(true);
            }
        };

        SwingUtilities.invokeLater(runnable);
    }

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

        Graphics2D g2d = (Graphics2D) g;

        for (MyEllipse ellipse : model.getEllipseList()) {
            g2d.setPaint(Color.WHITE);
            Ellipse2D ellipse2d = ellipse.getEllipse();
            g2d.fill(ellipse2d);
            g2d.setPaint(Color.BLACK);
            g2d.drawString(ellipse.getLabel(),
                    (int) ellipse2d.getCenterX() - 5,
                    (int) ellipse2d.getCenterY() + 6);
        }

        for (MyLine myLine : model.getLineList()) {
            g2d.setPaint(Color.BLUE);
            g2d.drawLine(myLine.getFromPoint().x, myLine.getFromPoint().y,
                    myLine.getToPoint().x, myLine.getToPoint().y);
        }
    }

    public class MyMouseListener implements MouseListener {

        private JComponent component;

        private DijkstraModel model;

        private Point fromPoint;

        public MyMouseListener(JComponent component, DijkstraModel model) {
            this.component = component;
            this.model = model;
        }

        @Override
        public void mouseClicked(MouseEvent e) {

        }

        @Override
        public void mousePressed(MouseEvent e) {
            Point p = e.getPoint();
            Point2D p2d = new Point2D.Double((double) p.x, (double) p.y);
            p = getCenterPoint(p2d);
            if (p.x >= 0) {
                fromPoint = p;
            }
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            Point p = e.getPoint();
            Point2D p2d = new Point2D.Double((double) p.x, (double) p.y);
            p = getCenterPoint(p2d);
            if (p.x >= 0) {
                model.addMyLine(new MyLine(fromPoint, p));
                component.repaint();
            }
        }

        @Override
        public void mouseEntered(MouseEvent e) {

        }

        @Override
        public void mouseExited(MouseEvent e) {

        }

        private Point getCenterPoint(Point2D mousePoint) {
            for (MyEllipse ellipse : model.getEllipseList()) {
                Ellipse2D ellipse2d = ellipse.getEllipse();
                if (ellipse2d.contains(mousePoint)) {
                    Point p = new Point((int) ellipse2d.getCenterX(),
                            (int) ellipse2d.getCenterY());
                    return p;
                }
            }

            return new Point(-1, -1);
        }

    }

    public class DijkstraModel {
        private List<MyEllipse> ellipseList;
        private List<MyLine> lineList;

        public DijkstraModel() {
            this.ellipseList = new ArrayList<>();

            this.ellipseList.add(new MyEllipse("0", new Ellipse2D.Double(50,
                    120, 50, 50)));
            this.ellipseList.add(new MyEllipse("1", new Ellipse2D.Double(150,
                    45, 50, 50)));
            this.ellipseList.add(new MyEllipse("2", new Ellipse2D.Double(150,
                    150, 50, 50)));
            this.ellipseList.add(new MyEllipse("3", new Ellipse2D.Double(260,
                    120, 50, 50)));
            this.ellipseList.add(new MyEllipse("4", new Ellipse2D.Double(100,
                    240, 50, 50)));
            this.ellipseList.add(new MyEllipse("5", new Ellipse2D.Double(200,
                    250, 50, 50)));

            this.lineList = new ArrayList<>();
        }

        public List<MyEllipse> getEllipseList() {
            return Collections.unmodifiableList(ellipseList);
        }

        public void addMyLine(MyLine myLine) {
            this.lineList.add(myLine);
        }

        public List<MyLine> getLineList() {
            return Collections.unmodifiableList(lineList);
        }

    }

    public class MyEllipse {
        private final String label;
        private final Ellipse2D ellipse;

        public MyEllipse(String label, Ellipse2D ellipse) {
            this.label = label;
            this.ellipse = ellipse;
        }

        public String getLabel() {
            return label;
        }

        public Ellipse2D getEllipse() {
            return ellipse;
        }

    }

    public class MyLine {
        private final Point fromPoint;
        private final Point toPoint;

        public MyLine(Point fromPoint, Point toPoint) {
            this.fromPoint = fromPoint;
            this.toPoint = toPoint;
        }

        public Point getFromPoint() {
            return fromPoint;
        }

        public Point getToPoint() {
            return toPoint;
        }

    }
}