雙緩衝在畫板程式中的應用(二) (轉)
/文 14E.T.
2.用雙緩衝實現各種圖形的繪製
在一個畫板中,應該能夠用畫筆繪製各種圖形,除了上一節實現的自由畫法(Freehand)外,還應該可以畫直線,長方體,橢圓等等.以繪製直線為例,我們都知道,只有在鬆開滑鼠鍵之後,直線才實實在在的顯示在了畫布上,而在拖拽滑鼠的過程中,直線在畫布中的顯示是隨著滑鼠的箭頭方位的變化而不斷的.體現在程式中,這是一個不斷擦除,顯示,再擦除,再顯示的過程.擦除的是箭頭上一個點和起點間的直線,顯示的是箭頭當前點和起點間的的直線.這個顯示的過程由update_buffer負責,而這個擦除的工作則和上一節出理重新整理一樣,由copy_from_offscreen_buf來完成.實際上,所謂擦除,也就是將畫板恢復到某一個原來的時刻.
這一個過程在下面一個修改後的拖拽操作的處理程式中完成:
public void mouseDragged(MouseEvent e){
Graphics g = getGraphics();
copy_from_offscreen_buf(g);
x1=e.getX();
y1=e.getY();
update_buffer(g,new DrawItem(x0,y0,x1,y1));
g.dispose();
}
注意,在該方法中,我們沒有對後臺緩衝進行更新,這是因為滑鼠在拖拽的時候,雖然畫板上會顯示線條,但是這條直線並沒有真正的畫下去.那麼在什麼時候應該對後臺緩衝更新呢?顯然,是在滑鼠鬆開的時候.我們需要在mouseReleased方法中做這個工作.
public void mouseReleased(MouseEvent e){
Graphics g = getGraphics();
copy_from_offscreen_buf(g);
x1=e.getX();
y1=e.getY();
update_buffer(g,new DrawItem(x0,y0,x1,y1));
update_buffer(off_screen_gc,new DrawItem(x0,y0,x1,y1));
g.dispose();
}
可以看到,只有在滑鼠鬆開的時候,畫到畫板上的直線才最後確定了,我們才能夠將這一條線到緩衝區裡面去.
下面是升級後的完整的WhiteBoard.程式.
import java.awt.*;
import java.awt.event.*;
public class WhiteBoard extends Canvas implements MouseMotionListener,MouseListener{
final static int DEFAULT_BOARDWIDTH=700;
final static int DEFAULT_BOARDHEIGHT=400;
int x0,y0,x1,y1;
WhiteBoard(WBApplet WBApplet1){
parent = WBApplet1;
off_screen_buf =parent.createImage(DEFAULT_BOARDWIDTH,DEFAULT_BOARDHEIGHT);
off_screen_gc = off_screen_buf.getGraphics();
addMouseMotionListener(this);
addMouseListener(this);
draw_mode=2;
}
synchronized public void update_buffer(Graphics g,DrawItem data) {
g.drawLine(data.x0,data.y0,data.x1,data.y1);
}
public void mouseMoved(MouseEvent e){}
public void mouseReleased(MouseEvent e){
switch(draw_mode){
case 2:
Graphics g = getGraphics();
copy_from_offscreen_buf(g);
x1=e.getX();
y1=e.getY();
update_buffer(g,new DrawItem(x0,y0,x1,y1));
update_buffer(off_screen_gc,new DrawItem(x0,y0,x1,y1));
g.dispose();
}
}
public void mouseEntered(MouseEvent e){}
public void mouseExited(MouseEvent e){}
public void mouseClicked(MouseEvent e){}
public void mouseDragged(MouseEvent e){
switch(draw_mode){
case 1:
x1=e.getX();
y1=e.getY();
Graphics g = getGraphics();
update_buffer(g,new DrawItem(x0,y0,x1,y1));
update_buffer(off_screen_gc,new DrawItem(x0,y0,x1,y1));
g.dispose();
x0=x1;
y0=y1;
break;
case 2:
Graphics g1 = getGraphics();
copy_from_offscreen_buf(g1);
x1=e.getX();
y1=e.getY();
update_buffer(g1,new DrawItem(x0,y0,x1,y1));
g1.dispose();
}
}
public void mousePressed(MouseEvent e){
x0 =e.getX();
y0 =e.getY();
}
public void paint(Graphics g){
copy_from_offscreen_buf(g);
}
void copy_from_offscreen_buf(Graphics g){
if(g != null)
g.drawImage(off_screen_buf, 0, 0, null);
}
private int draw_mode;
private Image off_screen_buf;
private Graphics off_screen_gc;
WBApplet parent;
}
class DrawItem{
DrawItem(int x0,int y0,int x1,int y1){
this.x0=x0;
this.y0=y0;
this.x1=x1;
this.y1=y1;
}
int x0;
int y0;
int x1;
int y1;
}
///:~
注意到,在這個程式裡面我們建立了一個新的私有變數draw_mode,用來繪圖的代號.在這裡,我們使用1來代表自由繪畫,2來代表畫直線.在構造中為draw_mode定義初值可以使我們對不同種類圖形繪製的很方便,在上面的程式中,我們定義的是2,如果賦值為1,則又回到自由繪畫的模式.事實上,我們應該在這樣的一個上把程式不斷的擴充和完善.
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752019/viewspace-956275/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 雙緩衝在畫板程式中的應用(一) (轉)
- 雙緩衝學習
- Duilib的雙緩衝實現,附帶GDI、WTL的雙緩衝實現UI
- PSRAM在資料緩衝應用中可以取代SRAM或SDRAM
- Attribute 在.NET程式設計中的應用(二) (轉)程式設計
- PHP 輸出緩衝區應用PHP
- Libevent應用 (三) 資料緩衝
- MFC雙緩衝繪圖例項繪圖
- 你真的會用PostGIS中的buffer緩衝嗎?
- jive中的緩衝技術
- Vector在Java程式設計中的應用 (轉)Java程式設計
- Canvas畫板—手機上也可以用的畫板Canvas
- Thunk程式的實現原理以及在iOS中的應用(二)iOS
- android View 繪圖雙緩衝技術AndroidView繪圖
- sqlserver在JAVA中的應用 (轉)SQLServerJava
- 嵌入式核心板在麻醉系統中的應用
- 什麼?無限緩衝的佇列(二)?佇列
- 在應用程式中將OJB作為一個儲存層使用(二) (轉)
- Java緩衝流概述詳解(原理畫圖分析)Java
- 用緩衝技術OSCache 提高JSP應用的效能和穩定性JS
- 在應用程式中實現RAS撥號 (轉)
- Attribute在.net程式設計中的應用(一) (轉)程式設計
- Attribute在.NET程式設計中的應用(四) (轉)程式設計
- Attribute在.NET程式設計中的應用(五) (轉)程式設計
- Attribute在.NET程式設計中的應用(三) (轉)程式設計
- Java中縮放緩衝影像Java
- Qt5雙緩衝機制與例項QT
- 設計模式在vue中的應用(二)設計模式Vue
- AOP及其在Spring中的應用(二)Spring
- 物件有多少個資料塊緩衝在Data buffer中物件
- Golang併發程式設計有緩衝通道和無緩衝通道(channel)Golang程式設計
- 駭客中級技術--緩衝區溢位攻擊(轉)
- VB.net中HOOK的應用(二) (轉)Hook
- 用apache JCS實現物件緩衝Apache物件
- STM32串列埠DMA接收雙緩衝串列埠
- 調節Oracle資料緩衝區引數,緩衝整個資料庫(轉)Oracle資料庫
- 使用edit編輯緩衝區中的sqlSQL
- node.js中緩衝區–BufferNode.js