2009-08-06 17 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 2009-08-06 22:55:58

+1

+1 - 比我的好多了:) – banjollity 2009-08-07 07:44:21

+0

Area方法在可讀性和可擴展性方面更好(可以在其外部創建任何形狀和片段),但我認爲它可能存在一些性能問題(Area類有點也許在頂部)。如果您需要多次繪製剪輯並查看其他方法是否更快,則應該對其進行基準測試。 – 2009-08-07 10:56:00

3

你可以用AWT剪輯做到這一點。您需要知道要排除的矩形邊界以及繪圖區域的外邊界。

下面的演示代碼打開一個框架並在其中顯示一個面板。面板的繪畫方法設置了一個示例剪輯,它看起來像一箇中間有矩形孔的矩形,實際上它是一個描述我們想要排除的區域周圍的區域的多邊形。剪切矩形應該由排除的矩形的邊界和繪圖區域的外邊緣組成,但我留下了硬編碼的值以保持簡單並更好地說明了工作方式(我希望!)

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

該方法比手動計算直線交點有好處,因爲它可以防止所有AWT繪畫進入排除區域。我不知道這對你有沒有用。

我的演示接着在整個區域繪製一個黑色矩形,並穿過一條單一的白色對角線來說明剪輯的工作原理。

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 2009-08-06 22:55:28

+0

是的,Savvas Dalkitsis的答案好多了。 – banjollity 2009-08-07 07:43:34

+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 – 2009-08-13 22:55:38