2013-05-10 58 views
1

我想創建一個類似於Paint的應用程序,其中我必須使用一些基本形狀來創建更復雜的應用程序。使用幾何形狀作爲組件

我將使用Swing。我必須能夠將對象從一個JEditorPane拖放到另一個。我想要使​​用諸如線或圓的圖元。

我想知道的是 - 爲了能夠拖放它們,基元是否必須是組件?如果是這樣,我怎麼能做到這一點?

+0

可能是的,因爲這個類有'processMouseMotionEvent()'方法,這意味着它可以獲得這樣的鼠標事件並且可以拖放拖放。 – 2013-05-10 10:24:58

回答

4

其實我正打算做的「播放形狀」本週末博客條目。我有一個從Shape創建組件的類。該組件是直接使用:

ShapeComponent component = new ShapeComponent(shape,Color。???);

下面是代碼的早期發行版:

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Insets; 
import java.awt.Rectangle; 
import java.awt.RenderingHints; 
import java.awt.Shape; 
import javax.swing.JComponent; 

/** 
* A component that will paint a Shape object. Click detection will be 
* determined by the Shape itself, not the bounding Rectangle of the Shape. 
* 
* Shape objects can be created with an X/Y offset. These offsets will 
* be ignored and the Shape will always be painted at (0, 0) so the Shape is 
* fully contained within the component. 
* 
* The foreground color will be used to "fill" the Shape. 
*/ 
public class ShapeComponent extends JComponent 
{ 
    private Shape shape; 
    private boolean antiAliasing = true; 

    /** 
    * Create a ShapeComponent that is painted black. 
    * 
    * @param shape the Shape to be painted 
    */ 
    public ShapeComponent(Shape shape) 
    { 
     this(shape, Color.BLACK); 
    } 

    /** 
    * Create a ShapeComponent that is painted filled and outlined. 
    * 
    * @param shape the Shape to be painted 
    * @param color the color of the Shape 
    */ 
    public ShapeComponent(Shape shape, Color color) 
    { 
     setShape(shape); 
     setForeground(color); 

     setOpaque(false); 
    } 

    /** 
    * Get the Shape of the component 
    * 
    * @returns the the Shape of the compnent 
    */ 
    public Shape getShape() 
    { 
     return shape; 
    } 

    /** 
    * Set the Shape for this component 
    * 
    * @param shape the Shape of the component 
    */ 
    public void setShape(Shape shape) 
    { 
     this.shape = shape; 
     revalidate(); 
     repaint(); 
    } 

    /** 
    * Use AntiAliasing when painting the shape 
    * 
    * @returns true for AntiAliasing false otherwise 
    */ 
    public boolean isAntiAliasing() 
    { 
     return antiAliasing; 
    } 

    /** 
    * Set AntiAliasing property for painting the Shape 
    * 
    * @param antiAliasing true for AntiAliasing, false otherwise 
    */ 
    public void setAntiAliasing(boolean antiAliasing) 
    { 
     this.antiAliasing = antiAliasing; 
     revalidate(); 
     repaint(); 
    } 

    /** 
    * {@inheritDoc} 
    */ 
    @Override 
    public Dimension getPreferredSize() 
    { 
     // Include Border insets and Shape bounds 

     Insets insets = getInsets(); 
     Rectangle bounds = shape.getBounds(); 

     // Determine the preferred size 

     int width = insets.left + insets.right + bounds.width; 
     int height = insets.top + insets.bottom + bounds.height; 

     return new Dimension(width, height); 
    } 

    /** 
    * {@inheritDoc} 
    */ 
    @Override 
    public Dimension getMinimumSize() 
    { 
     return getPreferredSize(); 
    } 

    /** 
    * {@inheritDoc} 
    */ 
    @Override 
    public Dimension getMaximumSize() 
    { 
     return getPreferredSize(); 
    } 

    @Override 
    protected void paintComponent(Graphics g) 
    { 
     super.paintComponent(g); 

     // Graphics2D is required for antialiasing and painting Shapes 

     Graphics2D g2d = (Graphics2D)g.create(); 

     if (isAntiAliasing()) 
      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 

     // Shape translation (ie. non-zero X/Y position in bounding rectangle) 
     // and Border insets. 

     Rectangle bounds = shape.getBounds(); 
     Insets insets = getInsets(); 

     // Do all translations at once 

     g2d.translate(insets.left - bounds.x, insets.top - bounds.y); 

     // Fill the Shape 

     g2d.fill(shape); 

     g2d.dispose(); 
    } 

    /** 
    * Determine if the point is in the bounds of the Shape 
    * 
    * {@inheritDoc} 
    */ 
    @Override 
    public boolean contains(int x, int y) 
    { 
     Rectangle bounds = shape.getBounds(); 
     Insets insets = getInsets(); 

     // Check to see if the Shape contains the point. Take into account 
     // the Shape X/Y coordinates, Border insets and Shape translation. 

     int translateX = x + bounds.x - insets.left; 
     int translateY = y + bounds.y - insets.top; 

     return shape.contains(translateX, translateY); 
    } 
} 

它會幫助你與你的問題的組成部分。

1
  1. 您可以使用JPanel作爲區域繪製形狀
  2. 隨着JPanel,你不能把一些形狀的正面和背面。因此,理想的選擇是通過設置適當的Z-爲了使用JLayeredPane使拉絲後,你可以有選擇移動的形狀的正面和背面
  3. 當你描繪每一個新的形狀,添加在JLayeredPaneJPanel基於鼠標點擊位置。這樣做可以使內部和跨多個形狀的移動方便JLayeredPane小號