簡體   English   中英

使用幾何形狀作為組件

[英]Use geometric shapes as components

我試圖創建一個類似於Paint的應用程序,在其中必須使用一些基本形狀才能創建更復雜的形狀。

我將使用Swing。 我必須能夠將對象從一個JEditorPane拖放到另一個。 我想使用直線或圓形之類的圖元。

我想知道的是-原語是否必須是Components才能拖放它們? 如果是這樣,我怎么能做到這一點?

我實際上計划在本周末在“ Playing With Shapes”上做一個博客條目。 我有一個可以根據Shape創建組件的類。 該組件可以直接使用:

ShapeComponent組件=新的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. 您可以將JPanel用作繪制形狀的區域
  2. 使用JPanel ,您無法前后JPanel某些形狀。 因此,理想的選擇是使用JLayeredPane以便在繪制后可以通過設置適當的Z順序來前后移動形狀。
  3. 繪制每個新形狀時,請根據鼠標單擊的位置在JLayeredPane添加一個新的JPanel 這樣做可以輕松地在多個JLayeredPane內部和之間移動形狀。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM