Java Lesson 6 - drawing board
In this lesson, draw a drawing board. You can draw lines and circles. You can also draw beautiful patterns through recursion, such as shelbinsky triangle, Cantor square set, and even three-dimensional tumenger sponge.
First create a form. Define a class and a method.
public class Draw{ public void show(){ JFrame frame =new JFrame(); FlowLayout layout=new FlowLayout(); frame.setLayout(layout); frame.setSize(1000,1000); frame.setVisible(true); } public static void main(String[] args){ Draw ui=new Draw(); ui.show(); } }
Add a listener
The listener here is not just an ActionListener. Because it is a drawing board, there should not only be buttons to judge whether to draw a circle or a line in the garden, but also an action listener; In addition, to obtain the position of the mouse to draw lines, you need to use the mouse listener MouseListener or MouseMotionListener. The differences between the two are as follows:
MouseListener's mouse events are:
MOUSE_CLICKED mouse click (the requirements are harsh, and pressing and releasing must be the same pixel)
MOUSE_ENTERED mouse entry (a form)
MOUSE_ Exit mouse left
MOUSE_PRESSED mouse press
MOUSE_RELEASED mouse release
MouseMotionListener's mouse events are:
MOUSE_DRAGGED mouse drag
MOUSE_MOVED mouse movement
Then, it is recommended to use mousePressed and mouseReleased in MouseListener when scribing. Because the line will be drawn continuously during dragging, resulting in the line becoming thicker and thicker.
1. To add a listener, you need to create an additional class DrawListener
2. To draw lines, you need a brush. To use Graphics, you need to instantiate a Graphics object in both the listener class and the drawing board class, and make them equal.
3. In this class, you also need the coordinate values of the starting point and ending point of the dash startx,starty,endx,endy. The method of obtaining coordinates is implemented by getX() and getY().
4. After the listener is created and added, each time the button is pressed, the system needs to obtain the name of the last button pressed. According to the name to judge whether it should be crossed or rounded, an empty String is needed for storage.
public class DrawListener implements MouseListener,ActionListener{ //coordinate int startx,starty,endx,endy; //Graphics Graphics g; //Stores the name of the last button String str=""; //Complement function public void actionPerformed(ActionEvent a){} public void mousePressed(MouseEvent e){} public void mouseReleased(MouseEvent e){} public void mouseClicked(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} }
In the show method of Draw class
1. The brush acquired by Graphics must be visible after it is set
2. Add buttons to the form and add ActionListener to the buttons. When there are a large number of buttons, you can use array (which will be described in detail in the next lesson. Press the template first)
public class Draw{ public void show(){ JFrame frame =new JFrame(); FlowLayout layout=new FlowLayout(); frame.setLayout(layout); frame.setSize(1000,1000); DrawListener lis=new DrawListener(); frame.addMouseListener(lis); //Add button using array String[] name={"straight line","circular","Shelpinski triangle","Cantor square set","Menger sponge "} //Generate buttons through the for loop and add listeners for(int i=0;i<name.length;i++){ JButton btn=new JButton(name[i]); frame.add(btn); btn.addActionListener(lis); } frame.setVisible(true); //Get the location from the frame and return the listener class Graphics g=frame.getGraphics(); lis.g=g; } public static void main(String[] args){ Draw ui=new Draw(); ui.show(); } }
You can adjust the size of the button through the Dimension to make the interface more beautiful. In the interface class, I won't repeat it here.
The next task is to get the button text first. In actionPerformed(ActionEvent a), use a.getActionCommand() to get the button text and put it in str
public void actionPerformed(ActionEvent a){ str=a.getActionCommand(); }
Get the values of startx, starty, endx and endy in pressed and released
public void mousePressed(MouseEvent e){ startx = e.getX(); starty = e.getY(); } public void mouseReleased(MouseEvent e){ endx = e.getX(); endY = e.getY(); }
Draw a circle
Scribing is a process, that is, first press the mouse, drag, and then release the mouse. Then, when the mouse is released, scribing is performed. DrawLine for scribing (int x1, int Y1, int X2, int Y2)
The same is true for drawing circles. Use drawOval(int x1,int y1,int width,int height). There may be cases where startx > endx and starty > Endy. Then add math function math Min (startx, endx) is enough, and the width is math with the absolute value of endx startx abs(endx-startx)
public void mouseReleased(MouseEvent e){ endx = e.getX(); endY = e.getY(); if("straight line".equals(str)){ g.drawLine(startx,starty,endx,endy); } if("circular".equals(str)){ g.drawOval(Math.min(endx, startx), Math.min(starty, endy), Math.abs(endx-startx), Math.abs(endy-starty)); } }
Shelpinski triangle
It can be seen that there are three white triangles and one black triangle inside each white triangle, so it is easy to draw the shelpinski triangle by recursion. You only need to find the midpoint of each side of the white triangle every time, connect it and paint it black. The first two arrays of FillPolygon (int [] xpoints, int [] ypoints, int nPoints) are arrays of X and Y coordinates, The last nPoints represent the number of vertices of the filled polygon
Create a new class and draw a triangle with the function triangle
public class Sierpinskitriangle{ public void triangle(){ } }
Let n be the number of times to find the midpoint, and (x1,y1)(x2,y2)(x3,y3) be the coordinates of the three vertices of the largest triangle
First, connect the first three points, and get each midpoint into the array:
g.drawLine(x1, y1, x2, y2); g.drawLine(x1, y1, x3, y3); g.drawLine(x2, y2, x3, y3); int[] x={(x1+x2)/2,(x1+x3)/2,(x2+x3)/2}; int[] y={(y1+y2)/2,(y1+y3)/2,(y3+y2)/2};
When n=1, black fillPolygon(x, y, 3)
When n increases, you need to call yourself three times so that the new three white triangles can be divided into new triangles. You only need to assign x1, Y1, X2, Y2, X3 and Y3 to the three vertices of the new triangle, so it is much more convenient to assign values directly through the formal parameters. Therefore, you can use the following function header public void triangle (graphics g, int n, int x1, int X2, int X3, int Y1, int Y2, int Y3). Graphics G can get the brush directly through the formal parameters
Then, when n=2, there are three triangles (g, 2-1, x1, X2, X3, Y1, Y2, Y3). The three vertices here are the vertices of three white triangles, and then fillPolygon(x, y, 3) is followed after each call
When n=3, three triangles (g, 3-1, x1, X2, X3, Y1, Y2, Y3) and FillPolygon (x, y, 3)
It's troublesome to blacken every time you call yourself. It's better to do nothing when n=1 and blacken it into the main program:
public class Sierpinskitriangle{ public void triangle(Graphics g,int n,int x1,int x2,int x3,int y1,int y2,int y3){ int[] x={(x1+x2)/2,(x1+x3)/2,(x2+x3)/2}; int[] y={(y1+y2)/2,(y1+y3)/2,(y3+y2)/2}; g.drawLine(x1, y1, x2, y2); g.drawLine(x1, y1, x3, y3); g.drawLine(x2, y2, x3, y3); g.fillPolygon(x, y, 3); if(n==1){ return; } triangle(g,n-1,x1,(x1+x2)/2,(x1+x3)/2,y1,(y1+y2)/2,(y1+y3)/2); triangle(g,n-1,x2,(x1+x2)/2,(x2+x3)/2,y2,(y1+y2)/2,(y2+y3)/2); triangle(g,n-1,x3,(x1+x3)/2,(x2+x3)/2,y3,(y1+y3)/2,(y2+y3)/2); } }
Then in the listener class, you can create an object and call the method in the mouseReleased(MouseEvent e) function, like a straight line and drawing a circle. if("shelpinski triangle". equals(str))
if("Shelpinski triangle".equals(str)){ Sierpinskitriangle triangle=new Sierpinskitriangle(); triangle.triangle(g,5,500,100,900,100,900,900);
When n=5, the drawn image is the same as the above figure
Cantor square set
First create a class and a method
public class CantorSquareset{ public void csset(){ } }
Draw a rectangle with drawRect(int x1,int y1,int width,int height)
To define n, there is a largest rectangle at the beginning. When n=1, draw the second largest rectangle in the middle; When n=2, draw 8 third largest rectangles around the second largest rectangle. Then, starting from 1, every time n adds one, you need to call the function itself eight times. In fact, you only need to find the vertices of the eight rectangles eight times. Then use the function header csset(Graphics g,int n,int x1,int y1,int x2,int y2), where (x1,y1)(x1,y2) is the upper left corner and lower right corner of the rectangle respectively
Then when n=1, the middle rectangle drawRect(x1+(x2-x1)/3, y1+(y2-y1)/3, (x2-x1)/3, (y2-y1)/3)
When n=2, find out the upper left corner and length and width of each small rectangle
public class CantorSquareset{ public void csset(Graphics g,int n,int x1,int y1,int x2,int y2){ g.drawRect(100, 100, 800, 800); if(n==1){ g.drawRect(x1+(x2-x1)/3, y1+(y2-y1)/3, (x2-x1)/3, (y2-y1)/3); return; } csset(g,n-1,x1,y1,x2,y2); csset(g,n-1,x1,y1,x1+(x2-x1)/3,y1+(y2-y1)/3); csset(g,n-1,x1+(x2-x1)/3,y1,x2-(x2-x1)/3,y1+(y2-y1)/3); csset(g,n-1,x2-(x2-x1)/3,y1,x2,y1+(y2-y1)/3); csset(g,n-1,x1,y1+(y2-y1)/3,x1+(x2-x1)/3,y2-(y2-y1)/3); csset(g,n-1,x2-(x2-x1)/3,y1+(y2-y1)/3,x2,y2-(y2-y1)/3); csset(g,n-1,x1,y2-(y2-y1)/3,x1+(x2-x1)/3,y2); csset(g,n-1,x1+(x2-x1)/3,y2-(y2-y1)/3,x2-(x2-x1)/3,y2); csset(g,n-1,x2-(x2-x1)/3,y2-(y2-y1)/3,x2,y2); } }
In the mouseReleased(MouseEvent e) function
if("Square Cantor set".equals(str)){ CantorSquareset csset=new CantorSquareset(); csset.csset(g, 3, 100, 100, 900, 900); }
When n=3, the pattern is the same as the above figure
Menger sponge
(because the length, width and height are not calculated well, it doesn't look like a cube, but it can make do with it)
Munger sponge is composed of three layers, including 8 in the first layer, 4 in the second layer and 8 in the third layer. Mengge sponge is not complicated, but it's cumbersome. I won't expand it here. I'll put the code directly
public void smallsquare(Graphics g,int n,int x0,int y0,int a,int dx,int dy){ if (n==1){ g.drawRect(x0, y0-a, a, a); g.drawLine(x0+dx, y0-a-dy, x0+dx+a, y0-a-dy); g.drawLine(x0+dx+a, y0-a-dy, x0+dx+a, y0-dy); g.drawLine(x0, y0-a, x0+dx, y0-a-dy); g.drawLine(x0+a, y0-a, x0+dx+a, y0-a-dy); g.drawLine(x0+a, y0, x0+a+dx, y0-dy); Polygon Polg2=new Polygon(); Polg2.addPoint(x0, y0-a); Polg2.addPoint(x0+a, y0-a); Polg2.addPoint(x0+dx+a, y0-dy-a); Polg2.addPoint(x0+dx, y0-dy-a); g.setColor(new Color(255,145,0)); g.fillPolygon(Polg2); Polygon Polg1=new Polygon(); Polg1.addPoint(x0, y0); Polg1.addPoint(x0+a, y0); Polg1.addPoint(x0+a, y0-a); Polg1.addPoint(x0, y0-a); g.setColor(new Color(121,45,0)); g.fillPolygon(Polg1); Polygon Polg3=new Polygon(); Polg3.addPoint(x0+a, y0); Polg3.addPoint(x0+a, y0-a); Polg3.addPoint(x0+a+dx, y0-a-dy); Polg3.addPoint(x0+a+dx, y0-dy); g.setColor(new Color(137,111,0)); g.fillPolygon(Polg3); return; } smallsquare(g,n-1,x0+2*dx/3,y0-2*dy/3,a/3,dx/3,dy/3); smallsquare(g,n-1,x0+2*dx/3+a/3,y0-2*dy/3,a/3,dx/3,dy/3); smallsquare(g,n-1,x0+2*dx/3+2*a/3,y0-2*dy/3,a/3,dx/3,dy/3); smallsquare(g,n-1,x0+dx/3,y0-dy/3,a/3,dx/3,dy/3); smallsquare(g,n-1,x0+dx/3+2*a/3,y0-dy/3,a/3,dx/3,dy/3); smallsquare(g,n-1,x0,y0,a/3,dx/3,dy/3); smallsquare(g,n-1,x0+a/3,y0,a/3,dx/3,dy/3); smallsquare(g,n-1,x0+2*a/3,y0,a/3,dx/3,dy/3); smallsquare(g,n-1,x0+2*dx/3,y0-2*dy/3-a/3,a/3,dx/3,dy/3); smallsquare(g,n-1,x0+2*dx/3+2*a/3,y0-2*dy/3-a/3,a/3,dx/3,dy/3); smallsquare(g,n-1,x0,y0-a/3,a/3,dx/3,dy/3); smallsquare(g,n-1,x0+2*a/3,y0-a/3,a/3,dx/3,dy/3); smallsquare(g,n-1,x0+2*dx/3,y0-2*dy/3-2*a/3,a/3,dx/3,dy/3); smallsquare(g,n-1,x0+2*dx/3+a/3,y0-2*dy/3-2*a/3,a/3,dx/3,dy/3); smallsquare(g,n-1,x0+2*dx/3+2*a/3,y0-2*dy/3-2*a/3,a/3,dx/3,dy/3); smallsquare(g,n-1,x0+dx/3,y0-dy/3-2*a/3,a/3,dx/3,dy/3); smallsquare(g,n-1,x0+dx/3+2*a/3,y0-dy/3-2*a/3,a/3,dx/3,dy/3); smallsquare(g,n-1,x0,y0-2*a/3,a/3,dx/3,dy/3); smallsquare(g,n-1,x0+a/3,y0-2*a/3,a/3,dx/3,dy/3); smallsquare(g,n-1,x0+2*a/3,y0-2*a/3,a/3,dx/3,dy/3); }
In the mouseReleased(MouseEvent e) function
if("Menger sponge ".equals(name)){ Mengersponge sponge=new Mengersponge(); sponge.smallsquare(n, 4, 50, 950, 630, 220, 220); }
When n=4, the pattern is the same as the above figure
The content in the drawing board is almost here. In fact, it is to strengthen the use of recursion. In addition, the drawing board also has fractal, but since it is not difficult, I won't introduce it. The next lesson will talk about arrays