2009-08-06 32 views
9

java.awt.Graphics kullanarak bir çizgi çizmem gerekiyor, ancak yalnızca dikdörtgenin dışında kalan satırın bir kısmı oluşturulmalıdır.Java Grafikle kırpma

o Grafik kırpma destek kullanmak ya da kendim kesişim hesaplar ve çizgi klibi gerekiyor mümkün mü?

cevap

10

Area sınıfını kullanmanız gerekir. Bu örnekte, sorduklarınızı nasıl yapacağınızı göstereceğiz:

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

Teşekkürler, mükemmel! – tuler

+1

+1 - Benimkinden çok daha iyi :) – banjollity

+0

Alan yöntemi okunabilirlik ve genişletilebilirlik açısından daha iyidir (dışına herhangi bir şekil ve klip oluşturabilir) ancak bazı performans sorunları olabileceğini düşünüyorum (Alan sınıfı biraz üstte belki). Klibi bir çok kez çizmeniz gerekiyorsa ve diğer yöntemin daha hızlı olup olmadığına bakın. –

3

Bunu bir AWT klibi ile yapabilirsiniz. Dışlamak istediğiniz dikdörtgenin sınırlarını ve çizim alanınızın dış sınırlarını bilmeniz gerekir.

Aşağıdaki demo kodu bir çerçeve açar ve içine tek bir panel görüntüler. Panelin boya metodu, ortada dikdörtgen bir delik bulunan dikdörtgen gibi görünen bir örnek klibi, aslında dışlamak istediğimiz alanın etrafındaki alanı tanımlayan bir poligon oluşturuyor. klip dikdörtgen dışlanan dikdörtgenin ve çizim alanının dış kenarı sınırları oluşmalıdır, ama basit tutmak ve işleyişini daha iyi göstermek için sabit kodlu değerler bıraktım (umarım!)

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

Bu yöntem o dışlanmış sahasına girmeden tüm AWT boyama önlediğini elle hat kesişim hesaplanması üzerine yararı vardır. Bunun senin için yararlı olup olmadığını bilmiyorum.

Benim demo sonra tüm alanı üzerinde siyah bir dikdörtgen boyalar ve tek beyaz diyagonal çizgi klip çalışma göstermek için, üzerinden çalışan.

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

Ayrıca, doğru. Ama diğeri daha kolay çünkü çıkarmayı kullanıyor. Teşekkürler. – tuler

+0

Evet Savvas Dalkitsis'in cevabı çok daha iyi. – banjollity

+0

+1. Bu cevap neredeyse işe yarıyor ve J2ME PP tarafından desteklenen API'leri kullanıyor. Kapalı bir çokgen oluşturmak için şekli 0,20'de başlatmak zorunda kaldım. Komple çalışma kodu şu sorularımda: http://stackoverflow.com/questions/1273688/is-there-any-way-to-have-an-inverted-clip-region-for-painting-in-java –