2016-07-24 59 views
1

我想做一個簡單的繪畫程序。我正在試圖製作一個像鉛筆這樣的工具,它允許自由繪畫。到目前爲止,我的代碼是:如何在行間填充空格?

NPaintMain

public class NPaintMain { 
    public static void main(String[] args) { 
     new NPaintWindow(); 
    } 
} 

NPaintWindow

public class NPaintWindow { 
    private JFrame windowFrame; 
    private String windowTitle; 
    private NPaintCanvas canvas; 
    private Container easel;  
    public NPaintWindow() { 
     windowTitle = "NPaint - a simple paint program."; 
     windowFrame = new JFrame(windowTitle); 
     windowFrame.setDefaultCloseOperation(windowFrame.EXIT_ON_CLOSE); 
     windowFrame.setSize(500, 500); 
     windowFrame.setLocationRelativeTo(null); 
     canvas = new NPaintCanvas(); 
     easel = windowFrame.getContentPane(); 
     easel.add(canvas); 
     windowFrame.setVisible(true); 
    } 
} 

NPaintCanvas

public class NPaintCanvas extends JPanel { 
    double x, y, px, py; 
    ArrayList<Line2D> l; 
    public NPaintCanvas() { 
     new NPaintMouseEvents(this); 
     x = y = px = py = 0; 
     l = new ArrayList<>(); 
    } 
    @Override 
    public void paintComponent(Graphics g){ 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g; 
      for(Line2D ll: l){ 
       g2d.draw(ll); 
      } 
      l.add(new Line2D.Double(px, py, x, y)); 
      g.dispose(); 
      repaint(); 
    } 
} 

NPaintMouseEvents

public class NPaintMouseEvents implements MouseListener,MouseMotionListener { 

    NPaintCanvas canvas; 

    public NPaintMouseEvents(NPaintCanvas canvas) { 
     this.canvas = canvas; 
     this.canvas.addMouseMotionListener(this); 
     this.canvas.addMouseListener(this); 
    } 

    @Override 
    public void mouseDragged(MouseEvent e) { 
     if(canvas.px == 0 && canvas.py == 0){ 
      canvas.px = e.getX(); 
      canvas.py = e.getY(); 
     } 
     canvas.x = e.getPoint().x; 
     canvas.y = e.getPoint().y; 
     canvas.px = canvas.x; 
     canvas.py = canvas.y; 
    } 
} 

我在這裏的主要問題是,在拖動點繪製的,但他們有他們like this之間的空間。我想加入實線。任何幫助進一步的提示將不勝感激。

+0

有許多的方式來實現這一目標。 1)在當前點和最後點之間繪製一個'Line2D'。 2)將所有點添加到一個'GeneralPath'並且每次添加一個新的點時繪製它。順便說一句:爲了更快地提供更好的幫助,請發佈[MCVE]或[簡短,獨立,正確的示例](http://www.sscce.org/)。爲此,需要將除main(String [])'類之外的所有類都還原爲默認值,並將其放在NPaintMain末尾,然後添加導入。 –

+0

@安德魯·湯普森我不確定我是否有這個權利。 –

+0

查看編輯的評論..噢,對,我沒有(從來沒有)密切關注代碼,直到有一個MCVE,編譯在我的IDE .. –

回答

2

你的問題是你畫一個單一的點到每個鼠標拖動。

對於每條畫線:x1和x2是相同的,y1和y2是相同的。
你應該在兩個不同的點之間畫一條線。 我已經更新了您的代碼,通過引入兩個不同的點:prev和實際點。
爲了簡單解釋,僅當前一個點和實際點具有值時繪製一條線。
當繪製一條線時,最後一個實際繪製點將成爲下一個繪製線的上一個點。這樣,你就不會在線條之間產生空洞了。

在Canvas類:

if (previousPoint != null && actualPoint != null) { 
    l.add(new Line2D.Double(previousPoint.x, previousPoint.y, actualPoint.x, actualPoint.y)); 
    previousPoint = new Point(actualPoint.x, actualPoint.y); 
} 

如果你鬆開鼠標按鈕,前面的和實際點都設置爲null。

在事件類:

@Override 
    public void mouseReleased(MouseEvent e) { 
     canvas.mouseReleased(); 
    } 

在Canvas類:

public void mouseReleased() { 
    previousPoint = null; 
    actualPoint = null; 
    } 

通過這種方式,可以繪製線條倍數以獨立的方式,如果你想。

此外,我已使用Point實例(而不是雙打)使用點座標簡化了代碼,但您可以使用多個雙打字段,它在實踐中並不會改變很多事情。

package paint; 

import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Point; 
import java.awt.geom.Line2D; 

import java.util.ArrayList; 

import javax.swing.JPanel; 

public class NPaintCanvas extends JPanel { 
    ArrayList<Line2D> l; 
    Point actualPoint; 
    Point previousPoint; 

    public NPaintCanvas() { 
    new NPaintMouseEvents(this); 
     l = new ArrayList<>(); 
    } 



    @Override 
    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     Graphics2D g2d = (Graphics2D) g; 
     for (Line2D ll : l) { 
      g2d.draw(ll); 
     } 
     if (previousPoint != null && actualPoint != null) { 
      l.add(new Line2D.Double(previousPoint.x, previousPoint.y, actualPoint.x, actualPoint.y)); 
      previousPoint = new Point(actualPoint.x, actualPoint.y); 
     } 
     g.dispose(); 
     repaint(); 
    } 

    public void mouseReleased() { 
     previousPoint = null; 
     actualPoint = null; 
    } 

    public void mousePressed(int x, int y) { 
     previousPoint = new Point(x, y); 
    } 
} 

NPaintMouseEvent

package paint; 

import java.awt.Point; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 
import java.awt.event.MouseMotionListener; 

public class NPaintMouseEvents implements MouseListener, MouseMotionListener { 

    NPaintCanvas canvas; 

    public NPaintMouseEvents(NPaintCanvas canvas) { 
     this.canvas = canvas; 
     this.canvas.addMouseMotionListener(this); 
     this.canvas.addMouseListener(this); 
    } 

    @Override 
    public void mouseDragged(MouseEvent e) { 
     if (canvas.actualPoint == null) { 
     canvas.actualPoint = new Point(); 
     } 
     canvas.actualPoint.x = e.getPoint().x; 
     canvas.actualPoint.y = e.getPoint().y; 
    } 

    @Override 
    public void mouseMoved(MouseEvent e) { 
    } 

    @Override 
    public void mouseClicked(MouseEvent e) { 
    } 

    @Override 
    public void mousePressed(MouseEvent e) { 
     canvas.mousePressed((int) e.getX(), (int) e.getY()); 
    } 

    @Override 
    public void mouseReleased(MouseEvent e) { 
     canvas.mouseReleased(); 
    } 

    @Override 
    public void mouseEntered(MouseEvent e) { 
    } 

    @Override 
    public void mouseExited(MouseEvent e) { 
    } 
} 
+0

謝謝:)。我知道在這個問題中沒有問你這個問題,但是你能幫助我解決這個問題 - >即使在釋放鼠標並從面板的某個角落開始後,最後一點和新點也會加入。是因爲我在使用ArrayList嗎?你能幫我一下嗎? –

+0

不客氣:) 不,不應該。它與你的名單沒有關係。我的示例代碼調用canvas.mouseReleased();在事件類中避免它。你可能忘了從我的例子中複製一些東西。我在我的答案中解釋它。 – davidxxx

+0

對不起我的壞! :) –

2

您正在修改您的對象狀態paintXXX - 這是錯誤的。 paint方法僅用於繪製當前狀態。

你應該在MouseListener添加鼠標點到列表中,並調用rapaint標記您的canvas類在EDT被粉刷一新。

paintComponent應該始終只繪製當前列表。

所以,你應該這樣來做:

public class NPaintCanvas extends JPanel { 
    ArrayList<Line2D> l; 
    public NPaintCanvas() { 
     new NPaintMouseEvents(this); 
     l = new ArrayList<>(); 
    } 
    @Override 
    public void paintComponent(Graphics g){ 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g; 
      for(Line2D ll: l){ 
       g2d.draw(ll); 
      } 
    } 
} 


public class NPaintMouseEvents implements MouseListener,MouseMotionListener { 

    NPaintCanvas canvas; 
    Point2D prev; 
    public NPaintMouseEvents(NPaintCanvas canvas) { 
     this.canvas = canvas; 
     this.canvas.addMouseMotionListener(this); 
     this.canvas.addMouseListener(this); 
    } 

    @Override 
    public void mouseDragged(MouseEvent e) { 
     if (prev==null) { 
      prev=e.getPoint(); 
      return; 
     } 
     Point2D p = new Line2D.Double(e.getPoint().x,e.getPoint().y); 
     if (p.equals(prev)) return ; //not really moved 
     canvas.l.add(prev, p); 
     p=prev; 
     canvas.repaint(); 
    } 
} 

注:最佳解決方案,你應該保持點,並採用GeneralPath

+0

謝謝:)會牢記這一點! –