2016-05-18 21 views
0

我有6個頂點,用戶應該能夠創建一條線,例如,如果用戶從頂點1拖拽鼠標到頂點2。用戶釋放鼠標並且鼠標沒有在其中一個頂點結束,它不會創建一條線。當用戶從點a拖拽到點b時,在橢圓之間創建一條線

我該怎麼做?

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

花了一段時間,但我畫了你的線。

Shortest Path

我做你的代碼如下重大變化。

  1. 我把JFrame的創建代碼在一個Runnable,並呼籲SwingUtilities類的invokeLater方法用了Runnable把Swing組件的創建和使用的Event Dispatch thread。 Oracle和我堅持所有的Swing應用程序都從Event Dispatch線程開始。

  2. 我創建了一個GUI模型類DijkstraModel。 DijkstraModel類包含一個橢圓列表和一行列表。

  3. 我創建了一個橢圓類MyEllipse來容納Ellipse2D信息和橢圓標籤。每當你看到自己試圖保持兩個列表同步時,考慮創建一個Java getter/setter類來保存這些字段。

  4. 我創建了一個線類MyLine來保存線端點。

  5. 由於GUI模型,paintComponent方法被簡化了。我添加了對super paintComponent方法的調用。

  6. 我創建了一個單獨的MouseListener類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; 
     } 

    } 
} 
+0

非常感謝!這是非常有用的,很好的解釋。 – Temmie