雙緩衝在畫板程式中的應用(二) (轉)
/文 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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- PSRAM在資料緩衝應用中可以取代SRAM或SDRAM
- Duilib的雙緩衝實現,附帶GDI、WTL的雙緩衝實現UI
- 雙緩衝學習
- PHP 輸出緩衝區應用PHP
- Libevent應用 (三) 資料緩衝
- 你真的會用PostGIS中的buffer緩衝嗎?
- android View 繪圖雙緩衝技術AndroidView繪圖
- Thunk程式的實現原理以及在iOS中的應用(二)iOS
- 什麼?無限緩衝的佇列(二)?佇列
- 嵌入式核心板在麻醉系統中的應用
- InnoDB 中的緩衝池(Buffer Pool)
- 設計模式在vue中的應用(二)設計模式Vue
- Golang併發程式設計有緩衝通道和無緩衝通道(channel)Golang程式設計
- Qt5雙緩衝機制與例項QT
- Java_轉換流和緩衝流Java
- 初識Netty原理 (二)——ByteBuf緩衝區Netty
- radan軟體在鈑金件數衝加工中的應用
- Java中縮放緩衝影像Java
- Java緩衝流概述詳解(原理畫圖分析)Java
- 緩衝區溢位小程式分析
- 緩衝管理
- 測試C#GDI+雙緩衝高效繪圖--BufferedGraphicsContextC#繪圖Context
- STM32串列埠DMA接收雙緩衝串列埠
- Android自定義View之雙緩衝機制和SurfaceViewAndroidView
- 「譯」有限狀態機在 CSS 動畫中的應用CSS動畫
- socket程式設計在TCP中的應用程式設計TCP
- 緩衝帶裡的少年
- jQuery 緩衝效果二級導航下拉選單jQuery
- 輸出緩衝
- MySQL中讀頁緩衝區buffer poolMySql
- Debian 12採用 Ubuntu三重緩衝Ubuntu
- 動畫利器-lottie在懂表帝App中的實戰應用動畫APP
- PHP的輸出緩衝區PHP
- arcgis10之緩衝區轉化成四邊形
- IO流(02)--屬性集、緩衝流、轉換流
- 面試官:Redis中的緩衝區瞭解嗎面試Redis
- 2.3 應用程式容器中的應用程式概述
- MVC模式在Java Web應用程式中的實現MVC模式JavaWeb
- stdio流緩衝區