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

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

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

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

应该可以编辑绘制的形状

  • 调整
  • 改变它的填充颜色
  • 改变笔画颜色
  • 复制/粘贴它
  • 移动多边形的单个点

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

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

我希望有人可以告诉我一个方法来做到这一点,或者写一些代码来certificate这一点。

提前致谢!!

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

基本上你需要一个存储的形状类

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

resize更改其填充颜色更改笔触颜色复制/粘贴它移动多边形的单个点…

您概述了一个存储对象/管理器,它将枚举创建的形状类对象/实例。 这个类或多或少会被一个实际处理所有图形的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并根据需要使用它……

首先是Listener接口:

 /* * 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 listeners = new HashSet(); 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 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; } } 

ImageJ项目具有一个特别好的多边形工具实现,具有可调顶点,如此处和此处所示 。

替代文字http://sofzh.miximages.com/java/juy1q0.png

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