2009-08-06 9 views
9

java.awt.Graphicsを使用して線を描画する必要がありますが、矩形の外側にある線の部分だけをレンダリングする必要があります。Javaグラフィックスによるクリッピングの内部

グラフィックスクリッピングサポートを使用することはできますか、または交差点を計算して自分でラインをクリップする必要がありますか?

答えて

10

Areaクラスを使用する必要があります。この例では、尋ねることを行う方法をデモンストレーションします。

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.geom.Area; 
import java.awt.geom.Rectangle2D; 

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


public class Test extends JPanel { 

    public static void main(String[] args) { 
     JFrame f = new JFrame(); 
     Test t = new Test(); 
     f.getContentPane().setLayout(new BorderLayout()); 
     f.getContentPane().add(t,BorderLayout.CENTER); 
     f.pack(); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.setVisible(true); 
    } 

    public Test() { 
     setPreferredSize(new Dimension(300, 300)); 
    } 

    public void paintComponent(Graphics g) { 
     Graphics2D g2 = (Graphics2D)g.create(); 
     Rectangle2D rectangleNotToDrawIn = new Rectangle2D.Double(100, 100, 20, 30); 
     Area outside = calculateRectOutside(rectangleNotToDrawIn); 
     g2.setPaint(Color.white); 
     g2.fillRect(0, 0, getWidth(), getHeight()); 
     g2.setPaint(Color.black); 
     g2.setClip(outside); 
     g2.drawLine(0, 0, getWidth(), getHeight()); 

    } 


    private Area calculateRectOutside(Rectangle2D r) { 
     Area outside = new Area(new Rectangle2D.Double(0, 0, getWidth(), getHeight())); 
     outside.subtract(new Area(r)); 
     return outside; 
    } 

} 
+0

ありがとう、完璧! – tuler

+1

+1 - 私よりもはるかに優れています:) – banjollity

+0

エリアメソッドは読みやすさと拡張性の点で優れています(任意のシェイプを作成して外側にクリップすることができます)が、パフォーマンス上の問題があるかもしれません(Areaクラスは少しです多分トップの上に)。クリップを何度も描画し、他の方法が高速であるかどうかを確認する必要がある場合は、ベンチマークする必要があります。 –

3

これはAWTクリップで行うことができます。除外する矩形の境界と描画領域の外側境界を知る必要があります。

次のデモコードはフレームを開き、その中に単一のパネルを表示します。パネルのペイントメソッドは、真ん中に長方形の穴がある四角形のように見えるサンプルクリップを設定します。実際には、除外したい領域の周囲の領域を表すポリゴンです。 clip rectangleは、除外された矩形の境界と描画領域の外側の境界で構成されている必要がありますが、ハードコードされた値をそのまま残しておくだけで、作業をよりよく説明できます(私も願っています)。

 
+-------------------+ 
| clip drawing area | 
+---+-----------+ | 
| | excluded | | 
| | area | | 
| +-----------+ | 
|     | 
+-------------------+ 

この方法は、すべてのAWTペイントが除外領域に入るのを防ぐという点で、手動で線の交点を計算することよりも利点があります。それがあなたにとって有用かどうかは分かりません。

私のデモでは、黒い矩形が全体の領域に塗りつぶされ、1つの白い対角線がクリップを通って描かれ、クリップの動作を示しています。

public class StackOverflow extends JFrame { 
    public static void main(String[] args) { 
     new StackOverflow(); 
    } 

    private StackOverflow() { 
     setTitle("Clip with a hole"); 
     setSize(320,300); 
     getContentPane().add(new ClipPanel()); 
     setVisible(true); 
    } 
} 

class ClipPanel extends JPanel { 
    @Override 
    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 

     Polygon clip = new Polygon(
       new int[]{ 0, 100, 100, 0, 0, 20, 20, 80, 80, 0 }, 
       new int[]{ 0, 0, 60, 60, 20, 20, 40, 40, 20, 20 }, 
       10 
      ); 
     g.setClip(clip); 
     g.setColor(Color.BLACK); 
     g.fillRect(0,0,100,60); 
     g.setColor(Color.WHITE); 
     g.drawLine(0,0,100,60); 
    } 
} 
+0

また、正しいです。しかし、減算を使用するので、他の方が簡単です。ありがとう。 – tuler

+0

うんSavvas Dalkitsisの答えははるかに良いです。 – banjollity

+0

+1。この回答はほとんど動作し、J2ME PPでサポートされているAPIを使用しています。私は、囲まれたポリゴンを作成するために0,20で形状を開始しなければならないことがわかった。完全な作業コードは私の質問です:http://stackoverflow.com/questions/1273688/is-there-any-way-to-have-an-inverted-clip-region-for-painting-in-java –

関連する問題