简体   繁体   English

使用几何形状作为组件

[英]Use geometric shapes as components

I am trying to create an application similar to Paint, in which I must use some basic shapes in order to create more complex ones. 我试图创建一个类似于Paint的应用程序,在其中必须使用一些基本形状才能创建更复杂的形状。

I will use Swing. 我将使用Swing。 I have to be able to drag and drop objects from one JEditorPane to another. 我必须能够将对象从一个JEditorPane拖放到另一个。 I want to use primitives such as line or circle. 我想使用直线或圆形之类的图元。

What I would like to know is - must the primitives be Components in order to be able to drag and drop them? 我想知道的是-原语是否必须是Components才能拖放它们? If so, how could I achieve this? 如果是这样,我怎么能做到这一点?

I was actually planning on doing a blog entry on "Playing With Shapes" this weekend. 我实际上计划在本周末在“ Playing With Shapes”上做一个博客条目。 I have a class that creates a component out of a Shape. 我有一个可以根据Shape创建组件的类。 The component is straight forward to use: 该组件可以直接使用:

ShapeComponent component = new ShapeComponent(shape, Color.???); ShapeComponent组件=新的ShapeComponent(shape,Color。???);

Here is an early release version of the code: 这是该代码的早期版本:

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);
    }
}

It will help you with the component part of your question. 它将帮助您解决问题的组成部分。

  1. You can use JPanel as the area for drawing shapes 您可以将JPanel用作绘制形状的区域
  2. With JPanel , you cannot bring some shapes to back and front. 使用JPanel ,您无法前后JPanel某些形状。 So, ideal choice is to use JLayeredPane so that after drawing you can have options to move the shapes back and front by setting proper Z-Order 因此,理想的选择是使用JLayeredPane以便在绘制后可以通过设置适当的Z顺序来前后移动形状。
  3. When you draw every new shape, add a new JPanel in the JLayeredPane based on the mouse-click location. 绘制每个新形状时,请根据鼠标单击的位置在JLayeredPane添加一个新的JPanel Doing this will enable easy moving of the shapes inside and across multiple JLayeredPane s 这样做可以轻松地在多个JLayeredPane内部和之间移动形状。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM