Java Swing自定义形状(2D图形)

时间:2010-03-20 15:11:42

标签: java swing drawing 2d

我需要绘制自定义形状。现在,当用户点击面板上的几个点时,我使用多边形创建一个形状。

public void mouseClicked(MouseEvent e) {
            polygon.addPoint(e.getX(), e.getY());
            repaint();
        }

但我不知道这是否是绘制自定义形状的最佳方式。

应该可以编辑绘制的形状

  • 调整大小
  • 更改其填充颜色
  • 更改笔触颜色
  • 复制/粘贴
  • 移动多边形的单个点
  • ...

我见过人们创建一个自己的类来实现Shape类并使用GeneralPath。但我再也不知道这是不是一个好方法。

现在我可以使用多边形(或使用GeneralPath)创建自己的形状,但我不知道如何将所有编辑功能附加到我自己的形状(编辑功能我的意思是调整大小,移动等等从上面)

我希望有人能告诉我这样做的方法,或者写一些代码来证明这一点。

提前致谢!!

3 个答案:

答案 0 :(得分:5)

在回答你的问题时,我肯定会做你所描述的AWT解决方案 - 这样你就可以跟踪创建的对象并允许用户将它们重新加载到编辑画布上,而且很可能每个用户创建的形状将是一个“图层”而不是图层Swing容器,但是一个对象可以存储和跟踪绘制的形状并能够重绘它们 - 要记住的主要事项是“绘制顺序”。基本上你可以通过指定作为你的“形状”的每个对象或对象组来具有Z = [0-100]等(100,可以是任何数字)来确定每个对象/形状的顺序。吸收,以及他们如何相互叠加。

基本上你需要一个存储

的形状类
  

应该可以编辑绘制的   形状:

     

调整大小更改其填充颜色更改   笔触颜色复制/粘贴它移动一个   多边形的单点......

您概述了一个存储对象/管理器,它将枚举创建的形状类对象/实例。这个类或多或少会被一个实际处理所有图形的java.awt.Canvas容器包含。

大多数情况下,你想在Swing上使用awt,因为Swing不是Thread安全的 - 这样你就不会在设计的早期“在角落里画画”。另一个原因是这是一种需要以用户习惯的方式响应和交互的实现。 Swing是在AWT上构建的,并且增加了像这样的应用程序不需要的大量复杂性。总而言之,您将创建一个类Custom组件,这正是Canvas对象的意思 提供,如果Sun早些时候保持这种机智,他们就不会进入 Swing的结果是......开发者社区 - 包括我自己 - 正在创造很多Swing在“光滑”和基于组件的设计中提供的东西,但我们正在构建的是完全基于AWT的。当Swing进入场景时,Java作为一个GUI平台非常复杂,让Sun和Java走上了一条滑路......

此外,您必须决定您最终想要的内容,以控制您在此处创建的内容。如果您需要快速而且不太关心将来修改它,那么有很多开源示例可以做到这一点 - 大多数是免费的。如果你想自己做,那么希望我上面谈到的内容以及下面的橡皮筋代码将足以让你在那里更深入地了解Java作为GUI。我个人希望你自己接受它 - 这种语言迫切需要更多真正理解语言及其设计的“核心”人,而不仅仅是如何“工作”像Hibernate和Spring等框架......

祝你好运,希望这会有所帮助,

WM

就“橡皮筋”选择代码来说,这是我过去使用过的,只需考虑它GLP并根据需要使用它......

首先是监听器界面:

/*
 * RubberBandListener.java
 *
 * Created on August 18, 2005, 3:27 PM
 *
 * To change this template, choose Tools | Options and locate the template under
 * the Source Creation and Management node. Right-click the template and choose
 * Open. You can then make changes to the template in the Source Editor.
 */
package com.ges.util;

import java.util.EventListener;
import java.awt.Rectangle;

/**
 *
 * @author mstemen
 */
public interface RubberBandListener extends EventListener {

    public abstract void notifyBounds(Rectangle boundingBox);
}

这是一个自定义AWT组件的类 - 它应该可以在Swing / AWT中使用,甚至可能是SWT

/*
 * RubberBandSelect.java
 *
 * Created on August 18, 2005, 9:11 AM
 * By Matthew Stemen/Wintermute Studios for util like use
 *
 */
package com.ges.util;

import javax.swing.*;
import java.awt.*;
import java.util.*;
import java.awt.event.*;

/**
 *
 * @author mstemen
 */
public class RubberBandSelect extends Component {

    /** Creates a new instance of RubberBandSelect */
    private Point startPoint = null;
    private Point endPoint = null;
    private Graphics hostGraphics = null;
    private Component hostComponent = null;
    private Color bandColor = Color.ORANGE.darker().darker();
    private boolean started = false;
    private boolean eraseSomething = false;
    private int startX, endX, startY, endY = 0;
    private Rectangle boundingBox;
    private StringBuilder QuadrantMessage = null;
    private HashSet<RubberBandListener> listeners =
        new HashSet<RubberBandListener>();
    private int width = 0;
    private int height = 0;

    public RubberBandSelect(Component c) {
        hostComponent = c;
        hostGraphics = c.getGraphics();
    }

    public void addListener(RubberBandListener l) {
        listeners.add(l);
    }

    public void paint(Graphics g) {
        draw();
    }

    public void erase() {
        if (eraseSomething) {
//            hostComponent.repaint();
            draw();
            eraseSomething = false;
        }
    }

    private void draw() {
        hostGraphics = hostComponent.getGraphics();
        if (hostGraphics != null) {
            try {
                /// hostGraphics.setXORMode( hostComponent.getBackground() );
                erase();
                drawRubberBand();
                eraseSomething = false;
            } finally {
//                hostGraphics.dispose();
            }
        }
    }

    private void drawRubberBand() {
        if (!started) {
            return;
        }

        hostGraphics = hostComponent.getGraphics();
        if (hostGraphics == null) {
            return;
        }

        if (startPoint == null || endPoint == null) {
            return;
        }

        hostGraphics.setColor(bandColor);

        if (endX > startX && endY > startY) {
            boundingBox = new Rectangle(startX, startY, endX - startX, endY - startY);
            hostGraphics.drawRect(startX, startY, endX - startX, endY - startY);

            QuadrantMessage = new StringBuilder("Drawing in Q - IV X1=");
            width = endX - startX;
            height = endY - startY;
            //UDTMgr.getMgr().sendStatusMessage( "Drawing Rect: " + "(X1=" + startX + ",Y1=" + startY + ") (X2=" + endX + ",Y2=" + endY + ")"  );
        } else if (endX < startX && endY < startY) {
            boundingBox = new Rectangle(endX, endY, startX - endX, startY - endY);
            hostGraphics.drawRect(endX, endY, startX - endX, startY - endY);
            //UDTMgr.getMgr().sendStatusMessage( "Drawing Rect: " + "(X1=" + startX + ",Y1=" + startY + ") (X2=" + endX + ",Y2=" + endY + ")"  );
            QuadrantMessage = new StringBuilder("Drawing in Q - II X1=");
            width = startX - endX;
            height = startY - endY;

        } else if (endX > startX && endY < startY) {
            boundingBox = new Rectangle(startX, endY, endX - startX, startY - endY);
            hostGraphics.drawRect(startX, endY, endX - startX, startY - endY);
            //UDTMgr.getMgr().sendStatusMessage( "Drawing Rect: " + "(X1=" + startX + ",Y1=" + startY + ") (X2=" + endX + ",Y2=" + endY + ")"  );
            QuadrantMessage = new StringBuilder("Drawing in Q - I X1=");
            width = endX - startX;
            height = startY - endY;
        } else if (endX < startX && endY > startY) {
            boundingBox = new Rectangle(endX, startY, startX - endX, endY - startY);
            hostGraphics.drawRect(endX, startY, startX - endX, endY - startY);
            //UDTMgr.getMgr().sendStatusMessage( "Drawing Rect: " + "(X1=" + startX + ",Y1=" + startY + ") (X2=" + endX + ",Y2=" + endY + ")"  );
            QuadrantMessage = new StringBuilder("Drawing in Q - III X1=");
            width = startX - endX;
            height = endY - startY;
        }


    }

    public void assignToCompoent(Component c) {
        this.hostComponent = c;
        hostGraphics = c.getGraphics();
    }

    public void update(Graphics g) {
        drawRubberBand();
    }

    public Point getStartPoint() {
        return startPoint;
    }

    public void setStartPoint(Point startPoint) {
        this.startPoint = startPoint;
        startX = (int) startPoint.getX();
        startY = (int) startPoint.getY();
        QuadrantMessage = new StringBuilder();
        // UDTMgr.getMgr().sendStatusMessage( "RubberBandSelect--Started:  point is: X=" + startX + " Y=" + startY );
        // drawRubberBand();
        // started = true;
    }

    public Point getEndPoint() {
        return endPoint;
    }

    public void setEndPoint(Point endPoint) {

        this.endPoint = endPoint;
        clear();
        endX = (int) endPoint.getX();
        endY = (int) endPoint.getY();
        // UDTMgr.getMgr().sendStatusMessage( "RubberBandSelect--Streching: points are: X=" + startX + " Y=" + startY + " Ending Point is: X=" + endX + " Y="+ endY );

        draw();
        notifyListeners();
        started = true;
    }

    public Color getBandColor() {
        return bandColor;
    }

    public void setBandColor(Color bandColor) {
        this.bandColor = bandColor;
    }

    public void setForeground(Color color) {
        this.bandColor = color;

    }

    private void clear() {
        hostGraphics = hostComponent.getGraphics();
        if (hostGraphics == null) {
            return;
        }
        // hostGraphics.setXORMode( hostComponent.getBackground() );
        try {
            // hostGraphics.setXORMode( hostComponent.getBackground() );
            drawRubberBand();
        } finally {
//            hostGraphics.dispose();
        }
    }

    public void breakBand() {
        startPoint = null;
        endPoint = null;
        started = false;
        boundingBox = new Rectangle(0, 0, 0, 0);
        if (hostGraphics != null) {
            hostGraphics.dispose();
        }
        clear();
        hostComponent.repaint();
        // UDTMgr.getMgr().sendStatusMessage( "RubberBandSelect-- Broke band, click to restart" );
    }

    public boolean isStarted() {
        return started;
    }

    public void notifyListeners() {
        Iterator<RubberBandListener> it = listeners.iterator();

        while (it.hasNext()) {
            it.next().notifyBounds(boundingBox);
        }
    }

    public void redraw(Graphics g) {
        if (startPoint == null || endPoint == null) {
            return;
        }

        g.setColor(bandColor);
//        hostGraphics.setPaintMode();
        // hostComponent.repaint();
        // four way case state to determine what quadrant to draw in
        if (endX > startX && endY > startY) {
            boundingBox = new Rectangle(startX, startY, endX - startX, endY - startY);
            g.drawRect(startX, startY, endX - startX, endY - startY);

            QuadrantMessage = new StringBuilder("Drawing in Q - IV X1=");
            width = endX - startX;
            height = endY - startY;
            //UDTMgr.getMgr().sendStatusMessage( "Drawing Rect: " + "(X1=" + startX + ",Y1=" + startY + ") (X2=" + endX + ",Y2=" + endY + ")"  );
        } else if (endX < startX && endY < startY) {
            boundingBox = new Rectangle(endX, endY, startX - endX, startY - endY);
            g.drawRect(endX, endY, startX - endX, startY - endY);
            //UDTMgr.getMgr().sendStatusMessage( "Drawing Rect: " + "(X1=" + startX + ",Y1=" + startY + ") (X2=" + endX + ",Y2=" + endY + ")"  );
            QuadrantMessage = new StringBuilder("Drawing in Q - II X1=");
            width = startX - endX;
            height = startY - endY;

        } else if (endX > startX && endY < startY) {
            boundingBox = new Rectangle(startX, endY, endX - startX, startY - endY);
            g.drawRect(startX, endY, endX - startX, startY - endY);
            //UDTMgr.getMgr().sendStatusMessage( "Drawing Rect: " + "(X1=" + startX + ",Y1=" + startY + ") (X2=" + endX + ",Y2=" + endY + ")"  );
            QuadrantMessage = new StringBuilder("Drawing in Q - I X1=");
            width = endX - startX;
            height = startY - endY;
        } else if (endX < startX && endY > startY) {
            boundingBox = new Rectangle(endX, startY, startX - endX, endY - startY);
            g.drawRect(endX, startY, startX - endX, endY - startY);
            //UDTMgr.getMgr().sendStatusMessage( "Drawing Rect: " + "(X1=" + startX + ",Y1=" + startY + ") (X2=" + endX + ",Y2=" + endY + ")"  );
            QuadrantMessage = new StringBuilder("Drawing in Q - III X1=");
            width = startX - endX;
            height = endY - startY;
        }
    }

    public Rectangle getBoundingBox() {
        return boundingBox;
    }
}

答案 1 :(得分:3)

ImageJ项目具有可调顶点Polygon tool的特别好的实现,如herehere所示。

alt text http://i44.tinypic.com/juy1q0.png

答案 2 :(得分:2)

您是否看过java中的Graphics类(还有一个Polygon类)?有绘制和填充多边形方法,每个方法都可以采用x坐标和y坐标的数组。通过使用这些数组,您应该能够非常轻松地更改点的位置。就像你可以通过重新调整大小来平等地改变所有这些,或者通过平均移动所有点来复制和粘贴。改变颜色就像用新颜色填充并重新粉刷一样容易。