[英]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. 它将帮助您解决问题的组成部分。
JPanel
as the area for drawing shapes JPanel
用作绘制形状的区域 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顺序来前后移动形状。 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.