用Java创建可拖动和可调整大小的组件

时间:2014-11-12 16:05:20

标签: java swing piccolo

如何创建可在Java Swing中拖动和调整大小的组件?

喜欢"文字工具" MS Paint中的文本框功能,在图像中以红色边框突出显示。

我只想要拖动和调整大小功能,而不是文本格式化。

如何使用Java Swing实现此组件?

Component is highlighted by red border

1 个答案:

答案 0 :(得分:0)

为了解决这个问题,我找到了Piccolo2d ZUI库。

确切地说,我在寻找什么!但是,实施" Draggable& amp;可能不是最佳方法。可调整大小的文本框" ,但我使用Piccolo2d在一小时内完成了它。所以,我在这里发布代码,如果有人能发现它有用。

以下是示例应用程序的屏幕截图! Draggable & Resizable Box using Piccolo2d

我试图让代码尽可能可描述,所以它有点长。

您需要piccolo2d-core-XXX.jar& piccolo2d-extras-XXX.jar运行此代码,可以从Maven Central Repository下载。我使用的是版本3.0&没有测试任何其他版本!

自定义组件类

class PBox extends PNode {

    private PCanvas canvas;

    private Rectangle2D rectangle;

    private Cursor moveCursor;

    public PBox(PCanvas canvas) {           
        this(0, 0, 50, 50, canvas);         
    }

    public PBox(double x, double y, double width, double height, PCanvas canvas) {
        this.canvas = canvas;
        rectangle = new Rectangle2D.Double();
        moveCursor = Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR);

        addAnchors(x, y, width, height);
        setBounds(x, y, width, height);
        setInputEventListener();
    }

    private void addAnchors(double x, double y, double width, double height) {
        addChild(new Anchor(SwingConstants.NORTH));
        addChild(new Anchor(SwingConstants.NORTH_EAST));
        addChild(new Anchor(SwingConstants.EAST));
        addChild(new Anchor(SwingConstants.SOUTH_EAST));
        addChild(new Anchor(SwingConstants.SOUTH));
        addChild(new Anchor(SwingConstants.SOUTH_WEST));
        addChild(new Anchor(SwingConstants.WEST));
        addChild(new Anchor(SwingConstants.NORTH_WEST));
    }

    private void setInputEventListener() {
        addInputEventListener(new PBasicInputEventHandler() {

            @Override
            public void mouseEntered(PInputEvent event) {
                canvas.setCursor(moveCursor);
            }

            @Override
            public void mouseExited(PInputEvent event) {
                canvas.setCursor(Cursor.getDefaultCursor());
            }

            @Override
            public void mouseDragged(PInputEvent event) {
                PDimension delta = event.getDeltaRelativeTo(PBox.this);
                translate(delta.width, delta.height);
                event.setHandled(true);
            }

        });
    }

    @Override
    protected void layoutChildren() {
        Iterator iterator = getChildrenIterator();
        int position = SwingConstants.NORTH;
        while (iterator.hasNext()) {
            PNode anchor = (PNode) iterator.next();
            anchor.setBounds(getAnchorBounds(position));
            ++position;
        }
    }

    private Rectangle2D getAnchorBounds(int position) {             
        double x = 0, y = 0;
        Rectangle2D b = getBounds();

        switch (position) {                 
        case SwingConstants.NORTH:
            x = b.getX()+b.getWidth()/2;
            y = b.getY();
            break;

        case SwingConstants.NORTH_EAST:
            x = b.getX()+b.getWidth();
            y = b.getY();
            break;

        case SwingConstants.EAST:
            x = b.getX()+b.getWidth();
            y = b.getY()+b.getHeight()/2;
            break;

        case SwingConstants.SOUTH_EAST:
            x = b.getX()+b.getWidth();
            y = b.getY()+b.getHeight();
            break;

        case SwingConstants.SOUTH:
            x = b.getX()+b.getWidth()/2;
            y = b.getY()+b.getHeight();
            break;

        case SwingConstants.SOUTH_WEST:
            x = b.getX();
            y = b.getY()+b.getHeight();
            break;  

        case SwingConstants.WEST:
            x = b.getX();
            y = b.getY()+b.getHeight()/2;
            break;              

        case SwingConstants.NORTH_WEST:
            x = b.getX();
            y = b.getY();
            break;
        }

        return new Rectangle2D.Double(x-2, y-2, 4, 4);
    }

    @Override
    public boolean setBounds(double x, double y, double width, double height) {
        if (super.setBounds(x, y, width, height)) {
            rectangle.setFrame(x, y, width, height);
            return true;
        }
        return false;
    }

    @Override
    public boolean intersects(Rectangle2D localBounds) {
        return rectangle.intersects(localBounds);
    }

    @Override
    protected void paint(PPaintContext paintContext) {
        Graphics2D g2 = paintContext.getGraphics();
        g2.setPaint(Color.BLACK);
        g2.setStroke(new BasicStroke(1.0f,
                BasicStroke.CAP_BUTT,
                BasicStroke.JOIN_MITER,
                1.0f, new float[]{4.0f}, 0));
        g2.draw(rectangle);
    }

    class Anchor extends PNode {

        private Rectangle2D point;

        private Cursor resizeCursor;

        Anchor(int position) {
            point = new Rectangle2D.Double();
            setCursor(position);
            setInputEventListener(position);
        }

        private void setCursor(int position) {
            switch (position) {                 
            case SwingConstants.NORTH:
                resizeCursor = Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR);
                break;

            case SwingConstants.NORTH_EAST:
                resizeCursor = Cursor.getPredefinedCursor(Cursor.NE_RESIZE_CURSOR);
                break;

            case SwingConstants.EAST:
                resizeCursor = Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR);
                break;

            case SwingConstants.SOUTH_EAST:
                resizeCursor = Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR);
                break;

            case SwingConstants.SOUTH:
                resizeCursor = Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR);
                break;

            case SwingConstants.SOUTH_WEST:
                resizeCursor = Cursor.getPredefinedCursor(Cursor.SW_RESIZE_CURSOR);
                break;  

            case SwingConstants.WEST:
                resizeCursor = Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR);
                break;              

            case SwingConstants.NORTH_WEST:
                resizeCursor = Cursor.getPredefinedCursor(Cursor.NW_RESIZE_CURSOR);
                break;

            default:
                resizeCursor = Cursor.getDefaultCursor();
            }
        }

        private void setInputEventListener(final int position) {
            addInputEventListener(new PBasicInputEventHandler() {

                @Override
                public void mouseEntered(PInputEvent event) {
                    canvas.setCursor(resizeCursor);
                    event.setHandled(true);
                }

                @Override
                public void mouseExited(PInputEvent event) {
                    canvas.setCursor(Cursor.getDefaultCursor());
                    event.setHandled(true);
                }

                @Override
                public void mouseDragged(PInputEvent event) {
                    PDimension delta = event.getDeltaRelativeTo(Anchor.this);
                    PNode parent = getParent();

                    if (position == SwingConstants.EAST
                            || position == SwingConstants.NORTH_EAST
                            || position == SwingConstants.SOUTH_EAST) {
                        parent.setWidth(parent.getWidth() + delta.width);
                    } else if (position == SwingConstants.WEST
                            || position == SwingConstants.NORTH_WEST
                            || position == SwingConstants.SOUTH_WEST) {
                        parent.setX(parent.getX() + delta.width);
                        parent.setWidth(parent.getWidth() - delta.width);
                    }

                    if (position == SwingConstants.SOUTH
                            || position == SwingConstants.SOUTH_EAST
                            || position == SwingConstants.SOUTH_WEST) {
                        parent.setHeight(parent.getHeight() + delta.height);
                    } else if (position == SwingConstants.NORTH
                            || position == SwingConstants.NORTH_EAST
                            || position == SwingConstants.NORTH_WEST) {
                        parent.setY(parent.getY() + delta.height);
                        parent.setHeight(parent.getHeight() - delta.height);
                    }

                    event.setHandled(true);
                }

            });
        }

        @Override
        public boolean setBounds(double x, double y, double width, double height) {
            if (super.setBounds(x, y, width, height)) {
                point.setFrame(x, y, width, height);
                return true;
            }
            return false;
        }

        @Override
        public boolean intersects(Rectangle2D localBounds) {
            return point.intersects(localBounds);
        }

        @Override
        protected void paint(PPaintContext paintContext) {
            Graphics2D g2 = paintContext.getGraphics();
            g2.setColor(Color.WHITE);
            g2.fill(point);
            g2.setStroke(new BasicStroke(1.0f));
            g2.setColor(Color.BLACK);
            g2.draw(point);
        }

    }

}

而且,主要的课程

public class Piccolo2DExample extends PFrame {

    @Override
    public void initialize() {
        PCanvas canvas = getCanvas();

        PNode text = new PText("Draggable & Resizable Box using Piccolo2d");
        text.scale(2.0);
        canvas.getCamera().addChild(text);

        PLayer layer = canvas.getLayer();

        PNode aLayerNode = new PText("A_Layer_Node");
        aLayerNode.setOffset(10, 50);
        layer.addChild(aLayerNode);

        // Adding the component to layer
        layer.addChild(new PBox(50, 100, 250, 50, canvas));
    }

    public static void main(String[] args) {
        PFrame frame = new Piccolo2DExample();
        frame.setSize(800, 640);
    }

}