代码之家  ›  专栏  ›  技术社区  ›  juFo

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

  •  2
  • juFo  · 技术社区  · 14 年前

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

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

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

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

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

    我见过有人创建自己的类来实现shape类并使用generalpath。但我还是不知道这是不是个好办法。

    现在我可以用一个多边形(或者一个通用路径)创建自己的形状,但是我不知道如何将所有的编辑函数附加到自己的形状上 (编辑功能我指的是从上面调整大小、移动等) .

    我希望有人能给我展示一种方法,或者写一点代码来演示。

    提前谢谢!!

    3 回复  |  直到 14 年前
        1
  •  5
  •   trashgod    14 年前

    在回答您的问题时,我绝对会按照您所描述的awt解决方案来做——这样您就可以跟踪创建的对象,并允许用户将它们重新加载到编辑画布上,而且很可能用户创建的每个形状都是一个“层”,而不是swing包含的层。呃,但是一个可以存储和跟踪所绘制形状并能够重新绘制它们的对象——需要记住的主要事情是“绘制顺序”。基本上,您可以通过将每个对象或作为“形状”的对象组指定为z=[0-100]等(100,可以是任意数字),以确定每个对象/形状的绘制顺序以及它们如何重叠。

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

    应该可以编辑绘图 形状:

    调整大小更改其填充颜色更改 笔划颜色复制/粘贴 多边形的单点…

    您概述了存储对象/管理器,它将枚举创建的形状类对象/实例。这些类将或多或少地包含在java.awt.canvas容器中,该容器将实际处理所有图形。

    大多数情况下,您希望使用awt over swing,因为swing不是线程安全的——这样您就不会在设计的早期就“在角落里画画”。另一个原因是,这是一个需要以用户习惯的方式响应和交互的实现。swing是在awt之上构建的,它增加了很多这样的应用程序不需要的复杂性。总之,您将创建一个类自定义组件,这正是canvas对象的意义所在 如果孙能早点保持这种机智,他们就不会进入 结果那个秋千一团糟…包括我在内的开发人员社区已经在创造swing在“灵活”和基于组件的设计中所提供的很多东西的路上了,但是我们所构建的完全是基于awt的。当Swing进入场景时,Java作为一个GUI平台变得非常复杂,并且启动Sun和Java走上了一条很滑的路径…

    此外,你必须决定你最终想要什么,以控制你在这里创造的东西。如果您需要它的速度很快,并且不想在将来修改它,那么有很多开源的例子可以做到这一点——大多数都是免费的。如果你想自己做,那么希望我上面所说的话和下面的橡皮带代码就足够让你了解和理解Java作为GUI。我个人希望你能自己理解这门语言——这门语言迫切需要更多真正理解语言及其设计的“核心”人员,而不仅仅是如何“工作”hibernate和spring等框架……

    祝你好运希望这有帮助,

    西米

    至于“橡皮筋”的选择代码,这是我的我在过去使用过,只要考虑它的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;
        }
    }
    
        2
  •  3
  •   trashgod    14 年前

    这个 ImageJ 项目有一个特别好的实现 Polygon tool 具有可调整顶点,如图所示 here here .

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

        3
  •  2
  •   John Kane    14 年前

    你看过Java中的图形类(还有一个多边形类)吗?有绘制和填充多边形的方法,每个方法都可以采用x坐标和y坐标数组。通过使用这些数组,您应该能够相当容易地更改点的位置。就像你可以改变它们的大小一样,或者复制和粘贴,只需同样移动所有的点。改变颜色就像用新颜色填充和重新上漆一样简单。