2010-03-20 61 views
1

我需要繪製自定義形狀。現在,當用戶點擊面板上的幾個點時,我使用多邊形創建一個形狀。的Java Swing自定義形狀(2D圖形)

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

但我不知道這是否是繪製自定義形狀的最佳方式。

應該可以編輯繪製的圖形

  • 調整
  • 改變其填充顏色
  • 改變筆觸顏色
  • 複製/粘貼
  • 移動單多邊形
  • 的點...

我看到人們創建自己的類實現Shape類和使用的GeneralPath。但我不知道這是否是一個好方法。

現在我可以創建自己的形狀與多邊形(或與GeneralPath),但我不知道如何將所有編輯功能附加到我自己的形狀(編輯功能我的意思是調整大小,移動等從以上)

我希望有人能告訴我一個辦法做到這一點也許寫的代碼,一點點地證明這一點。

在此先感謝!

回答

5

在回答你的問題,我肯定會做你形容一個作爲AWT的解決方案 - 這樣你可以跟蹤創建的對象,並能夠讓用戶重新加載到編輯畫布而更可能每個用戶創建將是一個「層」,而不是搖擺層容器形狀,但是這將存儲和跟蹤繪製什麼形狀,並能重繪他們的對象 - 主要的事情要記住是「繪製順序」。基本上你可以做到這一點,通過分配每個對象或一組對象是你的「形狀」,以便有一個Z = [0-100]等(100,可以是任何數字),它決定了每個對象/形狀的順序被吸引進來,因此他們如何相互打好對方。

基本上你將需要一個形狀類存儲

應該可以編輯繪製 形狀:

調整大小改變其填滿顏色變化 筆觸顏色複製/粘貼它移動了一個 單點的多邊形...

你勾畫了一個存儲對象/管理器,它將枚舉形狀類對象/創建的實例。這些類將或多或少地包含在java.awt.Canvas容器中,該容器實際上可以處理所有的圖形。

晴你想使用過的Swing AWT由於Swing不是線程安全的 - 這樣你不「畫自己在角落裏」在設計早期。另一個原因是這是一種需要以用戶習慣的方式進行響應和交互的實現。 Swing是建立在AWT上的,並且增加了很多複雜性,像這樣的應用程序並不需要。在你將要創建一個類的自定義組件,這正是Canvas對象是平均到 提供,如果太陽會這個機智早些時候保持他們不會都涌入了 混亂鞦韆竟然是。開發人員社區 - 我自己包括 - 很好地創造了許多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組件的類 - 它應該是罰款或者搖擺/ 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

我重新格式化了您的示例;如果不正確請回復。 Wintermute! – trashgod 2010-03-20 21:09:42

+0

謝謝!我是一名Java初學者,但我會檢查這個代碼,我想它會幫助我很多! 現在調查這個代碼是如何工作的,並嘗試修改它,以便它符合我的需求。 (和框架,以及我寧願現在不使用它們)) – juFo 2010-03-20 21:20:29

+0

謝謝trashgod我有點快 - 它確實仍然編譯 - 因爲我從一個相當複雜的GUI框架中抽象出來我寫了一段時間後,再加上我仍然得到這個網站提供的編輯能力仍然懸而未決。 juFo:非常歡迎。多年來,我一直都是Java的佼佼者。爲此,任何機會我都可以讓別人認爲它不僅僅是獲得「快速」解決方案的一種方式,而是希望真正把它理解爲對大多數問題空間的整體解決方案。 – Wintermut3 2010-03-20 22:14:57

2

你有沒有看Graphics類在Java中(也有Polygon類)?有繪製和填充多邊形方法,每個方法都可以採用x座標和y座標的數組。通過使用這些數組,你應該能夠相當容易地改變點的位置。就像你可以通過平均移動所有點一樣來改變它們的大小,或者複製和粘貼。改變顏色就像填充新顏色和重新繪製一樣簡單。

+0

而當我想調整它的大小我想自定義光標和邊界框來顯示我可以在哪裏點擊並拖動來調整它的大小,我該怎麼做? – juFo 2010-03-20 16:13:22

+0

您可以更改事件上的光標。就像你可以添加一個鼠標點擊偵聽器,或鼠標拖動偵聽器,或類似的東西。當您在繪畫方法中拖動鼠標時,您可以設置一些布爾變量。所以,如果你拖動,你可以在你想要的地方繪製你的邊界框,或者做同樣類型的東西來切割和粘貼。 – 2010-03-20 17:39:56

+0

http://blog.codebeach.com/2008/02/using-custom-cursors-in-java。html 這是顯示如何使用自定義光標的鏈接。 – 2010-03-20 17:43:34