Java-Graphics類的繪圖方法實現
Java-Graphics(畫圖類)
就比如畫一個矩形,你給出矩形左上角座標,再給出矩形長度和寬度就可以在JFrame上畫出來一個矩形
除了矩形之外,還可以畫橢圓、圓、圓弧、線段、多邊形、影象等
下面給出畫矩形的程式碼
Rect.java
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;
public class Rect extends JPanel{
public static Color myColor = Color.RED;
public static int myX = 10;
public static int myY = 10;
public static int myWidth = 100;
public static int myHeight = 100;
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(myColor);
g.fillRect(myX+100,myY+100,myWidth,myHeight); //畫矩形著色塊
g.drawRect(myX,myY,myWidth,myHeight); // 畫矩形線框
}
}
Main.java
import java.awt.Color;
import javax.swing.JFrame;
public class Main{
//Note how we don't need to extend the Rect class (It just adds confusion)
public static void main(String[] args ) {
JFrame window = new JFrame("test");
window.setSize(1000, 800);
window.setLocationRelativeTo( null);
window.setVisible(true);
window.setResizable(false);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//create Rect
Rect rect = new Rect();
//set the size of the new panel
//rect.setPreferredSize(new Dimension(800, 600));
//add the rect to your JFrame
window.add(rect);
//如果你改變了Rect的靜態屬性color的值,它會同步更新,你把下面的程式碼註釋了還可以畫出矩形,那樣的話畫出來的圖形就是紅色的
Rect.myColor = Color.BLUE;
Rect.myX = 400;
Rect.myY = 400;
//加上下面,但是感覺加不加沒啥差距,,學廢了,,,,
rect.repaint();
}
}
repaint的一些問題
下面程式碼輸出的結果是錯誤的
// In MyPanel.java
public void paintComponent(Graphics g)
{
super.paintComponent(g);
// Draw something
mypanel_count++;
}
// In Test.java
public void testLargeData()
{
while (notDone)
{
panel.repaint();
// do huge work
test_count++;
System.out.println("Test_count: " + test_count + ", MyPanel_count: " + mypanel_count);
}
}
// 程式Output !!!
Test_count: 752, MyPanel_count: 23
Test_count: 753, MyPanel_count: 23
Test_count: 754, MyPanel_count: 23
Test_count: 755, MyPanel_count: 24
當我將 panel.repaint()更改為 panel.paintComponent(panel.getGraphics()),輸出正確:
//正確輸出如下
Test_count: 752, MyPanel_count: 752
Test_count: 753, MyPanel_count: 753
Test_count: 754, MyPanel_count: 754
Test_count: 755, MyPanel_count: 755
paintComponent 方法雖然有效,但是有些時候也會錯誤!
為什麼會這樣?
這意味著允許AWT / Swing通過合併快速連續請求的重繪來優化重繪。還有一個repaint( (長時間)方法,該方法可讓您控制AWT / Swing在完成重新繪製請求後等待的時間。但是,它仍然可以合併請求,特別是如果您是迴圈執行的話。
解決辦法
使用paintImmediately(...)但是您必須在事件分配執行緒中進行所有處理,如下所示:
SwingUtilities.invokeLater(new Runnable(){ public void run(){ while(notDone){ //是否處理 panel.paintImmediately(...); } } });
paintImmediately函式:
public void paintImmediately(Rectangle r)
Paints the specified region now.
Parameters:
r - a Rectangle containing the region to be painted
要使面板在每次迭代時都重新粉刷,您必須等待粉刷發生,然後繼續迴圈。這意味著您需要在處理執行緒(迴圈)和AWT / Swing執行緒之間進行一些同步。大致來說,您可以例如wait()在迴圈結束時在面板物件上,如果自從上次呼叫 repaint(),然後呼叫面板的 paintComponent()方法末尾的notifyAll()。但是,這可能很難正確實現,因此,僅在確實需要"實時"重繪元件時才應這樣做。
好了,不談論repaint的問題了,我們來說畫其他型別圖形的方法
就只需要改下面函式裡面的程式碼就可以了
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(myColor);
g.fillRect(myX+100,myY+100,myWidth,myHeight); //畫矩形著色塊
g.drawRect(myX,myY,myWidth,myHeight); //畫矩形線框
}
畫圓角矩形
畫圓角矩形也有兩個方法:
/** * 用此圖形上下文的當前顏色繪製圓角矩形的邊框。 * 矩形的左邊緣和右邊緣分別位於 x 和 x + width。 * 矩形的上邊緣和下邊緣分別位於 y 和 y + height。 */ public abstract void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) /** * 用當前顏色填充指定的圓角矩形。 * 矩形的左邊緣和右邊緣分別位於 x 和 x + width - 1。 * 矩形的上邊緣和下邊緣分別位於 y 和 y + height - 1。 */ public abstract void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight)
引數 arcWidth 表示4個角弧度的水平直徑,arcHeight 表示4個角弧度的垂直直徑。
以下程式碼是畫矩形的例子:
g.drawRoundRect(10,10,150,70,40,25); // 畫一個圓角矩形 g.setColor(Color.blue); g.fillRoundRect(80,100,100,100,60,40); // 填充一個圓角矩形塊 g.drawRoundRect(10,150,40,40,40,40); // 畫圓 g.setColor(Color.red); g.fillRoundRect(80,100,100,100,100,100);//畫圓塊
可以用畫圓角矩形方法畫圓形,當矩形的寬和高相等,圓角弧的橫向直徑和圓角弧的縱向直徑也相等,並等於矩形的寬和高時,畫的就是圓形。參見上述例子中的註釋,前一個是畫圓,後一個是塗圓塊。
畫多邊形
多邊形是用多條線段首尾連線而成的封閉平面圖。多邊形線段端點的x座標和y座標分別儲存在兩個陣列中,畫多邊形就是按給定的座標點順序用直線段將它們連起來。以下是畫多邊形常用的兩個方法:
/** * 繪製一個由 x 和 y 座標陣列定義的閉合多邊形。每對 (x, y) 座標定義一個點。 */ public abstract void drawPolygon(int[] xPoints, int[] yPoints, int nPoints); /** * 填充由 x 和 y 座標陣列定義的閉合多邊形。 */ public abstract void fillPolygon(int[] xPoints, int[] yPoints, int nPoints)
繪製由 nPoint 個線段定義的多邊形,其中前 nPoint - 1 個線段是 1 ≤ i ≤ 時從 (xPoints[i - 1], yPoints[i - 1]) 到 (xPoints[i], yPoints[i]) 的線段。如果最後一個點和第一個點不同,則圖形會通過在這兩點間繪製一條線段來自動閉合。
以下程式碼是畫多邊形的例子:
int px1[]={50,90,10,20};//首末點相重,才能畫多邊形 int py1[]={10,50,50,20}; int px2[]={140,180,170,180,140,100,110,140}; int py2[]={5,25,35,45,65,35,25,5}; g.setColor(Color.blue); g.fillPolygon(px1,py1,4); g.setColor(Color.red); g.drawPolygon(px2,py2,8);
也可以用多邊形物件畫多邊形。用多邊形類Polygon建立一個多邊形物件,然後用這個物件繪製多邊形。Polygon類的主要方法:
Polygon() // 建立空的多邊形。 Polygon(int[] xpoints, int[] ypoints, int npoints) // 根據指定的引數構造並初始化新的 Polygon。 public void addPoint(int x, int y) // 將一個座標點加入到Polygon物件中。
使用Polygon多邊形物件繪製多邊形的方法:
public void drawPolygon(Polygon p) // 繪製多邊形。 public void fillPolygon(Polygon p) // 填充多邊形。
例如,以下程式碼,畫一個三角形和填充一個黃色的三角形。注意,用多邊形物件畫封閉多邊形不要求首末點重合。
Polygon ponlygon1=new Polygon(); polygon1.addPoint(50,10); polygon1.addPoint(90,50); polygon1.addPoint(10,50); g.drawPolygon(polygon1); int x[]={140,180,170,180,140,100,110,100}; int y[]={5,25,35,45,65,45,35,25}; Polygon polygon2 = new Polygon(x,y,8); g.setColor(Color.yellow); g.fillPolygon(polygon2);
畫影象
繪製圖像的常用方法:
boolean drawImage(Image img, int x, int y, ImageObserver observer) boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver observer) boolean drawImage(Image img, int x, int y, Color bgcolor, ImageObserver observer) boolean drawImage(Image img, int x, int y, int width, int height, Color bgcolor, ImageObserver observer)
引數:
Image img – 需要繪製的影象。
int x, int y – 影象左上角座標。
int width, int height – 影象的寬度和高度。
Color bgcolor – 背景色,即影象下面的顏色。如果影象包含透明象素時這會有用,影象將在指定顏色背景下顯示。
ImageObserver observer – 一個實現ImageObserver 介面的物件。它將該物件登記為一個影象觀察者,因此當影象的任何新資訊可見時它被通知。大多元件可以簡單的指定this。
元件可以指定this作為影象觀察者的原因是Component 類實現了ImageObserver 介面。當影象資料被載入時它的實現呼叫repaint方法,這通常是你所期望的。
drawImage 方法只要要顯示的影象資料已經載入完就返回。如果你要確保drawImage只繪製完整的影象,那麼你需要跟蹤影象的載入。
例如,繪製一張圖片:
Image img = Toolkit.getDefaultToolkit().getImage("img/monster.gif"); g.drawImage(img, 510, 5, 200, 200, Color.LIGHT_GRAY, this);
畫線段:在視窗中畫一條線段,可以使用Graphics類的drawLine()方法:
/** * 在此圖形上下文的座標系中,使用當前顏色在點 (x1, y1) 和 (x2, y2) 之間畫一條線 * * @param x1 * 第一個點的 x 座標 * @param y1 * 第一個點的 y 座標 * @param x2 * 第二個點的 x 座標 * @param y2 * 第二個點的 y 座標 */ public abstract void drawLine(int x1, int y1, int x2, int y2)
例如,以下程式碼在點(3,3)與點(50,50)之間畫線段,在點(100,100)處畫一個點。
g.drawLine(3,3,50,50); //畫一條線段 g.drawLine(100,100,100,100); //畫一個點。
更多見: