0% found this document useful (0 votes)
9 views

Lab 2

The document provides instructions for students to modify an existing GUI application called 'DSA2020_GUI' to add new features. It describes how to add a class called 'SpaceMapping' and make the application display the mouse position. It also explains how to create basic geometry classes like 'Point2D' and draw them using Java graphics APIs.

Uploaded by

Tùng Trần
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
9 views

Lab 2

The document provides instructions for students to modify an existing GUI application called 'DSA2020_GUI' to add new features. It describes how to add a class called 'SpaceMapping' and make the application display the mouse position. It also explains how to create basic geometry classes like 'Point2D' and draw them using Java graphics APIs.

Uploaded by

Tùng Trần
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 12

LAB #2

Thanh-Sach LE
[email protected]

March 30, 2020

1 Compile and run project “DSA2020_GUI“


I have shared will you a project named “DSA2020_GUI“ in the cloud folder1 shared with you at the
begining of the course.

Question 1
Do the following tasks:
1. Compile the project

2. Explore the code (with helps from Mr. LAM and Mr. PHU) and try to understand it.

2 Add features to “DSA2020_GUI“


2.1 Class SpaceMapping

Question 2
Using the document accompanied with materiala to create class SpaceMapping in package geom
in “DSA2020_GUI“ .
a File: SpaceMapping.pdf

2.2 Print Mouse’s Location

Question 3
Do the tasks below:
1. Create an instance of SpaceMapping in class WorkingPanel .

2. Allow classWorkingPanel to implement methods defined in interface ComponentListener a .


3. Register the instance of classWorkingPanel as a processor for ComponentListener’s events.
4. Add code to methods defined in MouseMotionListener and MouseMotionListener to show
the mouse’s position as in Figure 2.
a java.awt.event.ComponentListener

1 Folder Project/Project1 from: The Cloud Folder

1
2.2.1 Print Mouse’s Location: Guideline
1. Create an instance of SpaceMapping in class WorkingPanel
• declare and initialize a data field inside of WorkingPanel , see Line 5, Figure 1.

2. Allow classWorkingPanel to implement methods defined in interface ComponentListener 2 .


• implements interface ComponentListener for WorkingPanel , see Line 3, Figure 1. You have
to add all methods defined in ComponentListener to class WorkingPanel .
• add implementation for method componentResized , see Line 28, Figure 1. Please note that,
you need to call this.spaceMapping.updateDevViewPort to update the viewport in the device.
This viewport depends on the size of the working panel, so you need to change it accordingly.
3. Register the instance of classWorkingPanel as a processor for ComponentListener’s events.
• call addComponentListener(this) to register WorkingPanel as a lister to component’s change.

4. Add code to methods defined in MouseMotionListener and MouseMotionListener to show the


mouse’s position as in Figure 2.
• call method this.spaceMapping.device2Logic(e.getX(), e.getY()); to convert mouse position in
device space to the logic space.
• Format and print string, see method mouseMoved , mouseDragged in Figure 1 for more detail.

3 Basic geometry objects


This section helps you to create basic geometry objects as following:

3.1 Class GeomObject


This class is the parent for all geometrical objects. So, it contains common data fields, constants, and
methods that should be supported by geometrical objects. Therefore, as you can see in Figure 3, Geo-
mObject contains data field edgeColor to keep the color for drawing the objects, and faceColor to
keep the color for filling the objects. It also contains method draw for drawing the object with given the
graphics and the space mapping objects.

Question 4
Do the following tasks:

1. Create a package named geom and Class GeomObject as shown in Figure 3.


2. Fill the constructor of Class GeomObject to initialize Field edgeColor with a colora created
from the following intensities: red = 20, green = 200, blue = 20;
3. Fill the constructor of Class GeomObject to initialize Field faceColor with red color.
a Please refer to Java Color for more information on using Java Color.

2 java.awt.event.ComponentListener

2
1 public class WorkingPanel extends JPanel
2 implements MouseMotionListener, MouseListener,
3 ItemListener, ActionListener, ComponentListener{
4

5 SpaceMapping spaceMapping = new SpaceMapping();


6 //here: more code
7 public WorkingPanel(){
8 this.setBorder(BorderFactory.createEtchedBorder());
9 this.addMouseMotionListener(this);
10 this.addMouseListener(this);
11 this.addComponentListener(this);
12 }
13 @Override
14 public void mouseDragged(MouseEvent e) {
15 Point2D logPoint = this.spaceMapping.device2Logic(e.getX(), e.getY
());
16 String message = String.format("mouseDragged: Device(x,y)=(%d,%d);
Logic(x,y)=(%6.2f, %6.2f)", e.getX(), e.getY(), logPoint.getX(),
logPoint.getY());
17 MainFrame.infoPanel.println(message);
18 }
19

20 @Override
21 public void mouseMoved(MouseEvent e) {
22 Point2D logPoint = this.spaceMapping.device2Logic(e.getX(), e.getY
());
23 String message = String.format("mouseMoved: Device(x,y)=(%d,%d);
Logic(x,y)=(%6.2f, %6.2f)", e.getX(), e.getY(), logPoint.getX(),
logPoint.getY());
24 MainFrame.infoPanel.println(message);
25 }
26 //here: similarly for other mouse events
27 @Override
28 public void componentResized(ComponentEvent e) {
29 Dimension size = this.getSize();
30 int xGap = 50, yGap = 20;
31 this.spaceMapping.updateDevViewPort(xGap, size.width-2*xGap, yGap,
size.height-2*yGap);
32 }
33

34 @Override
35 public void componentMoved(ComponentEvent e) {}
36

37 @Override
38 public void componentShown(ComponentEvent e) {}
39

40 @Override
41 public void componentHidden(ComponentEvent e) {}
42 }

Figure 1: Class WorkingPanel: sample code

3.2 Class Point2D


Class Point2D is a subclass of GeomObject , it means that an instance of Point2D is a geometrical
object. It overrides method draw to draw itself.

3
Figure 2: Demo application for Question 2: students are required to modify “DSA2020_GUI“ to show the
mouse’s position in the device space and the logic space as shown in message areas of the GUI. Adding
New button and drawing axis are exluded from Question 2.

1 package geom;
2 import java.awt.*;
3

4 public abstract class GeomObject {


5 protected Color edgeColor;
6 protected Color faceColor;
7 protected int line_weight = 1;
8 public GeomObject(){
9 /*Answer here*/
10 }
11 public abstract void draw(Graphics g, SpaceMapping mapper);
12 }

Figure 3: Class GeomObject

4
Question 5
Do the following tasks:

1. Create Class Poin2D in Package geom as shown in Figure 4. You need to fill the code at the
location marked as Reuse code from LAB1 with your answer for LAB1.
2. Modify the code to make Class Point2D be a subclass of Class GeomObject .
3. Fill method linear at the location marked as /*answer here*/ to do:

• create a point with y-coordinate computed by y = a ∗ x + b


• add this point to array “list“ at index “idx“.
4. Read the document of fillRect and then fill the code in method draw at the location marked
as /*answer here*/ .

5. Read document of fillOval then replace Line 53 in Figure 4 to show the point as a circle centering
at the point and having radius = P OIN T _HALF _SIZE.
Please refer to Java Color for more information on using Java Color.

3.3 Drawing using java.awt.Graphics


In Java, to draw objects in 2D, we can use API supported by package java.awt.Graphics or java.awt.Graphics2D
(Graphics2D is subclass of Graphics).
Students may have a question now. How do we obtain an instance of Graphics or Graphics2D ? The
answer is simple, you need to step:
1. Create a class subclassed from class javax.swing.JPanel .
2. Override method paintComponent . paintComponent is called from Swing framework whenever
it needs to redraw the component. It will pass an instance of Graphics to paintComponent . You can
check class WorkingPanel in the project supplied to you.
API of Graphics and Graphics2D only work with coordinates in a device space . Therefore, in
order to call draw , we need to pass an instance of class SpaceMapping . This class supports API for
converting coordinates from the device to the logic space and vice versa.
In this Lab, points are drawn as a square of size 2×POINT_HALF_SIZE+1; where, POINT_HALF_SIZE
is a static property of Point2D . As shown in Figure 4, the algoritm to draw a point is simple as explained
in the following.
1. Line 46: “Graphics2D g2 = (Graphics2D) g;“ It casts instance of Graphics to Graphics2D to have
more functionalities for drawing with 2D objects.
2. Line 47: call method logic2device to convert logical coordinates to device coordinates, i.e., in unit
of pixel.
3. Line 49-50: the result of previous step is the center of the square beging drawn for the point. So we
need to shift to obtain the left-top corner of the square.
4. Line 52: set color of the square by using data field faceColor .
5. Line 53: perform the drawing by calling method fillRect of Graphics2D.

3.4 Graph
A graph can be a polyline (e.g. quadratic or linear line in Figure 5) or and sequence of dots (e.g. sin
function in Figure 5). Graphs are usually used to visualize function or relation between variable x and y.
Functions are defined in an infinite range, so you need viewport for viewing them. Therefore, class Graph
must maintain the following information, see Figure 6 for an overview.

5
1. Viewport on the logic space for viewing graph. Remember, a viewport maintains four values: xMin,
xMax, yMin, and yMax (see class Viewport ).
2. List of points, look at sin function on Figure 5.
3. Mode of drawing; we draw as dots like sin function on Figure 5 or quadratic function on Figure 5.
4. Graph needs to extend from class GeomObject to inherit data fields and methods of geometrical
objects.
Method copyPoints (Line 77-84): assigning array of points received from the parameter to the data
field inside of Graph is not enough. A graph must maintain its viewport; so, it given a list of points,
copyPoints must do two tasks as follows:
1. copies the point list from the parameter.
2. finds the smallest rectangle that contains all the point int the list. It does this by: (a) initialize the
viewport to contain only the first, and (b) for each point in the list it enlarge the viewport to contain
the point (see method addPoint in class Viewport ).

Question 6
Do the following tasks:
1. Create class Graph from the source given partially in Figure 6, 7 and 8.

2. Try to understand the idea of method quaratic to generate a quaratic graph using parameters
given.
3. Copy the idea of quadratic generation, fill code for method sin in Figure 7.

Question 7
Do the following tasks:
1. Add button Graph to toolbar, see Figure 5.
2. When users press on button Graph do:

• Create a sin graph and a quaratic graph.


• Draw it on the screen.

3.4.1 Drawing graph of functions: guideline


1. Add button Graph to toolbar, see Figure 5.
• See Question 1 for how to do
2. When users press on button Graph do:
• You have to place the code for drawing in method paintComponent of class WorkingPanel ;
• but, you have to intialize the drawing from event processed for pressing button, i.e., in method
actionPerformed .
• From method actionPerformed you can not call paintComponent directly. Therefore, these
two methods must communicate via common data fields in class WorkingPanel .
(a) Declare two graphs (named sin , and quad ) as data fields in WorkingPanel .

6
(b) intialize sin , and quad in actionPerformed by calling to Graph.sin and Graph.quadratic
respectively.
(c) Inside of paintComponent , you check if sin / quad is not null, you call draw for sin
and quad . Remember, you need to pass instance of SpaceMapping (data field of class
WorkingPanel ) to draw to allow graphs doing coordinate conversion.

7
1 package geom;
2 import java.awt.*;
3 import java.util.Random;
4 public class Point2D /*answer here: Point2D is a subclass of GeomObject*/{
5 public static int POINT_HALF_SIZE = 2;
6 private double x;
7 private double y;
8 //Add setters and getters here: Reuse code from LAB1
9 public Point2D(){
10 this.x = 0; this.y = 0;
11 }
12 public Point2D(double x, double y){
13 this.x = x; this.y = y;
14 }
15 public Point2D(Point2D oldPoint){
16 this.x = oldPoint.x; this.y = oldPoint.y;
17 }
18 public Point2D clone(){
19 return new Point2D(this.x, this.y);
20 }
21 public String toString(){
22 return String.format("P(%6.2f, %6.2f)", this.x, this.y);
23 }
24 public static Point2D[] generate(int N, double min, double max){
25 //Reuse code from LAB1
26 }
27 public static Point2D[] linear(int N, double a, double b, double xMin,
double xMax){
28 Point2D[] list = new Point2D[N];
29 double step = (xMax - xMin)/(N-1); //xMax inclusive
30 double x = xMin;
31 for(int idx=0; idx < N; idx++){
32 /*answer here*/
33 x += step;
34 }
35 return list;
36 }
37 public static double distanceAB(Point2D a, Point2D b){
38 //Reuse code from LAB1
39 }
40 public double distanceTo(Point2D point){
41 //Reuse code from LAB1
42 }
43

44 @Override
45 public void draw(Graphics g, SpaceMapping mapper) {
46 Graphics2D g2 = (Graphics2D) g;
47 Point2D point = mapper.logic2Device(this.getX(), this.getY() );
48

49 int x = (int)point.getX() - POINT_HALF_SIZE;


50 int y = (int)point.getY() - POINT_HALF_SIZE;
51

52 g2.setColor(this.faceColor);
53 g2.fillRect(/*anwser here*/);
54 }
55 }

Figure 4: Class Point2D

8
Figure 5: Axis and graph

9
56 package geom;
57 import java.awt.*
58 public class Graph extends GeomObject{
59 public enum GraphMode {
60 LINE,
61 SCATTER
62 };
63 protected Viewport viewport = null;
64 private Point2D[] points = null;
65 private GraphMode mode = GraphMode.LINE;
66

67 //setter and getter for mode


68 public Graph(Point2D[] points, double xMin, double xMax, double yMin,
double yMax){
69 this.viewport = new Viewport(xMin, xMax, yMin, yMax);
70 this.points = points;
71 }
72 public Graph(Point2D[] points, double xMin, double xMax, double yMin,
double yMax, Color color){
73 this.viewport = new Viewport(xMin, xMax, yMin, yMax);
74 this.points = points;
75 this.edgeColor = color;
76 }
77 private void copyPoints(Point2D[] points){
78 this.points = points;
79 //update viewport
80 this.viewport = new Viewport(points[0].getX(), points[0].getX(),
81 points[0].getY(), points[0].getY());
82 for(int idx=0; idx < points.length; idx++)
83 this.viewport.addPoint(points[idx]);
84 }
85 public Graph(Point2D[] points){
86 copyPoints(points);
87 }
88 public Graph(Point2D[] points, Color color){
89 copyPoints(points);
90 this.edgeColor = color;
91 }
92 @Override
93 public void draw(Graphics g, SpaceMapping mapper) {
94 }
95 public static Graph sin(double a, double xMin, double xMax, double step
){
96 }
97 public static Graph quadratic(double a, double b, double c, double xMin
, double xMax, double
98 }
99 }

Figure 6: Class Graph: an overview of methods and data fields

10
101 package geom;
102 import java.awt.*
103 public class Graph extends GeomObject{
104 //here: more code
105 public static Graph sin(double a, double xMin, double xMax, double step
){
106 /*answer here/
107 }
108 public static Graph quadratic(double a, double b, double c, double xMin
, double xMax, double step){
109 int N = (int)((xMax - xMin)/step) + 1;
110 Point2D[] points = new Point2D[N];
111 double x = xMin;
112 for(int idx = 0; idx < N; idx++){
113 double y = a*x*x + b*x + c;
114 points[idx] = new Point2D(x, y);
115 x += step;
116 }
117 return new Graph(points);
118 }
119

120 //here: more code


121 }

Figure 7: Class Graph: Generating graph

11
122 package geom;
123 import java.awt.*
124 public class Graph extends GeomObject{
125 //here: more code
126 @Override
127 public void draw(Graphics g, SpaceMapping mapper) {
128 Graphics2D g2 = (Graphics2D) g;
129 //
130 if(this.mode == GraphMode.LINE){
131 if(this.points == null) return;
132 int[] x = new int[this.points.length];
133 int[] y = new int[this.points.length];
134 for(int idx=0; idx < this.points.length; idx++){
135 Point2D devPoint = mapper.logic2Device(this.points[idx]);
136 x[idx] = (int)devPoint.getX();
137 y[idx] = (int)devPoint.getY();
138 }
139 g2.setColor(this.edgeColor);
140 Stroke style = new BasicStroke(this.line_weight);
141 g2.setStroke(style);
142 g2.drawPolyline(x, y, x.length);
143 }
144 else if(this.mode == GraphMode.SCATTER){
145 for(int idx=0; idx < this.points.length; idx++){
146 this.points[idx].draw(g, mapper);
147 }
148 }
149 else{
150 throw new UnsupportedOperationException("Not supported yet.");
151 }
152 }
153 //here: more code
154 }

Figure 8: Class Graph: Drawing graph

12

You might also like