您好,登錄后才能下訂單哦!
本篇內容介紹了“JAVA圖形設計卷的知識點有哪些”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
注意1:在AWT中提供的用戶接口構件(如按鈕、列表、菜單、對話框等)不包含一些類似的純粹的繪制圖形的對象(如Line或Circle類)
詳細意思:由于原始的AWT在設計時不允許純粹的繪制圖形的對象,那么Rectangle、Polygon和Point沒有任何繪制圖形的能力。換句話說,
Rectangle、Polygon和Point不具備draw方法。您可做的,僅僅是可以設置和得到它們代表的幾何實體的信息。
為了代替那些純粹的、可繪制圖形的對象,AWT使用了一種簡單的——盡管不夠靈活并且不易擴展——模式:
每個AWT構件完全來自于它自己的java.awt.Graphics對象,盡管其中的一些圖形操作可以在與之相關的構件中實現。
Graphics也可以向種各樣的輸出設備中繪制,像畫面外緩沖器和打印機——參見第24章“雙緩沖技術”和18.4節“打印”中的相關內容。
請先看兩張表(都忽略了java.awt.peer方法):
表3-1 傳遞一個對Graphics的引用的jdk方法
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
軟件包 類 方 法
─────────────────────────────────
java.awt Canvas paint(Graphics g)
Component paint(Graphics g)
Component paintAll(Graphics g)
Component print(Graphics g)
Component printAll(Graphics g)
Component update(Graphics g)
Container paint(Graphics g)
Container paintComponents(Graphics g)
Container print(Graphics g)
Container printComponents(Graphics g)
ScrollPane printComponents(Graphics g)
java.beans Property_Enditor paintValue(Graphics g,Rectangle r)
Property_EnditorSupport paintValue(Graphics g,Rectangle r)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
表3-2 返回Graphics 引用的JDK方法
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
軟件包 類 方 法
─────────────────────────────────
java.awt Component getGraphics()---(為最常使用)
Image getGraphics()
PaintJob getGraphics()
Graphics create()
Graphics create(int x,int y,int w,int h)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1.java.awt.Graphics 作用:定義一個真正的工具,用來接受圖形操作(顯示圖像和文本、繪制和填充開關、剪貼圖像操作等)
幾乎在所有的applet程序(和應用程序)中,都使用了AWT處理Graphics來為圖像服務。
某applet程序片斷:
public void paint(Graphics g){
g.drawString("Hello Graphics Java World",75,100);
...}
另外,在構件內部執行圖像操作時,每個Graphics中都保持了下面的圖形屬性:
·用來繪制和填充形狀的顏色。
·用來描述文本的字體。
·剪貼矩形。
·繪制模式(XOR或Paint)。
·用于顯示和剪貼坐標的平移原點。
2.Graphics參數
Graphics類的兩個主要的職責:
(1)設置和獲取圖形參數
(2)在輸出設備中執行圖形操作(為主)
Graphics類中使用的四個參數
表3-3
| 方法
-----------------------|----------------------------------------------------------------------------
(a)顏色 void setColoer(Color color)
Color getColor()
-----------------------|----------------------------------------------------------------------------
(b)字體 void setFont(Font f)
和 Font getFont()
-------------------------------------------------------------------
字體度量(屬性為只讀) FontMetrics getFontMetrics() 返回的字體度量,和Graphics當前的字體結合在一起
FontMetrics getFontMetrics(Font f) 返回的字體尺度和指定的字體結合在一起
-----------------------|----------------------------------------------------------------------------
(c)剪貼矩形 void setClip(int x,int y,int w,int h)
Rectangle getClipBounds()
void setClip(Shape) Shape接口是java 2D api的一部分,Shape所表示的形狀可以是非矩形的,
所以它可以為輸出設備定義一個非矩形的剪貼矩形
Shape getClip()
void clipRect(int x,int y,int w,int h) 計算一個新的剪貼矩形,該剪貼矩形是原先剪貼矩形和
方法中參數指定的剪貼矩形的交集
-----------------------|----------------------------------------------------------------------------
(d)圖形模式(屬性為只寫) void setPaintMode()(默認模式) 設置paint圖形模式,意味著后面的著色操作將改寫現有的圖形
void set setXORMode() 允許繪制和擦掉現在圖形而不干擾其下面的圖形
-----------------------|-------------------------------------------------------------------------------------------
簡單的applet例子 卻要注意:
例1.
import java.applet.Applet;
import java.awt.*;
public class RectTest extends Applet{
public void paint(Graphics g){
g.drawRect(2,2,4,4);//*****行A
}
}
file://隨便一個HTML文件如001.html,
Public void paint(Graphics g){
Dimension size=getSize();
g.drawRect(0,0,size.width-1,size.height-1);//不減一的話,右邊緣和底邊緣邊界將被繪制在構件的外面而看不到該部分。
}
把例1中的//*****行A--->g.drawRect(2,2,4,4);換成g.fillRect(2,2,4,4);
注意:此時傳遞給fillRect()的參數指定的坐標路徑與在前面調用drawRect()時指定的坐標路徑相同。但是,填充外形的Graphics
方法將填充路徑的內部,所以填充的矩形是4個像素寬和4個像素高
3.Graphics引用
有兩種方法要用到對構件的Graphics的引用。這兩種方法就是:覆蓋前面表3-1中的方法(傳遞一個對Graphics的引用),或調用表3-2
列出的方法(將返回對Graphics的引用)。值得注意的是從Component、Image和PrintJob中的getGraphics()方法返回的Graphics引
用并不是一個對Graphics引用的引用,而是返回一個初始Graphics的副本。在下面的章節中,你將會發現這是一個很重要的概念。
又一個簡單的applet例子:再強調一遍 Graphics引用引用和構件相關的真實Graphics的副本
import java.applet.Applet;
import java.awt.*;
public class CopyTest extends Applet {
public void paint(Graphics g) {
setForeground(Color.yellow);//設置其前景顏色為黃色
g.drawLine(0,0,getSize().width-1, getSize().height-1);
}
}
結果可能不像你所期待那樣:在開始畫線時,線的顏色可能不是黃的(黑色一閃,用IE看吧。)
原因:調用Component.setForeground(),改變構件中Graphics的當前顏色——在本例中,
該顏色被改變成黃色。SetFroeground()影響applet的Graphics,但并不影響傳遞給paint()
的Graphics的副本。因此,當第一次調用paint()時,線條的顏色并沒有變成黃色。當調用
drawLine()時,傳遞給paint()的Graphics和實際的Graphics并不同步。后來調用paint()時,
傳遞給paint()的是applet的Graphics的一個新副本,因此setForeground()的調用結果可以
將applet的Graphics的當前顏色改變成黃色。
如果將該applet程序改一下:
import java.applet.Applet;
import java.awt.*;
public class CopyTest2 extends Applet {
public void paint(Graphics g) {
setForeground(Color.yellow);// the next line would do just as well as the following
// g.setColor(Color.yellow);
Graphics copy = getGraphics();
try {
System.out.println("g=" + g.getColor() +" copy=" + copy.getColor());
copy.drawLine(0,0,getSize().width-1, getSize().height-1);
}
finally {
copy.dispose();
}
}
} file://那么一開始畫出的線就是黃色的,DOS下打印出:
g=java.awt.Color[r=0,g=0,b=0] copy=java.awt.Color[r=255,g=255,b=0]
g=java.awt.Color[r=255,g=255,b=0] copy=java.awt.Color[r=255,g=255,b=0]
g=java.awt.Color[r=255,g=255,b=0] copy=java.awt.Color[r=255,g=255,b=0]
解釋:傳遞給paint()的Graphics將被忽略掉,通過調用getGraphics()方法得到一個新的Graphics,
應用這個新的Graphics繪制直線。因為在調用setForeground()之后獲取Graphics,所以Graphics
當前的顏色,也就是線條的顏色,將變成黃色。
4.Graphics引用的壽命
注意:除了引用真實的副本外,傳遞給paint()和update()等方法的Graphics引用僅僅在方法的執行過程中才有效。
一旦方法返回,引用將不再有效(強行重新載入如刷新等可重繪該applet)
例子:
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
public class HoldRef extends Applet {
private Graphics oldg;
private boolean first = true;
public void paint(Graphics g) {
if(first) {
oldg = g;
first = false;
}
oldg.drawLine(0,0,getSize().width-1, getSize().height-1);
}
}
可以看出:傳遞給方法的Graphics引用壽命很短,因為它們是必須處理的有限資源,每個Graphics表示的圖像環境
是由本地的窗口系統提供的。圖像環境通常被設定在一個有限的數量內可用,而且當調用返回時傳遞Graphics引用的
調用者會很仔細地處理掉它。例如,當調用Component.Paint()返回時,調用者處理掉傳遞給paint()的Graphics。
5.雖然Java帶有垃圾收集,但是在AWT中仍有兩個地方供開發者處理有限的系統資源,處理Graphics就是其中之一
(注:窗口和對話框也必須被處理,請參見第16章“窗口、框架和對話框”)。在處理Graphics有兩個要注意的事項,
即:什么時候需要處理和怎樣處理
處理Graphics規則:如果調用表3-2列出的getGraphics方法中的一個得到一個對Graphics的引用,
或者通過Graphics.create()創建一個Graphics,那么就有責任對它們進行處理
通過調用Graphics.dispose()處理Graphics,請看某程序片斷:
public void someMethodInAComponent(){//code fragment
Graphics g=getGraphics();
if(g!=null){
try{
file://do something with g- if an exception is thrown,
file://the finally block will be executed
}
finally{
g.dispose()//crucial至關重要,因為忽略不做將會導致窗口系統用完圖形環境,這在大部分操作上會引起問題
}
}
}
file://在這里要注意的是對g不做null檢測并不是無根據的,如果在構件的同位體創建之前調用getGraphics()則它確實返回null
對Graphics.dispose()的調用被安置在finally塊中,而對Graphics的控制則在相應的try塊中執行。這保證調用dispose()
將被放在事件內,例外的情況則會被從try塊中拋出。
技巧2:《傳遞圖形引用的方法引用副本》
技巧2的使用:
Graphics表示本地圖形環境,是一個典型的有限資源。所以,被返回的Graphics引用必須通過調用Graphics.dispose()方法處理。
傳遞Graphics引用的方法,像Component.paint(),是一種不需要手工設置處理的方法——當調用返回時,方法的調用者必須處理
大家累了吧?我也是。努努力!加加油!
6.繪制和填充形狀(直線(Lines)折線(Polylines)矩形(Rectangles)弧(Arcs)橢圓(Ovals)多邊形(Polygons)文本(Text)圖像(Images))
6.1畫直線 使用方法:Graphics.drawLine(int x,int y,int x2,int y2)
AWT不能畫不固定寬度的直線,使用圖形筆所畫的直線,其寬度一般是一個像素。
線經常被繪制成實線——沒有規定線的模式,如點線或虛線。但是,在Java 2D API中,為不同的線類型和圖形筆尺寸提供廣泛的支持。
隨機直線例子:起點,長度、方向和顏色都隨機
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
public class PickupSticks extends Applet {
private static Color[] colors = {
Color.white, Color.black, Color.blue, Color.red,
Color.yellow, Color.orange, Color.cyan, Color.pink,
Color.magenta, Color.green };
public void init() {
Button button = new Button("scatter");
add(button);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
repaint();
}
});
}
public void paint(Graphics g) {
for(int i=0; i < 500; ++i) {
int x = (int)(Math.random()*100);
int y = (int)(Math.random()*100);
int deltax = (int)(Math.random()*100);
int deltay = (int)(Math.random()*100);
g.setColor(colors[(int)(Math.random()*10)]);
g.drawLine(x,y,x + deltax, y + deltay);
}
}
}
6.2畫折線 使用方法:drawPolyline(int[] xPoints,int[] yPoints,int numPoints)
一個數組指定每個點的x坐標值,另一個數組指定點的y坐標值,要畫的折線的點數
點數等于線段數+1,如果起始點和終點不重合,所畫的折線是不封閉的
折線例子:
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
public class Polylines extends Applet {
private static Color[] colors = {
Color.white, Color.black, Color.blue, Color.red,
Color.yellow, Color.orange, Color.cyan, Color.pink,
Color.magenta, Color.green };
public void init() {
Button button = new Button("repaint");
add(button);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
Polylines.this.repaint();
}
});
}
public void paint(Graphics g) {
file://int arraySize = ((int)(Math.random()*100));//原例子
int arraySize =4;//線數過多,故我設為4
int[] xPoints = new int[arraySize];
int[] yPoints = new int[arraySize];//xPoints和yPoints要相等
file://int[] yPoints = new int[arraySize-1];//不相等,編譯時無錯,運行時給你個驚喜:)。
for(int i=0; i < xPoints.length; ++i) {
xPoints[i] = ((int)(Math.random()*200));
yPoints[i] = ((int)(Math.random()*200));
}
g.setColor(colors[(int)(Math.random()*10)]);
g.drawPolyline(xPoints, yPoints, arraySize);
showStatus(arraySize + " points");
}
}
6.3繪制矩形:
矩形有3種:
(1)實體的(solid)
(2)圓角的(rounded)
(3)3D
繪制方法如下:
void clearRect(int x,int y,int w,int h)
void drawRect(int x,int y,int w,int h)
void drawRoundRect(int x,int y,int w,int h,int arcWidth,int arcHeight)
增加的參數arcWidth用來設置弧的水平直徑和arcHeight用來設置豎直方向上的直徑
void draw3DRect(int x,int y,int w,int h,boolean raise)
增加的參數raise用來指定3D效果是凸的還是凹的,ture時,3D效果是凸的,false時3D效果是凹的
void fillRoundRect(int x,int y,int w,int h,int arcWidth,int arcHeight)
void fillRect(int x,int y,int w,int h)
void fill3DRect(int x,int y,int w,int h,boolean raise)
繪制矩形的例2:
file://applet程序中配備有三個按鈕和一個復選框,繪制矩形的代碼被封裝在applet的paint方法中
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
public class RandomRectangles extends Applet {
private static Color[] colors = {
Color.white, Color.black, Color.blue, Color.red,
Color.yellow, Color.orange, Color.cyan, Color.pink,
Color.magenta, Color.green };
private int numRects = 10;
private boolean fill = false,//復選框用于指定的矩形是否被填充
raise = false,
round = false,
threeD = false;//變量不能以數字開頭如3D樣
public void init() {//每個按鈕代表被繪制的矩形的類型
Button rectsButton = new Button("矩形");
Button roundbutton = new Button("圓角矩形");
Button threeDButton = new Button("3D矩形");
Checkbox fillCheckbox = new Checkbox("填充");
add(rectsButton);
add(roundButton);
add(threeDButton);
add(fillCheckbox);
rectsButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
round = false;
threeD = false;
repaint();
}
});
roundButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
round = true;
threeD = false;
repaint();
}
});
threeDButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
threeD = true;
round = false;
repaint();
}
});
fillCheckbox.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent event) {
fill = ((Checkbox)(event.getsource())).getState();
}
});
}
file://繪制所有的矩形時,采用的都是1像素寬的圖形筆,因為在AWT中,只允許這個尺寸
public void paint(Graphics g) {
for(int i=0; i < numRects; i++) {
Point lhc = randomPoint(); // left hand corner
Dimension size = randomDimension();
g.setColor(colors[(int)(Math.random()*10)]);
if(round) {
if(fill)
g.fillRoundRect(lhc.x,lhc.y,size.width,size.height,
(int)(Math.random()*250),
(int)(Math.random()*250));
else
g.drawRoundRect(lhc.x,lhc.y,size.width,size.height,
(int)(Math.random()*250),
(int)(Math.random()*250));
}
else if(threeD) {
file://繪制3D矩形前,Graphics的顏色被設置成亮灰色,才可以看見其3D效果
g.setColor(Color.lightGray);
if(fill)
g.fill3DRect(
lhc.x,lhc.y,size.width,size.height,raise);
else
g.draw3DRect(
lhc.x,lhc.y,size.width,size.height,raise);
}
else {
if(fill)
g.fillRect(lhc.x,lhc.y,size.width,size.height);
else
g.drawRect(lhc.x,lhc.y,size.width,size.height);
}
raise = raise ? false : true;
}
}
private Dimension randomDimension() {
return new Dimension((int)(Math.random()*250),
(int)(Math.random()*250));
}
private Point randomPoint() {
return new Point((int)(Math.random()*250),
(int)(Math.random()*250));
}
}
6.4畫弧:弧是唯一的一種非封閉的、但可以填充的圖形
繪制方法:void drawArc(int x,int y,int w,int h,int startAngle,int endAngle)
void fillArc(int x,int y,int w,int h,int startAngle,int endAngle)
參數意義:x,y,w(寬度)y(高度)弧指定坐標路徑。最后兩個是弧的開始角度和結束角度
簡單例子:
import java.applet.Applet;
import java.awt.*;
public class DrawArc extends Applet {
public void paint(Graphics g) {
g.setColor(Color.blue);
g.drawArc(10,10,150,100,0,210);//寬度和高度分別是151和101個像素,知道為什么呢吧?
g.setColor(Color.yellow);
g.fillArc(50,50,100,200,90,270);//寬100,高200個像素,因為是填充。
}
}
6.5繪制橢圓(not 圓角矩形)
繪制方法://寬高相同,所繪制的圖形是一個圓
void drawOval(int x,int y,int w,int h)
void fillOval(int x,int y,int w,int h)
參數意義:外框與橢圓相內切的矩形框
聰明的你一定知道drawOval()所繪畫的橢圓,適合的矩形是w+1個像素寬和h+1個像素高
6.6繪制多邊形
繪制方法://與折線類似,另:初始點和結束點不是同一個點多邊形將自動閉合
void drawPloygon(int[] xPoints,int[] yPoints,int[] numPoints)
void drawPolygon(Polygon polygon)
void fillPloygon(int xPoints,int[] yPoints,int[] numPoints)
void fillPolygon(Polygon polygon)
注意:盡管在AWT中提供非圖形Polygon和Rectangle類,但Graphics類不提供
drawRect(Rectangle)方法,盡管存在一個drawPolygon(Polygon)方法。
6.7繪制文本
繪制方法:
void drawString(String s,int x,int y)
void drawChars(char[],int offset,int length,int x,int y)
void drawBytes(byte[],int offset,int length,int x,int y)
參數注意:所繪制文本的x,y位置對應的是文本基線,不是文本的左上角,和矩形不一樣
可參看windows的SDK編程。JDK與windows的SDK編程很相似,同時學習可互為注腳,互相提高。
簡單的一句話:字符以其底線為始,如A以大約左腳處為始。
技巧3:
如果字符串和矩形被繪制在同一個位置,則字符串將顯示在矩形的上方
offset和length參數分別用來規定開始位置在數組中的偏移量和繪制的字符數,(Graphics類不提供旋轉文本的能力)
6.8轉換坐標系原點:如果不指定,則在Graphics坐標系中,原點一般設置在左上角
轉換坐標方法:Graphics.translate()
兩個整數參數值:描繪在原先的坐標系統中的點,在轉換后的坐標系統中將成為新的原點
轉換坐標的原因:一個原因是容器中沒有滾動條而又要滾動其內容,如下例便是(點擊鼠標可以滾動該圖形)
轉換坐標系的例子:
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
public class TranslateTest extends Applet {
Image image;
Point pressed = new Point(), lastTranslate = new Point();
public void init() {
image = getImage(getCodeBase(), "Rabbit.gif");//在IE緩存中隨便找一個.gif文件即可,
try {
MediaTracker mt = new MediaTracker(this);
mt.addImage(image, 0);
mt.waitForID(0);
}
catch(InterruptedException e) {
e.printStackTrace();
}
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
java.awt.Point loc = e.getPoint();
file://Point loc = e.getPoint();//是原版,但編譯時說
file://--TranslateTest.java:19: incompatible t
file://--found : java.awt.Point
file://--required: Point
file://--Point loc = e.getPoint();
file://-- ^
file://-----故加了java.awt.于前。什么原因呢?THINK IN JAVA中說Point有幾個類(awt中有,2D中有)。故...
// adjust mouse pressed location for
// translation ...
pressed.x = loc.x - lastTranslate.x;
pressed.y = loc.y - lastTranslate.y;
}
});
addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
java.awt.Point loc = e.getPoint();//加了java.awt
Point translate = new Point(loc.x - pressed.x,
loc.y - pressed.y);
Graphics g = getGraphics();
try {
g.clearRect(0,0,
getSize().width,getSize().height);
g.translate(translate.x, translate.y);
showStatus("Translating Graphics: " +
translate);
g.drawImage(image, 0, 0, TranslateTest.this);
}
finally {
g.dispose();
}
lastTranslate = translate;
}
});
}
public void paint(Graphics g) {
g.drawImage(image, 0, 0, this);
}
}
6.9剪貼:每個Graphics都有一個關聯的剪貼矩形。剪貼矩形之所以這樣命名是因為它們復制它們表示的矩形。另外,
隨著Java 2D API的發展,剪貼區域的開關可以被設置為任意的開關,而不只局限于矩形
繪制方法:同表3-3
void setClip(int x,int y,int w,int) file://設置所要剪貼的區域是一個矩形區域
void setClip(Shape) file://設置所要剪貼的區域是任意形狀
Rectangle getClipBounds() file://返回剪貼區域是一個矩形區域
Shape getClip() file://返回剪貼區域是任意形狀
void clipRect(int x,int y,int w,int h) file://將剪貼矩形設置為當前剪貼矩形和方法中變無指定的矩形的交集
本節例子請參看例2。
技巧4:《向Component.paint()傳遞被剪貼的Graphics》
對于AWT的初學者來講,經常向paint方法傳遞那些剪貼矩形小于構件的Graphics。結果,底層覆蓋的paint方法不干
擾它接受的Graphics的剪貼矩形。當paint()繪制構件的內容時,著色操作仍被執行。在一些實例(如雙緩沖和動畫設計)
中,以只更新被剪貼的區域代替繪制完整的內容和依靠剪貼修復被損壞的區域,可以得到更好的效果
6.10圖形模式:參看表3-3
XOR模式最一般的用途是在現有的圖形上使用橡皮帶生成法(在制圖程序中和選擇多樣的對象時是一種很普通的用法)
面所有的例子都被設置成paint模式,所以在本節中我們將重點講述XOR模式
文檔中對XOR模式做了如下的描述的:Graphics.setXORMode(Color)
When drawing operations are performed,pixels which are the current color are changed to the
specify color,and vice versa。Pixels that are of colors other than those two color are changed
in an unpredictable but reversible manner;if the figure is drawn twice,then all pixels are
restored to their original values。
第二句中說明:如果在XOR模式連續兩次執行復制圖像操作,其下面的圖形是不受影響的
使用XOR模式橡皮帶生成法的一個例子:在一個圖像上拉,生成一個矩形
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
public class xortest extends Applet {
java.awt.Point pressed, last;
Image image;
boolean firstRect;
public void init() {
image = getImage(getCodeBase(), "Rabbit.gif");
try {
MediaTracker mt = new MediaTracker(this);
mt.addImage(image, 0);
mt.waitForID(0);
}
catch(InterruptedException e) {
e.printStackTrace();
}
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
firstRect = true;
pressed = e.getPoint();
}
public void mouseReleased(MouseEvent e) {
if(pressed != null) {
java.awt.Point released = e.getPoint();
Rectangle clip = new Rectangle();
Graphics g = getGraphics();
Dimension size = getSize();
try {
clip.x = pressed.x;
clip.y = pressed.y;
clip.width =Math.abs(released.x - pressed.x);
clip.height =Math.abs(released.y - pressed.y);
g.clearRect(0,0,size.width,size.height);
g.setClip(clip);
g.drawImage(image, 0, 0, xortest.this);
}
finally {
g.dispose();
}
}
}
public void mouseClicked(MouseEvent e) {
repaint();
}
});
addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
java.awt.Point loc = e.getPoint();
Graphics g = getGraphics();
try {
g.setXORMode(getBackground());
if(firstRect) {
firstRect = false;
}
else {
g.drawRect(pressed.x, pressed.y,Math.abs(pressed.x - last.x),Math.abs(pressed.y - last.y));
}
g.drawRect(pressed.x, pressed.y,Math.abs(loc.x - pressed.x),Math.abs(loc.y - pressed.y));
last = e.getPoint();
}
finally {
g.dispose();
}
}
});
}
public void paint(Graphics g) {
g.drawImage(image, 0, 0, this);
}
}
6.11創建圖形
當實現傳遞Graphics引用的方法時,最好是保證方法的結果不會引起Graphics的變化。換句話說,當方法返回時,
Graphics和調用前的情況應當是相同的。在該規則中當然也有例外,我們可以相當有把握地說,當調用paint()返
回時,paint(Graphics)的調用者僅僅處理Graphics。因此,可以改變傳遞給paint()的Graphics,而忽視維持
它的初始狀態。但是,在另外的情況下,是否Graphics一定保留它的初始狀態并沒這么清楚。在這樣的情況下,
最好是接受安全的步驟并保證Graphics不被改變,有下面的兩個方法可以實現。
方法之一是:Graphics的所有的初始的特征可以被存儲在本地,然后在方法返回之前重新設置:
file://code fragment
public void notSurelfGraphicsShouldChangeState(Graphics g){
Color oldColor=g.getColor();
Font oldFont=g.getFont();
file://modify g's color and font and perfoRM graphical operations
g.setColor(oldColor);//restore old color
g.setfont(oldFont)//restore old font
很明顯,一兩個屬性更改無所謂,大量的屬性被修改后并被重新恢復就麻煩了
方法之二:那么創建Graphics的一個副本并用它代替傳遞給方法的Graphics是更方便的辦法
public void notSurelfGraphicsShouldChangeState(Graphics g){
Graphics copy=g.create();
try{
file://use copy for rendering
}
finally{
g.dispose();//crucial
}
}
對于4.Graphics引用的壽命一節中的例子,該applet程序保留一個Graphics引用,由于傳遞
給paint()的Graphics是由調用者來進行處理的,所以Graphics引用僅在調用paint()期間有效
現在我們創建一個Graphics的副本,該副本在調用paint()之后將不被處理,如下面
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
public class HoldRef2 extends Applet {
private Graphics copy;
private boolean first = true;
public void paint(Graphics g) {
if(first) {
// note: copy is never disposed off
file://致命錯誤,即沒有處理Graphics的副本
file://在實際中,許可制造出一個類成員的副本引用,并在另一個方法中在適當電動機及時處理它
copy = g.create();
copy.setColor(Color.red);
copy.setFont(new Font("Times Roman", Font.BOLD, 14));
first = false;
}
copy.drawString("Red Text", 10, 10);
}
}
創建Graphics的方法:
Graphics create()//創建的是一個精確的Graphics副本
Graphics create(int x,int y,int w,int h)//也是個副本,但返回的Graphics的原點被轉換為
(x,y)坐標,剪貼矩形轉換為原剪貼矩形和指定矩形的交集
例子:
import java.applet.Applet;
import java.awt.*;
public class CreateTest extends Applet {
private Image image;
public void init() {
MediaTracker mt = new MediaTracker(this);
image = getImage(getCodeBase(), "Rabbit.gif");
try {
mt.addImage(image, 0);
mt.waitForID(0);
}
catch(Exception e) {
e.printStackTrace();
}
}
public void paint(Graphics g) {
Graphics copy = g.create(image.getWidth(this),0,100,100);
try {
System.out.println("g: " + g.getClip().toString());
System.out.println("copy: " +copy.getClip().toString());
g.drawImage(image, 0, 0, this);
copy.drawImage(image, 0, 0, this);
}
finally {
copy.dispose();
}
}
}
加載圖像并通過applet的paint方法創建一個要傳遞的Graphics的副本,
副本的原點變換到(imw,0),imw是指圖形的寬度
副本也有它的剪貼矩形,設置為初始Graphics的剪貼矩形和由(image.getWidth(this),0,100,100)指定
的矩形的交集。因為初始Graphics的剪貼矩形覆蓋由applet程序占領的區域,所以兩個矩形的交集由
(image.getWidth(this),0,100,100)決定。
提示:復制的Graphics已經被轉換,因為調用drawImage()在(0,0)繪制圖像
啊!快結束了!略結一下:
(1)圖形操作的坐標系被設定在設備的左上角,x和y軸的增長方向分別是向下和向右,坐標位于像素之間,
Graphics方法中繪制形狀外形是通過設定圖形的坐標而不是像素。圖形筆在坐標路徑右邊和下邊移動,
因此形狀的外形導致在圖形右邊和下邊各有一個額外
的像素行。在另一方面,形狀填充圖形內部,填充的尺寸和坐標路徑一樣
(2)AWT不提供支持特殊形狀的類,如Line和Circle類.java.awt.Graphics提供大量的方法繪制和
填充圖形、繪制文本、設置圖形參數.但有限制,故要深入請學Java 2D API
(3)每個Graphics聯系一個本機潛在的窗口系統中的圖形環境。因此,Graphics描述的是必須被手工處理的
有限資源。如果通過調用一個方法返回一個Graphics引用以得到一個Graphics,則Graphics.dispose()
必須被調用為Graphics釋放系統資源。另一方面,傳遞Graphics引用的方法通常不必處理Graphics。
一般地,這些方法調用者負責處理Graphics
“JAVA圖形設計卷的知識點有哪些”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。