2014-02-27 28 views
0

我找了一個相當簡單的(通過簡單的我的意思是什麼,需要的代碼tooo多線)以下的問題:的Java:圖形2D,不會畫得足夠快

我有油漆的應用程序。對於應用程序的代碼是在這裏:https://github.com/Tigatok/JavaProjects/tree/master/Paint2.0

這裏是我的問題:

如何獲得方行要爲pencilLine順利?

+0

使用'Polygon'某種Shape'的'和不斷增加點在一起,油漆,而不是代表行中的每個點的正方形...或者你可以在點之間畫線...所以,而不是'fillRect',你可以使用'drawLine' ... – MadProgrammer

回答

4

對於細線,目前您呼叫

g2D.drawLine(oldX, oldY, currentX, currentY); 

而對於粗線,你只叫

g2D.fillRect(currentX, currentY, getXSize(), getYSize()); 

這意味着當您快速移動鼠標時,就不會有連接投注以前和新的鼠標位置。

一個簡單的解決方案,已經允許以達到接近你可能想這可能是第二個呼叫變爲

g2D.setStroke(new BasicStroke(getXSize())); 
g2D.drawLine(oldX, oldY, currentX, currentY); 

然而效果,也適合當前的繪圖代碼幾種可能的改進。你應該考慮而不是根據一組布爾標誌作出決定。相反,你可以考慮像Pen接口,它允許你通過使用這個接口的不同實現來在不同的筆之間切換。

已經提到過,您可以將點組裝成一個Path2D並繪製此路徑。這是一個很好的建議,你一定要考慮:它提供了一些不錯的可能性。例如,您可以定義Stroke並創建任意筆形狀的「描邊形狀」。

但是,所有這些更改可能需要大量的重構,因此,直到現在,它們只是相當含糊的建議。


編輯:添加基於註釋

我能想象你想達到什麼效果的例子。但這可能相當困難。一個簡單的解決方案,可能至少是接近你想要什麼可能是這(使用一個類從http://www.jhlabs.com/java/java2d/strokes/的簡化版本)或

import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Shape; 
import java.awt.Stroke; 
import java.awt.geom.AffineTransform; 
import java.awt.geom.FlatteningPathIterator; 
import java.awt.geom.GeneralPath; 
import java.awt.geom.Path2D; 
import java.awt.geom.PathIterator; 
import java.awt.geom.Rectangle2D; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 

public class SharpiePaintTest 
{ 
    public static void main(String[] args) 
    { 
     SwingUtilities.invokeLater(new Runnable() 
     { 
      @Override 
      public void run() 
      { 
       createAndShowGUI(); 
      } 
     }); 
    }  

    private static void createAndShowGUI() 
    { 
     JFrame f = new JFrame(); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.getContentPane().add(new SharpiePaintTestPanel()); 
     f.setSize(1100,600); 
     f.setLocationRelativeTo(null); 
     f.setVisible(true); 
    } 
} 

class SharpiePaintTestPanel extends JPanel 
{ 
    @Override 
    protected void paintComponent(Graphics gr) 
    { 
     super.paintComponent(gr); 
     Graphics2D g = (Graphics2D)gr; 
     g.setColor(Color.BLACK); 

     Path2D path = new Path2D.Double(); 
     path.moveTo(300,300); 
     path.curveTo(400, 400, 400, 300, 300, 200); 

     g.setStroke(new ShapeStroke(new Rectangle2D.Double(0,0,3,15), 3.0f)); 
     g.draw(path); 
    } 
} 

// Based on http://www.jhlabs.com/java/java2d/strokes/ShapeStroke.java, 
// only slightly simplified 
class ShapeStroke implements Stroke { 
    private Shape shape; 
    private float advance; 
    private static final float FLATNESS = 1; 

    public ShapeStroke(Shape shape, float advance) { 
     this.advance = advance; 
     Rectangle2D bounds = shape.getBounds2D(); 
     this.shape = AffineTransform.getTranslateInstance(
      -bounds.getCenterX(), -bounds.getCenterY()).createTransformedShape(shape); 
    } 

    @Override 
    public Shape createStrokedShape(Shape shape) { 
     GeneralPath result = new GeneralPath(); 
     PathIterator it = new FlatteningPathIterator(shape.getPathIterator(null), FLATNESS); 
     float points[] = new float[6]; 
     float moveX = 0, moveY = 0; 
     float lastX = 0, lastY = 0; 
     float thisX = 0, thisY = 0; 
     int type = 0; 
     float next = 0; 
     while (!it.isDone()) { 
      type = it.currentSegment(points); 
      switch(type){ 
      case PathIterator.SEG_MOVETO: 
       moveX = lastX = points[0]; 
       moveY = lastY = points[1]; 
       result.moveTo(moveX, moveY); 
       next = 0; 
       break; 

      case PathIterator.SEG_CLOSE: 
       points[0] = moveX; 
       points[1] = moveY; 
       // Fall into.... 

      case PathIterator.SEG_LINETO: 
       thisX = points[0]; 
       thisY = points[1]; 
       float dx = thisX-lastX; 
       float dy = thisY-lastY; 
       float distance = (float)Math.sqrt(dx*dx + dy*dy); 
       if (distance >= next) { 
        float r = 1.0f/distance; 
        while (distance >= next) { 
         float x = lastX + next*dx*r; 
         float y = lastY + next*dy*r; 
         AffineTransform t = new AffineTransform(); 
         t.setToTranslation(x, y); 
         result.append(t.createTransformedShape(this.shape), false); 
         next += advance; 
        } 
       } 
       next -= distance; 
       lastX = thisX; 
       lastY = thisY; 
       break; 
      } 
      it.next(); 
     } 

     return result; 
    } 

} 
+0

感謝您的寶貴意見。我對整個繪畫理念和圖形課程都比較陌生。我根本不介意重構。如果你看到我的其他塗料類更糟 - 哈哈。不管怎麼說,多謝拉! – Kato

+0

您好,很抱歉發現您,但該解決方案大部分解決了我的問題。但是,我如何設置它以使筆畫像一個尖銳的?目前,我的代碼看起來像這樣給我的效果: g2D.fillRect(currentX,currentY,getXSize()/ 2,getYSize()+ 15); 在此先感謝! – Kato

+0

@Kato我已經添加了編輯 - 這可能很難,至少當你希望它在通話情況下看起來「很好」時.... – Marco13

1

它不是關於Java2D繪圖速度不夠快的問題,儘管Java2D與渲染庫應具有的速度相比是一個較慢的庫。

不管怎麼說申報程序中的一個Path2D.DoublePath2D.FloatmouseDrag,加的座標此Path2D對象mouseEvent
如果您要添加的是第一個座標,請使用moveTo()方法,否則請使用lineTo()方法。
完成後,請致電repaint()

在重繪,繪製Path2D類似以下內容:

public void paintComponent(Graphics graphics) 
{ 
    Graphics2D g = (Graphics2D) graphics; 
    // set appropriate color and line thickness here. 
    g.draw(path); 
    // draw other stuff. 
    g.dispose(); 
} 
+1

謝謝!我將致力於更新代碼。 – Kato