Weekly Plans and Assignments: 1. Thursday(02/11): Intro. to Ch.10 - Graphics in Java. Start with Prog10_1UsingDrawLine. Download some DrawLineSourceCode to use as a guide. If you are interested in some advanced commands that give you more control of the window, use this AdvancedSourceCode. HW: Finish program from class and turn-in tomorrow. 2. Friday(02/12): Start on Prog10_2CreateOwnLogo. Download some PolygonSourceCode to use as a guide. HW: Finish program from class and turn-in tomorrow. 3. Monday(02/15): No School - Presidents Day. HW: Finish Program assignments. Due tomorrow, no exceptions. 4. Tuesday(02/16): Prog 10_3SphereInscribedInCylinder. Use previous PolygonSourceCode as a guide. HW: Finish program from class and turn-in tomorrow. 5. Wednesday(02/17): Prog10_4AnimationsInJava. Check-out this idea. Download FallingObjectSourceCode. Download CarOnRoadSourceCode. HW: Finish program from class and turn-in tomorrow. 6. Thursday(02/18): Prog10_5AbstractArt. Create your own masterpiece. HW: Finish program from class and turn-in tomorrow. 7. Friday(02/19): Prog10_6ScienceGraphic. Make a graphic illustrating a concept in science. HW: Finish program from class and turn-in tomorrow. Click HERE for detailed assignment descriptions for Prog10_01 to 10_06. 8. Monday(02/22): Finish Prog10_7ModifySleepy.Download the SourceCode. HW: Finish program from class and turn-in tomorrow. 9. Tuesday(02/23): Prog 10_8ModifyButtonPressed. Here's the SourceCode. HW: Finish program from class and turn-in tomorrow. 10. Wednesday(02/24): Prog10_9ModifyMouseEvent. Here's the SourceCode. HW: Finish program from class and turn-in tomorrow. 11. Thursday(02/25): Prog10_10StudentProject. Create your own project. HW: Finish program from class and turn-in tomorrow. 12. Friday(02/26): No School due to Teacher Meeting Day. HW: Finish all assigned work. 13. Monday(03/01): Prog10_11CitySkyLine. Create your own skyline of a city using lines, fills, rectangles, etc. HW: Finish program from class and turn-in tomorrow. 14. Tuesday(03/02): Morning classes do not meet due to FCAT Practice from 8:40 to 12:30. Then Lunch and Periods 5, 6, 7. Prog10_12RegularPentagon. Draw a regular pentagon with all of its diagonals HW: Finish program from class and turn-in tomorrow. 15. Wednesday(03/03): Prog10_13RegularPolygon. Draw a any regular polygon of your choice with all of its diagonals HW: Finish program from class and turn-in tomorrow. 16. Thursday(03/04): Prog10_14ModifyRandomRectangles. Modify the Random Rectangles Program to get a nucleus of an atom. SourceCode. HW: Finish program from class and turn-in tomorrow. 17. Friday(03/05): Prog10_15ModifyRoadStripe. Modify the Road Stripe Program with trees, road signs, other cars, fenceposts, etc. SourceCode. HW: Finish program from class and turn-in tomorrow. 18. Monday(03/08): Prog10_16ModifyDriveThrough. Modify the Drive Through Program by adding more choices and features. SourceCode. HW: Finish program from class and turn-in tomorrow. 19. Tuesday(03/09): Report to 1st period. Testers report to testing location. Non-testers (gym or see below). Periods 5, 6, 7 do not meet. FCAT Rdg., g.9, g.10, Retakes; FCAT Sci. Pract., g.11; AP Micro., g.12 (>180 min.) · Extended time testers will complete only first session of Reading. · AP Micro students report to the cafeteria. · Testing should conclude by 12:50pm. · We will then have lunch, followed by abbreviated period 2-4 classes. 20. Wednesday(03/10): Prog10_17ModifyImager. Modify the Imager Program by adding more images (JPEG and/or GIF) to view and more features. ImagerSourceCode. An image to view. HW: Finish program from class and turn-in tomorrow. The morning goes like this: Report to 1st period. Testers report to testing location. Non-testers (gym or see below).
· FCAT Sci. Pract., g.11. · AP Gov. students report to the cafeteria. · Extended time testers will complete only second session of Rdg. · Testing should conclude by 1:00pm. Lunch, then shortened periods 5-7. 21. Thursday(03/11): Report to 1st period. Testers report to testing location. Non-testers (gym or see below). Periods 5, 6, 7 do not meet. FCAT Science, g.11; FCAT Math Session 1, Extended Time Testers . · Report to 1st per. class; then, ESE and ESOL students report to their extendedtime testing locations for the second session of the Reading FCAT. Grade 11 students report to testing locations for the FCAT Science test. · AP Human Geography students report to practice AP testing rooms.· AP Psych. students report to room 8118.· AP World students report to cafeteria.· Non-testers and teachers not proctoring the Science FCAT (check proctor list,changes have been made) report to former testing location from 3/09 and 3/10 for an extended time. · Testing should conclude by 12:30pm. Then we have lunch and periods 2-4.22. Friday(03/12): Prog10_18FlyingSaucer. Draw a flying saucer suspended above the horizon and use drawLine to send laser beams toward the ground in random directions. HW: Finish program from class and turn-in tomorrow. 23. Monday(03/15): Prog10_19TargetPractice. Create your own target practice game. Check-out some SourceCode. HW: Finish program from class and turn-in tomorrow. 24. Tuesday(03/16): Prog 10_20Molecule. Draw a molecule based on the one you picked in class. Check-out some SourceCode. HW: Finish program from class and turn-in tomorrow. 25. Wednesday(03/17): Prog10_21EquationGrapher. Code-up the program you were working-on in class from the handout that graphs y = x , y = x2 , and y = √x . Check-out some SourceCode. HW: Finish program from class and turn-in tomorrow. 26. Thursday(03/18): Prog10_22Modify10_01to10_05. Modify any program from Prog10_01 to Prog10-05 by adding something new to it. HW: Finish program from class and turn-in tomorrow. 27. Friday(03/19): Prog10_23Modify10_06to10_10. Modify any program from Prog10_06 to Prog10-10 by adding something new to it. HW: Finish program from class and turn-in tomorrow.
28. Monday(03/22): Prog10_24Modify10_11to10_15. Modify any program from Prog10_11 to Prog10-15 by adding something new to it. HW: Finish program from class and turn-in tomorrow. 29. Tuesday(03/23): Prog10_25Modify10_16to10_20. Modify any program from Prog10_16 to Prog10-20 by adding something new to it. HW: Finish program from class and turn-in tomorrow. 30. Wednesday(03/24): Prog10Exam. Code-up the program you were given in class for your exam on Ch.10 - Graphics in Java. Present to the class from Tuesday until Thursday (end of grading period). HW: Finish program from class and turn-in by tomorrow. 31. Thursday(03/25): Prog10Exam. Code-up the program you were given in class for your exam on Ch.10 - Graphics in Java. Present to the class from Tuesday until Thursday (end of grading period). HW: Have a Safe and Restful Spring Break!
Very Important: If you have any questions or were absent from class, see me before school (8:00 - 8:30 AM), during Lunch, or after school. Best to send an email to rpersin@fau.edu.
Website Notes - Ch.10: Creating Graphics in Java. I. Introduction. 1. Graphics in Java is made relatively easy by many standard library calls that are not included in many languages. First and foremost, you should know that in Java graphics programming, one of the most important instantiated objects is the graphics context. 2. This object is an instance of the java.awt.Graphics class, and it refers to an area of the screen such as a window. A graphics context provides methods for all of the drawing operations on its area. 3. It also holds "contextual" information about such things as the drawing area's clipping region, painting color, transfer mode, and text font. 4. Most often the graphics context is obtained from the Java window manager as a result of a painting request. This context is passed to your component's paint() or update() method. (Java also allows the user to obtain a graphics context for an offscreen image, which enables you to do double buffering. It is not necessary that you know what double buffering means, but you can find out from most any book on graphics and programming.) 5. The coordinate system is laid out with (0, 0) at the top left corner of the drawing area with the x's and y's increasing until they get to the applet's width and height. The coordinates are measured in pixels, with x increasing horizontal to the right and y increasing vertically down (not up!). 6. The paint(Graphics g) method includes an instance of the Graphics class as an argument. The graphics context represents a drawing surface and all of its graphics settings such as the current foreground and background colors, the fonts to be used for strings, etc. graphical user interface (GUI). 7. The class is referred to as the graphics context class since it provides the context under which all graphics commands operate. The graphics context does not need to represent a visible component but can be an off-screen image as we will see later in the double buffering discussion. II. Graphics Commands 1. Here are some of the drawing methods in the Graphics class. drawLine(int x1, int y1, int x2, int y2) drawArc(int x,int y,int width, int height, setColor(Color c) fillRect(int x, int y, int width, int height) 2. Note that the the coordinate system goes as follows: Origin (0,0)- top left hand corner x (in pixels) - increases towards the right Maximum x = width - 1 y (in pixels) - increases towards the bottom Maximum y = height -1 3. The width and height values come from the getSize() method, which returns an instance of the Dimension class, and getWidth() and getHeight() methods, which became available as of version 1.2. 4. So, for example in the instruction, drawRect(x,y,width,height) (x,y) are the coordinates of the top left corner and the bottom right corner will be at (x+width,y+height). 5. Similarly, drawOval(x,y,width,height) draws an oval bounded by the rectangle specified by these arguments. 6. The allow an application to draw onto components that are realized on various devices, as well as onto off-screen images. 7. A rendering operations that Java supports. This state information includes the following properties:
8. Coordinates are infinitely thin and lie between the pixels of the output device. Operations which draw the outline of a figure operate by traversing an infinitely thin path between pixels with a pixel-sized pen that hangs down and to the right of the anchor point on the path. 9. Operations which fill a figure operate by filling the interior of that infinitely thin path. Operations which render horizontal text render the ascending portion of character glyphs entirely above the baseline coordinate. 10. The graphics pen hangs down and to the right from the path it traverses. This has the following implications: If you draw a figure that covers a given rectangle, that figure occupies one extra row of pixels on the right and bottom edges as compared to filling a figure that is bounded by that same rectangle. 11. If you draw a horizontal line along the same y coordinate as the baseline of a line of text, that line is drawn entirely below the text, except for any descenders. 12. All coordinates which appear as arguments to the methods of this
13. All rendering operations modify only pixels which lie within the area bounded by both the current clip of the graphics context and the extents of the component used to create the 14. All drawing or writing is done in the current color, using the current paint mode, and in the current font. We can also use: clearRect(int, int, int, int) Clears the specified rectangle by filling it with the background color of the current drawing surface. clipRect(int, int, int, int)Intersects the current clip with the specified rectangle. copyArea(int, int, int, int, int, int)Copies an area of the component by a distance specified by Creates a new Creates a new new translation and clip area. dispose()Disposes of this graphics context and releases any system resources that it is using. draw3DRect(int, int, int, int, boolean)Draws a 3-D highlighted outline of the specified rectangle. drawArc(int, int, int, int, int, int)Draws the outline of a circular or elliptical arc covering the specified rectangle. drawBytes(byte[], int, int, int, int)Draws the text given by the specified byte array, using this graphics context's current font and color. drawChars(char[], int, int, int, int)Draws the text given by the specified character array, using this graphics context's current font and color. drawImage(Image, int, int, Color, ImageObserver)Draws as much of the specified image as is currently available. drawImage(Image, int, int, ImageObserver)Draws as much of the specified image as is currently available. drawImage(Image, int, int, int, int, Color, ImageObserver)Draws as much of the specified image as has already been scaled to fit inside the specified rectangle. drawImage(Image, int, int, int, int, ImageObserver)Draws as much of the specified image as has already been scaled to fit inside the specified rectangle. drawImage(Image, int, int, int, int, int, int, int, int, Color, ImageObserver)Draws as much of the specified area of the specified image as is currently available, scaling it on the fly to fit inside the specified area of the destination drawable surface. drawImage(Image, int, int, int, int, int, int, int, int, ImageObserver)Draws as much of the specified area of the specified image as is currently available, scaling it on the fly to fit inside the specified area of the destination drawable surface. drawLine(int, int, int, int)Draws a line, using the current color, between the points Draws the outline of an oval. drawPolygon(int[], int[], int)Draws a closed polygon defined by arrays of x and y coordinates. drawPolygon(Polygon)Draws the outline of a polygon defined by the specified Draws a sequence of connected lines defined by arrays of x and y coordinates. drawRect(int, int, int, int)Draws the outline of the specified rectangle. drawRoundRect(int, int, int, int, int, int)Draws an outlined round-cornered rectangle using this graphics context's current color. drawString(String, int, int)Draws the text given by the specified string, using this graphics context's current font and color. fill3DRect(int, int, int, int, boolean) Paints a 3-D highlighted rectangle filled with the current color. fillArc(int, int, int, int, int, int)Fills a circular or elliptical arc covering the specified rectangle. fillOval(int, int, int, int)Fills an oval bounded by the specified rectangle with the current color. fillPolygon(int[], int[], int)Fills a closed polygon defined by arrays of x and y coordinates. fillPolygon(Polygon)Fills the polygon defined by the specified Polygon object with the graphics context's current color. fillRect(int, int, int, int)Fills the specified rectangle. fillRoundRect(int, int, int, int, int, int)Fills the specified rounded corner rectangle with the current color. finalize()Disposes of this graphics context once it is no longer referenced. getClip()Gets the current clipping area. getColor() Gets this graphics context's current color. getFont()Gets the current font. getFontMetrics() Gets the font metrics of the current font. getFontMetrics(Font) Gets the font metrics for the specified font. setClip(int, int, int, int)Sets the current clip to the rectangle specified by the given coordinates. setClip(Shape)Sets the current clipping area to an arbitrary clip shape. setColor(Color)Sets this graphics context's current color to the specified color. setFont(Font)Sets this graphics context's font to the specified font. setPaintMode()Sets the paint mode of this graphics context to overwrite the destination with this graphics context's current color. setXORMode(Color)Sets the paint mode of this graphics context to alternate between this graphics context's current color and the new specified color. toString()Returns a Translates the origin of the graphics context to the point (x, y) in the current coordinate system. Ch.13: Creating Graphics in Java (II). The Abstract Window Toolkit (AWT). The Abstract Window Toolkit allows you to build graphical user interfaces, GUI's. This chapter begins by considering some of the classes that allow you to create different elements on a screen such as graphs, buttons, check boxes, lists and others. I. Creating a Window.A basic window in Java is represented by an object of the class Window in the package java.awt. Objects of the class Window are hardly ever used directly since borders and a title bar are fairly basic prerequisites for a typical application window, and this class provides neither. The library class JFrame, defined in javax.swing, is a much more useful class for creating a window, since as well as a title bar and a border, it provides a wealth of other facilities. The Component class is the grandmother of all component classes – it defines the basic properties and methods shared by all components. We will see later that all the Swing components have the Component class as a base. The Container class adds the capability for a Component object to contain other components, which is a frequent requirement. Since JFrame has Container as a superclass, a JFrame object can contain other components. Beyond the obvious need for a window to be able to contain the components that represent the GUI, a menu bar should contain menus, for instance, which in turn will contain menu items: a toolbar will obviously contain toolbar buttons, and there are many other examples. For this reason the Container class is also a base for all the classes that define Swing components. The Window class adds methods to the Container class that are specific to a window, such as the ability to handle events arising from user interaction with the window. The Frame class is the original class in java.awt that provided a proper window, with a title bar and a border, with which everyone is familiar. The JFrame class adds functionality to the Frame class to support much more sophisticated facilities for drawing and displaying other components. You can deduce from the hierarchy in the diagram how a JFrame object can easily end up with its 200+ methods as it has five superclasses from which it inherits members. We aren't going to trawl through all these classes and methods. We'll just look into the ones we need in context as we go along, and then see how they are applied for real. This will hopefully teach you the most important methods in this class. You can display an application window simply by creating an object of type JFrame, calling a method for the object to set the size of the window, and then calling a method to display the window. Here's the code:
Try resizing the window by dragging a border or a corner with the mouse. You can also try minimizing the window by clicking on the icons to the right of the title bar. Everything should work OK so we are getting quite a lot for so few lines of code. You can close the application by clicking on the close icon. II. Components and Containers. A component represents a graphical entity of one kind or another that can be displayed on the screen. A component is any object of a class that is a subclass of Component. As we have seen, a JFrame window is a component, but there are many others. Before getting into specifics, let's first get a feel for the general relationship between the groups of classes that represent components. All the classes derived from Container can contain other objects of any of the classes derived from Component, and are referred to generically as containers. Since the Container class is a sub class of the Component class, every container object is a Component too, so a container can contain other containers. The exception is the Window class and its subclasses, as objects of type Window (or of a subclass type) can't be contained in another container. If you try to do this, an exception will be thrown. The JComponent class is the base for all the Swing components used in a window as part of the GUI, so, since this class is derived from Container, all of the Swing components are also containers. A container is any component with the Container class as a base; so all the Swing components are containers. The Container class is the direct base class for the Window class and it provides the ability to contain other components. Since the Container class is an abstract class, you cannot create instances of Container. Instead it is objects of the subclasses such as Window, JFrame, or JDialog that inherit the ability to contain other components. III. The Layout Manager. An object called a layout manager determines the way that components are arranged in a container. All containers will have a default layout manager but you can choose a different layout manager when necessary. There are many layout manager classes provided in the java.awt and javax.swing packages, so we will introduce those that you are most likely to need. It is possible to create your own layout manager classes, but creating layout managers is beyond the scope of this course. The layout manager for a container determines the position and size of all the components in the container: you should not change the size and position of such components yourself. Just let the layout manager take care of it. Since the classes that define layout managers all implement the LayoutManager interface, you can use a variable of type LayoutManager to store any of them if necessary. We will look at six layout manager classes in a little more detail. The flow layout manager places components in a row, and when the row is full, it automatically spills components onto the next row. The default positioning of the row of components is centered in the container. There are actually three possible row-positioning options that you specify by constants defined in the class. These are FlowLayout.LEFT, FlowLayout.RIGHT, and FlowLayout.CENTER – this last option being the default. The flow layout manager is very easy to use, so let's see it working in an example.
The code is quite simple. We create a FlowLayout object and make this the layout manager for aWindow by calling setLayout(). We then add six JButton components of a default size to aWindow in the loop. If you compile and run the program you should get a window similar to the following: The Button objects are positioned by the layout manager flow. As you can see, they have been added to the first row in the window, and the row is centered. You can confirm that the row is centered and see how the layout manger automatically spills the components on to the next row once a row is full by reducing the size of the window. Here the second row is clearly centered. Each button component has been set to its preferred size, which comfortably accommodates the text for the label. The centering is determined by the alignment constraint for the layout manager, which defaults to CENTER. It can also be set to RIGHT or LEFT by using a different constructor. For example, you could have created the layout manager with the statement: FlowLayout flow = new FlowLayout(FlowLayout.LEFT); The flow layout manager then left-aligns each row of components in the container. If you run the program with this definition and resize the window, it will look like: Now the buttons are left aligned. Two of the buttons have spilled from the first row to the second because there is insufficient space across the width of the window to accommodate them all. The flow layout manager in the previous examples applies a default gap of 5 pixels between components in a row, and between one row and the next. You can choose values for the horizontal and vertical gaps by using yet another FlowLayout constructor. You can set the horizontal gap to 20 pixels and the vertical gap to 30 pixels with the statement: FlowLayout flow = new FlowLayout(FlowLayout.LEFT, 20, 30); If you run the program with this definition of the layout manager, when you resize the window you will see the components distributed with the spacing specified. You can also set the gaps between components and rows explicitly by calling the setHgap() or the setVgap() method. To set the horizontal gap to 35 pixels, you would write: flow.setHgap(35); // Set the horizontal gap Don't be misled by this. You can't get differential spacing between components by setting the gap before adding each component to a container. The last values for the gaps between components that you set for a layout manager will apply to all the components in a container. The methods getHgap() and getVgap() will return the current setting for the horizontal or vertical gap as a value of type int. The initial size at which the application window is displayed is determined by the values we pass to the setBounds() method for the JFrame object. If you want the window to assume a size that just accommodates the components it contains, you can call the pack() method for the JFrame object. Add the following line immediately before the call to setVisible(): aWindow.pack(); If you recompile and run the example again, the application window should fit the components. IV. Mouse Events - Overview The mouse listeners allow you to receive events to process:
Normally handled for you. The mouse is handled automatically by most components, so you never have to know about it. For example, if someone clicks on a button (JButton), the JButton translates that click into an ActionEvent, which is a higher level event that can be caused by a number of things. You don't need to know (and shouldn't care) whether the ActionEvent was from a mouse click on the button, or from a keyboard shortcut, or hitting enter while that button had focus. Sometimes used with graphics. If you are are drawing your own graphics (eg, on a JComponent or JPanel) and need to know where the user clicks, then you need to know about mouse events. You can easily add a mouse listener to a JComponent or JPanel. Important Classes and InterfacesThese classes and interfaces are defined in java.awt.event. The first three are the most commonly used.
MouseListener This type of mouse listener is for events which typically don't happen very often -- a mouse button is pressed, released, or the mouse enters or leaves the area of the component with a listener. Here are the actions that a MouseListener catches.
To listen for these events you will use addMouseListener. MouseListener InterfaceTo implement a MouseListener interface, you must define the following methods. You can copy these definitions into your program and only make a meaningful body for those methods that are of interest. public void mousePressed(MouseEvent e) {}
To Get the Mouse CoordinatesAll coordinates are relative to the upper left corner of the component with the mouse listener. Use the following MouseEvent methods to get x and y coordinates of where the mouse event occurred.
To Check for Double ClicksUse the MouseEvent method below for a count of the number of clicks.
MouseMotionListenerMoves and drags. When you move the mouse, the interface generates events very rapidly. If a mouse button is depressed, then this is called a drag. Events from a move or drag are generated very quickly, and can be listed to by adding a mouse motion listener. MouseMotionListener methodsTo implement a MouseMotionListener, you define the following methods. public void mouseMoved(MouseEvent e) {}
public void mouseDragged(MouseEvent e) {}
Mouse ListenersThere are several styles for using the mouse listeners. They are usually
added to a graphics panel with a
class DrawingPanel extends JPanel implements MouseListener{
public DrawingPanel() { // Constructor
this.addMouseListener(this);
. . .
}
public void paintComponent(Graphics g) {
. . .
}
. . .
public void mousePressed(MouseEvent e) {. . .}
public void mouseReleased(MouseEvent e) {. . .}
public void mouseClicked(MouseEvent e) {. . .}
. . .
}
It can communicate changes with the outside by (1) making it a subclass, (2) supplying getter methods, or (3) supplying a "model" object to the constructor. public class MyClass implements MouseListener { This requires setter methods in the DrawingPanel class so that what is drawn can be changed. Or a constructor for DrawingPanel could be passed an object for the "model" that would allow it to get values needed by paintComponent. MouseAdapter or MouseMotionAdapter classes to create an anonymous listener. For example, to listen for mouse clicks, p.addMouseListener(new MouseAdapter() { Mouse Buttons. Java supports up to three mouse buttons. Even if your mouse doesn't have three separate buttons, you can simulate some of the buttons by pressing modifier keys when pressing the mouse button.
that allows you to ask which combinations of buttons were pressed when the event occurred. Mouse scroll controls were first supported in Java 2 SDK 1.4.
keys.
the MouseEvent modifier bits. This is a very fast way to check, especially for complex combinations of modifiers and buttons, but you need to understand the bit
operators ( To Use Methods to Check Mouse ButtonsTo check which mouse button is pressed, call one of the static methods in SwingUtilities. These methods return true if the corresponding button is being used. Note that more than one of them will be true if more than one button is in use at the same time.
To Use Methods to Check Modifier KeysTo check which modifier keys are pressed, use these methods in the MouseEvent class: boolean isAltDown() // true if Alt key middle mouse button boolean isControlDown() // true if Control key is pressed boolean isShiftDown() // true if Shift key is pressed boolean isAltGraphDown()// true if Alt Graphics key is pressed boolean isMetaDown() // true if Meta key or right mouse button For example, inside the mouse listener we could make a test like the following to see if the right mouse button is pressed while the shift key is down. Assume that if (SwingUtilities.isRightMouseButton(e) && e.isShiftDown()) To Use Bit Masks to Check Mouse Buttons and Modifier KeysUse the MouseEvent tells which buttons were pressed when the event occurred. The masks for each of the mouse buttons as well as modifier keys are:
To rewrite the previous example using bit masks to test whether the right mouse button is pressed while the shift key is down, we could do the following: int RIGHT_SHIFT_MASK = InputEvent.BUTTON3_MASK + InputEvent.SHIFT_MASK; . . . if ((e.getModifiers() & RIGHT_SHIFT_MASK) == RIGHT_SHIFT_MASK) { ...
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|