CMIS 412
DrawingPanel.java
DrawingPanel.java
// CMSC 330 Advanced Programming Languages
// Project 1 Skeleton
// UMGC CITE
// August 2021
import
java
.
awt
.
*
;
import
java
.
util
.
*
;
import
javax
.
swing
.
*
;
// Class that defines the panel for drawing the images
class
DrawingPanel
extends
JPanel
{
private
ArrayList
<
Image
>
images
=
new
ArrayList
<>
();
// Adds a graphic object to the drawing panel
public
void
addImage
(
Image
image
)
{
images
.
add
(
image
);
}
// Draws all the images on the drawing panel
@
Override
protected
void
paintComponent
(
Graphics
graphics
)
{
super
.
paintComponent
(
graphics
);
for
(
Image
image
:
images
)
image
.
draw
(
graphics
);
}
}
HollowPolygon.java
HollowPolygon.java
// CMSC 330 Advanced Programming Languages
// Project 1 Skeleton
// UMGC CITE
// August 2021
import
java
.
awt
.
*
;
// Class that defines all hollow polygons
class
HollowPolygon
extends
Polygon_
{
// Constructor that calls super constructor
public
HollowPolygon
(
Color
color
,
int
vertexCount
)
{
super
(
color
,
vertexCount
);
}
// Draws hollow polygon
@
Override
public
void
drawPolygon
(
Graphics
graphics
,
Polygon
polygon
)
{
graphics
.
drawPolygon
(
polygon
);
}
}
Image.java
Image.java
// CMSC 330 Advanced Programming Languages
// Project 1 Skeleton
// UMGC CITE
// August 2021
import
java
.
awt
.
*
;
// Abstract base class that defines all image objects
abstract
class
Image
{
private
Color
color
;
// Constructor that can only be called by the subclasses to initialize the color
public
Image
(
Color
color
)
{
this
.
color
=
color
;
}
// Sets the color of the image to be drawn. Must be called first by the draw function of the subclasses
public
void
colorDrawing
(
Graphics
graphics
)
{
graphics
.
setColor
(
color
);
}
abstract
void
draw
(
Graphics
graphics
);
}
Lexer.java
Lexer.java
// CMSC 330 Advanced Programming Languages
// Project 1 Skeleton
// UMGC CITE
// August 2021
import
java
.
io
.
*
;
// This class provides the lexical analyzer for project 1
class
Lexer
{
private
StreamTokenizer
tokenizer
;
private
String
punctuation
=
",;.()"
;
private
Token
[]
punctuationTokens
=
{
Token
.
COMMA
,
Token
.
SEMICOLON
,
Token
.
PERIOD
,
Token
.
LEFT_PAREN
,
Token
.
RIGHT_PAREN
};
// Constructor that creates a lexical analyzer object given the source file
public
Lexer
(
File
file
)
throws
FileNotFoundException
{
tokenizer
=
new
StreamTokenizer
(
new
FileReader
(
file
));
tokenizer
.
ordinaryChar
(
'.'
);
tokenizer
.
quoteChar
(
'"'
);
}
// Returns the next token in the input stream
public
Token
getNextToken
()
throws
LexicalError
,
IOException
{
int
token
=
tokenizer
.
nextToken
();
switch
(
token
)
{
case
StreamTokenizer
.
TT_NUMBER
:
return
Token
.
NUMBER
;
case
StreamTokenizer
.
TT_WORD
:
for
(
Token
aToken
:
Token
.
values
())
if
(
aToken
.
name
().
replace
(
"_"
,
""
).
equals
(
tokenizer
.
sval
.
toUpperCase
()))
return
aToken
;
return
Token
.
IDENTIFIER
;
case
StreamTokenizer
.
TT_EOF
:
return
Token
.
EOF
;
default
:
for
(
int
i
=
0
;
i
<
punctuation
.
length
();
i
++
)
if
(
token
==
punctuation
.
charAt
(
i
))
return
punctuationTokens
[
i
];
}
return
Token
.
EOF
;
}
// Returns the lexeme associated with the current token
public
String
getLexeme
()
{
return
tokenizer
.
sval
;
}
// Returns the numeric value of the current token for numeric tokens
public
int
getNumber
()
{
return
(
int
)
tokenizer
.
nval
;
}
// Returns the current line of the input file
public
int
getLineNo
()
{
return
tokenizer
.
lineno
();
}
}
LexicalError.java
LexicalError.java
// CMSC 330 Advanced Programming Languages
// Project 1 Skeleton
// UMGC CITE
// August 2021
// Class that defines a lexical error
class
LexicalError
extends
Exception
{
// Constructor that creates a lexical error object given the line number and error
public
LexicalError
(
int
line
,
String
description
)
{
super
(
"Lexical Error on Line: "
+
line
+
" "
+
description
);
}
}
Main.java
Main.java
// CMSC 330 Advanced Programming Languages
// Project 1 Skeleton
// UMGC CITE
// August 2021
import
java
.
io
.
*
;
import
java
.
util
.
*
;
import
javax
.
swing
.
*
;
// Project 1 main class
class
Main
{
// The main method of the whole program, allows the name of the scene definition file to be input on the
// command line or selected using the file chooser dialog window. It calls the parser to parse the scene
// definition file and add the graphic objects to the scene.
public
static
void
main
(
String
[]
args
)
{
Scanner
stdin
=
new
Scanner
(
System
.
in
);
String
sceneFileName
;
File
sceneFile
;
Scene
scene
;
JFileChooser
choice
=
new
JFileChooser
(
new
File
(
"."
));
int
option
=
choice
.
showOpenDialog
(
null
);
if
(
option
==
JFileChooser
.
APPROVE_OPTION
)
sceneFile
=
choice
.
getSelectedFile
();
else
{
System
.
out
.
print
(
"Enter scene file name or a single space to choose file from window: "
);
sceneFileName
=
stdin
.
nextLine
();
sceneFile
=
new
File
(
sceneFileName
);
}
try
{
Parser
parser
=
new
Parser
(
sceneFile
);
scene
=
parser
.
parseScene
();
scene
.
draw
();
}
catch
(
SyntaxError
error
)
{
System
.
out
.
println
(
error
.
getMessage
());
}
catch
(
LexicalError
error
)
{
System
.
out
.
println
(
error
.
getMessage
());
}
catch
(
IOException
error
)
{
System
.
out
.
println
(
"IO Error"
);
}
}
}
Parser.java
Parser.java
// CMSC 330 Advanced Programming Languages
// Project 1 Skeleton
// UMGC CITE
// August 2021
import
java
.
awt
.
*
;
import
java
.
io
.
*
;
import
java
.
util
.
*
;
import
javax
.
swing
.
*
;
// This class provides the skeleton parser for project 1
class
Parser
{
private
JFrame
window
;
private
Token
token
;
private
Lexer
lexer
;
// Constructor to create new lexical analyzer from input file
public
Parser
(
File
file
)
throws
IOException
{
lexer
=
new
Lexer
(
file
);
}
// Parses the production
// scene -> SCENE IDENTIFIER number_list images END '.'
public
Scene
parseScene
()
throws
LexicalError
,
SyntaxError
,
IOException
{
verifyNextToken
(
Token
.
SCENE
);
verifyNextToken
(
Token
.
IDENTIFIER
);
String
window
=
lexer
.
getLexeme
();
int
[]
dimensions
=
getNumberList
(
2
);
Scene
scene
=
new
Scene
(
window
,
dimensions
[
0
],
dimensions
[
1
]);
parseImages
(
scene
,
lexer
.
getNextToken
());
verifyNextToken
(
Token
.
PERIOD
);
return
scene
;
}
// Parses the following productions
// images -> image images | image
// image -> right_triangle | rectangle
// right_triangle -> RIGHT_TRIANGLE COLOR number_list AT number_list HEIGHT NUMBER WIDTH NUMBER ';'
// rectangle -> RECTANGLE_ COLOR number_list AT number_list HEIGHT NUMBER WIDTH NUMBER ';'
private
void
parseImages
(
Scene
scene
,
Token
imageToken
)
throws
LexicalError
,
SyntaxError
,
IOException
{
int
height
,
width
,
offset
,
radius
;
verifyNextToken
(
Token
.
COLOR
);
int
[]
colors
=
getNumberList
(
3
);
Color
color
=
new
Color
(
colors
[
0
],
colors
[
1
],
colors
[
2
]);
verifyNextToken
(
Token
.
AT
);
int
[]
location
=
getNumberList
(
2
);
Point
point
=
new
Point
(
location
[
0
],
location
[
1
]);
if
(
imageToken
==
Token
.
RIGHT_TRIANGLE
)
{
verifyNextToken
(
Token
.
HEIGHT
);
verifyNextToken
(
Token
.
NUMBER
);
height
=
lexer
.
getNumber
();
verifyNextToken
(
Token
.
WIDTH
);
verifyNextToken
(
Token
.
NUMBER
);
width
=
lexer
.
getNumber
();
RightTriangle
triangle
=
new
RightTriangle
(
color
,
point
,
height
,
width
);
scene
.
addImage
(
triangle
);
}
else
if
(
imageToken
==
Token
.
RECTANGLE
)
{
verifyNextToken
(
Token
.
HEIGHT
);
verifyNextToken
(
Token
.
NUMBER
);
height
=
lexer
.
getNumber
();
verifyNextToken
(
Token
.
WIDTH
);
verifyNextToken
(
Token
.
NUMBER
);
width
=
lexer
.
getNumber
();
Rectangle
rectangle
=
new
Rectangle
(
color
,
point
,
height
,
width
);
scene
.
addImage
(
rectangle
);
}
else
{
throw
new
SyntaxError
(
lexer
.
getLineNo
(),
"Unexpected image name "
+
imageToken
);
}
verifyNextToken
(
Token
.
SEMICOLON
);
token
=
lexer
.
getNextToken
();
if
(
token
!=
Token
.
END
)
parseImages
(
scene
,
token
);
}
// Parses the following productions
// number_list -> '(' numbers ')'
// numbers -> NUMBER | NUMBER ',' numbers
// Returns an array of the numbers in the number list
private
int
[]
getNumberList
(
int
count
)
throws
LexicalError
,
SyntaxError
,
IOException
{
int
[]
list
=
new
int
[
count
];
verifyNextToken
(
Token
.
LEFT_PAREN
);
for
(
int
i
=
0
;
i
<
count
;
i
++
)
{
verifyNextToken
(
Token
.
NUMBER
);
list
[
i
]
=
lexer
.
getNumber
();
token
=
lexer
.
getNextToken
();
if
(
i
<
count
-
1
)
verifyCurrentToken
(
Token
.
COMMA
);
else
verifyCurrentToken
(
Token
.
RIGHT_PAREN
);
}
return
list
;
}
// Returns a list of numbers
private
int
[]
getNumberList
()
throws
LexicalError
,
SyntaxError
,
IOException
{
ArrayList
<
Integer
>
list
=
new
ArrayList
<
Integer
>
();
verifyNextToken
(
Token
.
LEFT_PAREN
);
do
{
verifyNextToken
(
Token
.
NUMBER
);
list
.
add
((
int
)
lexer
.
getNumber
());
token
=
lexer
.
getNextToken
();
}
while
(
token
==
Token
.
COMMA
);
verifyCurrentToken
(
Token
.
RIGHT_PAREN
);
int
[]
values
=
new
int
[
list
.
size
()];
for
(
int
i
=
0
;
i
<
values
.
length
;
i
++
)
values
[
i
]
=
list
.
get
(
i
);
return
values
;
}
// Verifies that the next token is the expected token
private
void
verifyNextToken
(
Token
expectedToken
)
throws
LexicalError
,
SyntaxError
,
IOException
{
token
=
lexer
.
getNextToken
();
verifyCurrentToken
(
expectedToken
);
}
// Verifies that the current token is the expected token
private
void
verifyCurrentToken
(
Token
expectedToken
)
throws
SyntaxError
{
if
(
token
!=
expectedToken
)
throw
new
SyntaxError
(
lexer
.
getLineNo
(),
"Expecting token "
+
expectedToken
+
" not "
+
token
);
}
}
Polygon_.java
Polygon_.java
// CMSC 330 Advanced Programming Languages
// Project 1 Skeleton
// UMGC CITE
// August 2021
import
java
.
awt
.
*
;
// Abstract base class for all polygon classes
abstract
class
Polygon_
extends
Image
{
private
int
vertexCount
;
private
Polygon
polygon
;
// Constructor that initializes color and vertexCount of a polygon
public
Polygon_
(
Color
color
,
int
vertexCount
)
{
super
(
color
);
this
.
vertexCount
=
vertexCount
;
}
// Creates a polygon object given its vertices
public
void
createPolygon
(
int
[]
x_points
,
int
[]
y_points
)
{
polygon
=
new
Polygon
(
x_points
,
y_points
,
vertexCount
);
}
// Draws polygon using polygon object
@
Override
public
void
draw
(
Graphics
graphics
)
{
colorDrawing
(
graphics
);
drawPolygon
(
graphics
,
polygon
);
}
abstract
public
void
drawPolygon
(
Graphics
graphics
,
Polygon
polygon
);
}
Rectangle.java
Rectangle.java
// CMSC 330 Advanced Programming Languages
// Project 1 Skeleton
// UMGC CITE
// August 2021
import
java
.
awt
.
*
;
// Class that defines a hollow rectangle object
class
Rectangle
extends
HollowPolygon
{
// Constructor that initializes the vertices of the rectangle
public
Rectangle
(
Color
color
,
Point
upperLeft
,
int
height
,
int
width
)
{
super
(
color
,
4
);
int
[]
x_points
=
{
upperLeft
.
x
,
upperLeft
.
x
+
width
,
upperLeft
.
x
+
width
,
upperLeft
.
x
};
int
[]
y_points
=
{
upperLeft
.
y
,
upperLeft
.
y
,
upperLeft
.
y
+
height
,
upperLeft
.
y
+
height
};
createPolygon
(
x_points
,
y_points
);
}
}
RightTriangle.java
RightTriangle.java
// CMSC 330 Advanced Programming Languages
// Project 1 Skeleton
// UMGC CITE
// August 2021
import
java
.
awt
.
*
;
// Class that defines a hollow right triangle
class
RightTriangle
extends
HollowPolygon
{
// Constructor that initializes the vertices of the right triangle
public
RightTriangle
(
Color
color
,
Point
upperLeft
,
int
height
,
int
width
)
{
super
(
color
,
3
);
int
[]
x_points
=
{
upperLeft
.
x
,
upperLeft
.
x
,
upperLeft
.
x
+
width
};
int
[]
y_points
=
{
upperLeft
.
y
,
upperLeft
.
y
+
height
,
upperLeft
.
y
+
height
};
createPolygon
(
x_points
,
y_points
);
}
}
Scene.java
Scene.java
// CMSC 330 Advanced Programming Languages
// Project 1 Skeleton
// UMGC CITE
// August 2021
import
javax
.
swing
.
*
;
// Class that defines a scene
class
Scene
{
private
JFrame
window
;
private
DrawingPanel
drawing
;
// Constructor that must be supplied the height and width of the drawing window for the scene
public
Scene
(
String
name
,
int
height
,
int
width
)
{
window
=
new
JFrame
(
name
);
window
.
setSize
(
width
,
height
);
window
.
setDefaultCloseOperation
(
JFrame
.
EXIT_ON_CLOSE
);
drawing
=
new
DrawingPanel
();
window
.
add
(
drawing
);
}
// Adds a graphic object to the scene's drawing panel
public
void
addImage
(
Image
image
)
{
drawing
.
addImage
(
image
);
}
// Causes the drawing panel to be repainted
public
void
draw
()
{
window
.
setVisible
(
true
);
drawing
.
repaint
();
}
}
scene.txt
Scene Polygons (500, 500) RightTriangle Color (255, 0, 0) at (50, 30) Height 100 Width 300; Rectangle Color (0, 128, 255) at (100, 100) Height 200 Width 100; End.
SyntaxError.java
SyntaxError.java
// CMSC 330 Advanced Programming Languages
// Project 1 Skeleton
// UMGC CITE
// August 2021
// Class that defines a syntax error
class
SyntaxError
extends
Exception
{
// Constructor that creates a syntax error object given the line number and error
public
SyntaxError
(
int
line
,
String
description
)
{
super
(
"Syntax Error on Line: "
+
line
+
" "
+
description
);
}
}
Token.java
Token.java
// CMSC 330 Advanced Programming Languages
// Project 1 Skeleton
// UMGC CITE
// August 2021
// Enumerated type that defines the list of tokens
enum
Token
{
AT
,
COLOR
,
END
,
HEIGHT
,
RECTANGLE
,
RIGHT_TRIANGLE
,
SCENE
,
WIDTH
,
COMMA
,
SEMICOLON
,
PERIOD
,
LEFT_PAREN
,
RIGHT_PAREN
,
IDENTIFIER
,
NUMBER
,
EOF
}