[英]Java Swing custom shapes (2D Graphics)
我需要繪制自定義形狀。 現在,當用戶點擊面板上的幾個點時,我使用多邊形創建一個形狀。
public void mouseClicked(MouseEvent e) {
polygon.addPoint(e.getX(), e.getY());
repaint();
}
但我不知道這是否是繪制自定義形狀的最佳方式。
應該可以編輯繪制的形狀 :
我見過人們創建一個自己的類來實現Shape類並使用GeneralPath。 但我再也不知道這是不是一個好方法。
現在我可以使用多邊形(或使用GeneralPath)創建自己的形狀,但我不知道如何將所有編輯功能附加到我自己的形狀(編輯功能,我的意思是從上面調整大小,移動等) 。
我希望有人能告訴我這樣做的方法,或者寫一些代碼來證明這一點。
提前致謝!!
在回答你的問題時,我肯定會做你所描述的AWT解決方案 - 這樣你就可以跟蹤創建的對象並允許用戶將它們重新加載到編輯畫布上,而且很可能每個形狀都是user create是一個“圖層”而不是Layer Swing Container,但是一個對象可以存儲和跟蹤繪制的形狀並能夠重繪它們 - 要記住的主要是“繪制順序”。 基本上你可以通過指定作為你的“形狀”的每個對象或對象組來具有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並根據需要使用它......
首先是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<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;
}
}
你有沒有看過java中的Graphics類(還有一個Polygon類)? 有繪制和填充多邊形方法,每個方法都可以采用x坐標和y坐標的數組。 通過使用這些數組,您應該能夠非常輕松地更改點的位置。 就像你可以通過重新調整大小來平等地改變所有這些,或者通過平均移動所有點來復制和粘貼。 改變顏色就像填充新顏色和重新塗漆一樣容易。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.