/ Text 14E.t.t.
2. Implement a variety of graphics with double buffer
In a discipline, the user should be able to draw a variety of graphics with a brush. In addition to the freehand method implemented by the previous section, it should also be able to draw straight lines, rectangles, ellipses, and more. Take the straight line as an example, we are Knowing that only after the mouse button is released, the straight line is actually displayed on the canvas, and during the drag and drop mouse, the display of the straight line in the canvas is continuously updated with the change of the mouse arrow orientation. In the process, this is a process that continuously erase, display, and then erase, and then display. Erase a straight line between a point and the starting point on an arrow, showing the straight line between the arrows and the starting point The process of this display is responsible by Update_buffer, and this erase works, as in the previous section, is completed by copy_from_offscreen_buf. In fact, the so-called erase is returned to a certain moment.
This process is completed in the following modified drag operation:
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 ();
Note that in this method, we did not update the background buffer, because the mouse is dragged, although the lines are displayed on the drawing board, but this straight line does not have a real painting. So when is the background Buffer update? Obviously, it is when the mouse is loose. We need to do this in the mouseeleased method.
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 ();
It can be seen that when the mouse is loose, the straight line drawn to the drawing board is finally determined, we can back up this line to the buffer.
Here is the complete Whiteboard.java program after the upgrade.
//:Whiteboard.java
Import 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); 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;} ///: ~
Notice that in this program we created a new private variable Draw_Mode, used to store the code of the drawing mode. Here, we use 1 to represent free painting, 2 to represent the draw line. In the constructor Draw_Mode definition Value allows us to make debugging to different kinds of graphics, in the above program, we define 2, if it is 1, return to the free painting mode. In fact, we should be in such a framework Constantly expand and improve the program.