2016-07-24 4 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」に追加し、新しい点が追加されるたびに描画します。 BTW:すぐに役立つように、[MCVE]または[短く、自己完結型の正しい例](http://www.sscce.org/)を投稿してください。この場合、 'main(String [])'クラスを除くすべてのクラスをデフォルトにして、 'NPaintMain'の最後にそれらを残してから、インポートを追加する必要があります。 –

+0

@AndrewThompson私はそれが正しいと確信していません。 –

+0

編集したコメントを見る..私のIDEでコンパイルされたMCVEがあるまで、ああ、まあ、私はコードをよく見ていませんでした。 –

答えて

2

あなたの問題は、マウスをドラッグして移動するたびに1点を描くことです。

各描画線について:x1とx2は同じであり、y1とy2は同じです。
2つの異なるポイント間の線をトレースする必要があります。 私はあなたのコードを更新して、2つの異なるポイント(前ポイントと実際のポイント)を導入しました。
簡単に説明すると、前の点と実際の点に値がある場合にのみ線が描画されます。
そして、線が描画されるとき、最後の実際の描画点は、次の描画線の前の点になります。この方法では、線の間に穴がありません。 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に設定されています。Canvasクラスで

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

:Eventクラスで

このように

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

したい場合、あなたは独立した形で倍数ラインを描くことができます。

また、私は座標のint型を使用していますが、複数のダブルスのフィールドを使用することができます(代わりにdoubleの)ポイントのインスタンスを使用して、コードを単純化している、それは実際にたくさんのことをしないで変更します。

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にリストにマウスポイントを追加し、EDTして再描画されるあなたのcanvasクラスをマークするrapaintを呼び出す必要があります。

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

ありがとうございます。 –

関連する問題