/ Text 14E.t.t.
1. Use double buffer to solve the refresh problem in the drawboard program
When we use Java to prepare a discipline program, there is always a refresh issue: When the window where Canvas is located, the window is minimized or after the other application is blocked, the graphics data on the Canvas will be partially or completely removed.
The method usually solving this problem is to redraw graphics in the canvas's Paint () function, but due to a lot of data in the drawing process, resetting these data on Canvas will result in a large number of system overhead, and flashing Therefore, this method is feasible but does not take.
Using double buffer technology can solve this problem, the main principle is to open two graphics buffers, one is the front desk display buffer (which is Canvas), one is the background graphics buffer (usually image). Users are drawing When the graphics, we synchronize the two buffers, which is equivalent to a background backup for the front desk. When the graphic of the station is covered, we can use this backup backup to recover, the specific method is Rewrite the Paint () function, draw a backup image onto the screen.
Why is it paint ()? Here you need to learn about the basics of Java processing AWT drawing: Java's display update is controlled by an AWT thread. The thread is responsible for two cases related to display updates. First The situation is called exposure, indicating that the partial display area is destroyed or needed. When this happens, the system directly calls the Paint () method; the second case is the program determines the display area, add some new content, at this time Call the member's repaint () method, the repaint () method calls the member's update (), Update () to call the Paint () method. It is clear that what we said is the first. As long as the window of the Canvas component minimizes or other The application covers, and the system will call Paint () to redraw the canvas. If we don't do anything in the Paint () method, you can only look at the lines of hard painting, once it is covered. I can't see it.
As a starting point, please see a simplest drawing program, please note that the following procedures are used by J2SDK1.4.1, and under the Win98 IE (not Tencent Explorer) all test:
//:Wbapplet.java
Import java.applet. *;
Public class wbapplet extends applet {final static int default_boardwidth = 700; factory static int default_boardHeight = 400;
Public void init () {super.init (); setLayout (null); Whiteboard = New Whiteboard (this); Whiteboard.reshape (0,0, default_boardwidth, default_boardhem); add (whiteboard);}
Whiteboard Whiteboard;
}
/ //: ~
//:Whiteboard.java
Java.awt. *; import java.awt.event. *;
Public class whiteboard extends canvas imports mousemotionListener, mouselistener {
Final static int default_boardwidth = 700; final static int default_boardheight = 400; int X0, Y0, X1, Y1;
Whiteboard (wbapplet wbapplet1) {parent = wbapplet1; addmousemotionListener (this); addmouseristener (this);}
synchronized public void update_buffer (Graphics g, DrawItem data) {g.drawLine (data.x0, data.y0, data.x1, data.y1);} public void mouseReleased (MouseEvent e) {} public void mouseEntered (MouseEvent e) {} public void mouseExited (MouseEvent e) {} public void mouseClicked (MouseEvent e) {} public void mouseMoved (MouseEvent e) {} public void mouseDragged (MouseEvent e) {x1 = e.getX (); y1 = e.getY (); Graphics g = getGraphics (); Update_buffer (g, new drawitem (x0, y0, x1, y1)); g.dispose (); x0 = x1; y0 = Y1;}
Public void mousepressed (mouseevent e) {x0 = E.GETX (); y0 = E.Gety ();}
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;
/ //: ~
All logical operations we need to complete in a WhiteBoard class in a Whiteboard class to facilitate the Applet call of the main program. At the same time, a drawing data class DrawItem is defined to encapsulate graphic data. Draw the operation is written in Update_buffer Obviously, this program cannot achieve refreshing recovery, we need double buffer technology.
In order to achieve double buffer, first define the graphics buffer as follows
Private image off_screen_buf; private graphics off_screen_gc;
And initialize it in the constructor of the WhiteBoard class
OFF_SCREEN_BUF = Parent.createImage (Default_BoardWidth); Off_Screen_GC = Off_screen_buf.getgraphics ();
In the function of processing the user plots graphics, we use Update_buffer to update the display buffer and graphics buffer
Graphics g = getgraphics (); Update_buffer (g, new drawitem (x0, y0, x1, y1)); // front update canvas Update_buffer (off_screen_gc, new drawitem (x0, y0, x1, y1)); // Background Update Buffer g.dispose ();
Obviously, the update operation of the background is not visible, so it is OFF-Screen.
Finally, rewrite the Paint () method, call COPY_FROM_OFFSCREEN_BUF (G) to draw images of the graphics buffer to the screen.
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);}
It is such a simple one-line code to allow us to avoid the problem that the graphics cannot recover. The following is the complete code after the WHITEBOARD is improved.
//:Whiteboard.javaImport java.awt. *; Import java.awt.event. *;
Public class whiteboard extends canvas imports 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);}
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) {} public void mouseEntered (MouseEvent e) {} public void mouseExited (MouseEvent e) {} public void mouseClicked (MouseEvent e) {} public void mouseDragged (MouseEvent e) {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;} public void mousepressed (mouseEvent e) {x0 = E.GETX (); y0 = E.Gety ();}
Public void Paint (Graphics G) {COPY_FROM_OFFSCREEN_BUF (G); // Shield this sentence, you cannot recover the graphics drawn by the user}
Void Copy_From_offScreen_BUF (Graphics G) {IF (g! = null) g.drawimage (OFF_SCREEN_BUF, 0, 0, NULL);}
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;
/ //: ~