Draw a shape with a different color (JavaFX)
Circle.java
Circle.java
import
java
.
awt
.
*
;
import
java
.
util
.
zip
.
CheckedInputStream
;
// File name: Circle.java
// Written by: Richard X. Mercado
// Description: This program is a subclass of GeometricObjects, inherits its abstract methods, and
// performs task related to Cirlce shape.
// Challenges:
// Time Spent: 7 days on GeometricShapes Project
// Revision History:
// Date: By: Action:
// ---------------------------------------------------
// 02/19/2021 Richard Mercado Created everything but equals()
// 02/20/2021 Richard Mercado Created equals()
public
class
Circle
extends
GeometricObject
{
//instance variable
private
double
radius
;
//constructors
public
Circle
()
{
}
//constructor
public
Circle
(
double
radius
)
{
this
.
radius
=
radius
;
}
//constructor
public
Circle
(
double
radius
,
String
color
,
boolean
filled
){
super
(
color
,
filled
);
getDate
();
this
.
radius
=
radius
;
}
//set and get methods
public
void
setRadius
(
double
radius
)
{
this
.
radius
=
radius
;
}
public
double
getRadius
(){
return
radius
;
}
//determines with if the radius of each obj are equals to each other
public
boolean
equals
(
Circle
o
){
if
((
this
.
getRadius
()
==
o
.
getRadius
()))
return
true
;
return
false
;
}
//inherited abstract method - determines how to get the area of a circle
@
Override
public
double
getArea
(){
return
(
radius
*
radius
*
Math
.
PI
);
}
//inherited abstract method - calculates the perimeter of specific shape
@
Override
public
double
getPerimeter
()
{
return
(
2
*
radius
*
Math
.
PI
);
}
//inherited abstract method - display name of shape
@
Override
public
String
getObjName
(){
return
"[Circle]"
;
}
//inherited abstract method - display strings for how to draw specific shape
@
Override
public
String
howToDraw
()
{
return
String
.
format
(
"Circle color: %s and filled: %s"
,
getColor
(),
isFilled
());
}
//Display string for objects
@
Override
public
String
toString
(){
return
String
.
format
(
"%s Radius: %.2f Circle's Area: %.2f Circle's Perimeter: %.2f"
,
getObjName
(),
getRadius
(),
getArea
(),
getPerimeter
());
}
}
Colorable.java
Colorable.java
// File name: Colorable.java
// Written by: Richard X. Mercado
// Description: This program creates super constructors that will be used through out the entire program for created
// other constructors with color and filled instance variables and abstract method howToDraw that will
// be inherited by GeometricObject abstract class
// Challenges: No challenges with colorable class
// Time Spent: 7 days on GeometricShapes Project
// Revision History:
// Date: By: Action:
// ---------------------------------------------------
// 02/15/2021 Richard Mercado created entire colorable abstract class
public
abstract
class
Colorable
{
//instance variables
private
String
color
;
private
boolean
filled
;
//constructor
public
Colorable
()
{
color
=
"WHITE"
;
filled
=
false
;
}
//constructor
public
Colorable
(
String
color
,
boolean
filled
)
{
this
.
color
=
color
;
this
.
filled
=
filled
;
}
//set and get method
public
String
getColor
()
{
return
color
;
}
public
void
setColor
(
String
color
)
{
this
.
color
=
color
;
}
public
void
setFilled
(
boolean
isFilled
)
{
filled
=
isFilled
;
}
//isFilled method
public
boolean
isFilled
()
{
return
filled
;
}
//abstract howToDraw methods
public
abstract
String
howToDraw
();
}
Controller.java
Controller.java
public
class
Controller
{
}
GeometricObject.java
GeometricObject.java
// File name: GeometricObject.java
// Written by: Richard X. Mercado
// Description: subclass of Colorable. this class has the methods to compare two objects, create a clone of an object,
// and determines the greatest of the two objects being compared by there area
// Challenges: Creating the compareTo method, static max method,
// Time Spent:7 days on GeometricShapes Project
// Revision History:
// Date: By: Action:
// ---------------------------------------------------
/* 02/16/2021 Richard Mercado Created everything but compareTo(), max(), and clone()
02/17/2021 Richard Mercado Created clone()
02/19/2021 Richard Mercado Created max()
02/20/2021 Richard Mercado Created compareTo()
*/
import
java
.
util
.
Date
;
public
abstract
class
GeometricObject
extends
Colorable
implements
Comparable
<
GeometricObject
>
,
Cloneable
{
//instance variables
private
Date
dateCreated
;
//Constructors
public
GeometricObject
(){
super
();
dateCreated
=
new
Date
();
}
//constructor
public
GeometricObject
(
String
color
,
boolean
filled
)
{
super
(
color
,
filled
);
dateCreated
=
new
Date
();
}
//additional methods
public
Date
getDate
(){
return
dateCreated
;
}
//compares objects by there area and determines if obj is either greater, less, or equal
public
int
compareTo
(
GeometricObject
o
)
{
if
(
this
.
getArea
()
<
o
.
getArea
())
return
-
1
;
if
(
this
.
getArea
()
>
o
.
getArea
())
return
1
;
return
0
;
}
//Created a clone of an object
@
Override
public
Object
clone
()
throws
CloneNotSupportedException
{
return
super
.
clone
();
}
//uses compareTo() and compares two objs and determines which one is greater
public
static
GeometricObject
max
(
GeometricObject
obj1
,
GeometricObject
obj2
)
{
if
(
obj1
.
compareTo
(
obj2
)
==
1
)
return
obj1
;
else
return
obj2
;
}
//Display string for objects
@
Override
public
String
toString
(){
return
String
.
format
(
"Date Created: %s%n"
+
"Color: %s%n"
+
"Filled: %s%n"
,
dateCreated
,
getColor
(),
isFilled
());
}
//Abstract methods
public
abstract
String
getObjName
();
public
abstract
double
getArea
();
public
abstract
double
getPerimeter
();
}
MyJavaFX.java
MyJavaFX.java
import
javafx
.
application
.
Application
;
import
javafx
.
event
.
ActionEvent
;
import
javafx
.
event
.
Event
;
import
javafx
.
event
.
EventHandler
;
import
javafx
.
scene
.
Scene
;
import
javafx
.
scene
.
control
.
Button
;
import
javafx
.
scene
.
layout
.
*
;
import
javafx
.
stage
.
Stage
;
//import javafx.scene.ComboBoxBase;
import
javafx
.
scene
.
control
.
ComboBox
;
import
javafx
.
collections
.
FXCollections
;
import
javafx
.
geometry
.
Insets
;
import
javafx
.
scene
.
Group
;
import
javafx
.
scene
.
control
.
Label
;
import
javafx
.
scene
.
control
.
Slider
;
import
javafx
.
beans
.
value
.
ChangeListener
;
import
javafx
.
beans
.
value
.
ObservableValue
;
import
javafx
.
geometry
.
Pos
;
import
javafx
.
scene
.
control
.
CheckBox
;
import
javafx
.
scene
.
control
.
RadioButton
;
import
javafx
.
scene
.
control
.
TextField
;
import
javafx
.
scene
.
control
.
TitledPane
;
import
javafx
.
scene
.
control
.
ToggleGroup
;
public
class
MyJavaFX
extends
Application
{
public
static
final
String
SHAPE_CIRCLE
=
"Circle"
;
public
static
final
String
SHAPE_RECTANGLE
=
"Rectangle"
;
public
static
final
String
SHAPE_SQUARE
=
"Square"
;
public
static
final
String
SHAPE_TRIANGLE
=
"Triangle"
;
private
static
final
String
[]
shapes
=
{
SHAPE_CIRCLE
,
SHAPE_RECTANGLE
,
SHAPE_SQUARE
,
SHAPE_TRIANGLE
};
private
TextField
resultTextFieldShape
;
private
TextField
resultTextFieldInformation
;
private
TextField
resultTextFieldArea
;
private
TextField
resultTextFieldPerimeter
;
private
TextField
textFieldWidth
;
private
TextField
textFieldHeight
;
private
TextField
textFieldSide
;
private
Slider
opacityLevel
;
private
String
selectedShape
=
SHAPE_CIRCLE
;
private
String
selectedColor
=
"BLACK"
;
private
boolean
isFilled
=
false
;
private
GeometricObject
shape
;
//private final String[] shapes = {"Circle", "Rectangle", "Square", "Triangle"};
//ComboBox<String> chooseShape = new ComboBox<String>();
@
Override
public
void
start
(
Stage
stage
)
throws
Exception
{
//create title of stage
stage
.
setTitle
(
"Shape Chooser"
);
//Creating Main Pane
Pane
mainScene
=
new
Pane
();
//Setting size of Main Pane
mainScene
.
setPrefSize
(
800
,
590
);
//Creating Input Data Title Pane
TitledPane
gridTitlePane
=
new
TitledPane
();
gridTitlePane
.
relocate
(
50
,
50
);
//Creating Grid Pane
GridPane
gridExample
=
new
GridPane
();
gridExample
.
setVgap
(
8
);
gridExample
.
setPadding
(
new
Insets
(
10
,
10
,
10
,
10
));
//Creating BorderPane
BorderPane
paneForComboBox
=
new
BorderPane
();
paneForComboBox
.
setLeft
(
new
Label
(
"Select Geometric Shape"
));
paneForComboBox
.
relocate
(
50
,
20
);
//Creating Slider
opacityLevel
=
new
Slider
(
0
,
30
,
15
);
//final Label opacityCaption = new Label("Radius:");
gridExample
.
add
(
new
Label
(
"Radius: "
),
0
,
1
);
final
Label
opacityValue
=
new
Label
(
Double
.
toString
(
opacityLevel
.
getValue
()));
gridExample
.
setVgap
(
10
);
gridExample
.
setHgap
(
100
);
//Real Time value for slider
opacityLevel
.
valueProperty
().
addListener
(
new
ChangeListener
<
Number
>
()
{
@
Override
public
void
changed
(
ObservableValue
<?
extends
Number
>
ov
,
Number
old_val
,
Number
new_val
)
{
System
.
out
.
println
(
new_val
.
doubleValue
());
opacityValue
.
setText
(
String
.
format
(
"%.2f"
,
new_val
));
calculateArea
();
}
});
GridPane
.
setConstraints
(
opacityLevel
,
1
,
1
);
gridExample
.
getChildren
().
add
(
opacityLevel
);
gridExample
.
add
(
opacityValue
,
2
,
1
);
//GridPane.setConstraints(opacityValue, 2, 1);
//TextField objects for right alignment
textFieldWidth
=
new
TextField
();
textFieldWidth
.
setAlignment
(
Pos
.
CENTER_RIGHT
);
textFieldHeight
=
new
TextField
();
textFieldHeight
.
setAlignment
(
Pos
.
CENTER_RIGHT
);
textFieldSide
=
new
TextField
();
textFieldSide
.
setAlignment
(
Pos
.
CENTER_RIGHT
);
//Adding Labels
gridExample
.
add
(
new
Label
(
"Width: "
),
0
,
2
);
gridExample
.
add
(
textFieldWidth
,
1
,
2
);
gridExample
.
add
(
new
Label
(
"Height: "
),
0
,
3
);
gridExample
.
add
(
textFieldHeight
,
1
,
3
);
gridExample
.
add
(
new
Label
(
"Side: "
),
0
,
4
);
gridExample
.
add
(
textFieldSide
,
1
,
4
);
//Title for TitlePane, centering, and setting content
gridTitlePane
.
setText
(
"Input Data"
);
gridTitlePane
.
setAlignment
(
Pos
.
CENTER
);
gridTitlePane
.
setContent
(
gridExample
);
gridTitlePane
.
setPrefWidth
(
705
);
//Creating ComboBox
ComboBox
<
String
>
comboBox
=
new
ComboBox
<>
(
FXCollections
.
observableArrayList
(
shapes
));
comboBox
.
relocate
(
635
,
10
);
comboBox
.
getSelectionModel
().
select
(
0
);
// Create action event
EventHandler
<
ActionEvent
>
selectShapeEvent
=
e
->
handleShapeChange
(
comboBox
.
getValue
());
// Set on action
comboBox
.
setOnAction
(
selectShapeEvent
);
//Creating Check Box
CheckBox
checkBox
=
new
CheckBox
(
"Filled"
);
gridExample
.
add
(
checkBox
,
3
,
1
);
RadioButton
radioButton1
=
new
RadioButton
(
"Black"
);
radioButton1
.
setSelected
(
true
);
radioButton1
.
requestFocus
();
RadioButton
radioButton2
=
new
RadioButton
(
"Red"
);
RadioButton
radioButton3
=
new
RadioButton
(
"Green"
);
RadioButton
radioButton4
=
new
RadioButton
(
"Blue"
);
ToggleGroup
radioGroup
=
new
ToggleGroup
();
radioButton1
.
setToggleGroup
(
radioGroup
);
radioButton2
.
setToggleGroup
(
radioGroup
);
radioButton3
.
setToggleGroup
(
radioGroup
);
radioButton4
.
setToggleGroup
(
radioGroup
);
EventHandler
<
ActionEvent
>
e
=
event
->
{
selectedColor
=
((
RadioButton
)
event
.
getSource
()).
getText
().
toUpperCase
();
if
(
shape
!=
null
)
shape
.
setColor
(
selectedColor
);
updateUI
(
shape
);
};
radioButton1
.
setOnAction
(
e
);
radioButton2
.
setOnAction
(
e
);
radioButton3
.
setOnAction
(
e
);
radioButton4
.
setOnAction
(
e
);
VBox
vbox
=
new
VBox
(
radioButton1
,
radioButton2
,
radioButton3
,
radioButton4
);
gridExample
.
add
(
vbox
,
3
,
2
);
//Creating Result Title Pane
TitledPane
resultTitlePane
=
new
TitledPane
();
resultTitlePane
.
setCollapsible
(
false
);
resultTitlePane
.
relocate
(
50
,
320
);
//Creating ResultExample Pane
GridPane
resultExample
=
new
GridPane
();
resultExample
.
setVgap
(
8
);
resultExample
.
setPadding
(
new
Insets
(
10
,
10
,
10
,
10
));
resultTextFieldShape
=
new
TextField
();
resultTextFieldShape
.
setAlignment
(
Pos
.
TOP_LEFT
);
resultTextFieldShape
.
setPrefWidth
(
600
);
resultTextFieldShape
.
setEditable
(
false
);
resultTextFieldInformation
=
new
TextField
();
resultTextFieldInformation
.
setAlignment
(
Pos
.
TOP_LEFT
);
resultTextFieldInformation
.
setEditable
(
false
);
resultTextFieldArea
=
new
TextField
();
resultTextFieldArea
.
setAlignment
(
Pos
.
TOP_LEFT
);
resultTextFieldArea
.
setEditable
(
false
);
resultTextFieldPerimeter
=
new
TextField
();
resultTextFieldPerimeter
.
setAlignment
(
Pos
.
TOP_LEFT
);
resultTextFieldPerimeter
.
setEditable
(
false
);
//Creating Result Title Pane Labels
resultExample
.
add
(
new
Label
(
"Shape: "
),
0
,
2
);
resultExample
.
add
(
resultTextFieldShape
,
1
,
2
);
resultExample
.
add
(
new
Label
(
"Information: "
),
0
,
3
);
resultExample
.
add
(
resultTextFieldInformation
,
1
,
3
);
resultExample
.
add
(
new
Label
(
"Area: "
),
0
,
4
);
resultExample
.
add
(
resultTextFieldArea
,
1
,
4
);
resultExample
.
add
(
new
Label
(
"Perimeter: "
),
0
,
5
);
resultExample
.
add
(
resultTextFieldPerimeter
,
1
,
5
);
//Title name, centering, and setting
resultTitlePane
.
setText
(
"Result"
);
resultTitlePane
.
setAlignment
(
Pos
.
CENTER
);
resultTitlePane
.
setContent
(
resultExample
);
TitledPane
bottomButtonTitlePane
=
new
TitledPane
();
bottomButtonTitlePane
.
setCollapsible
(
false
);
bottomButtonTitlePane
.
relocate
(
50
,
550
);
//Creating ResultExample Pane
GridPane
bottomExample
=
new
GridPane
();
bottomExample
.
setVgap
(
8
);
bottomExample
.
setPadding
(
new
Insets
(
10
,
10
,
10
,
10
));
//Calculate, Clear, and Exit Buttons
Button
calculateButton
=
new
Button
(
"Calculate"
);
Button
clearButton
=
new
Button
(
"Clear"
);
Button
exitButton
=
new
Button
(
"Exit"
);
int
prefButtonWidth
=
120
;
calculateButton
.
setPrefWidth
(
prefButtonWidth
);
clearButton
.
setPrefWidth
(
prefButtonWidth
);
exitButton
.
setPrefWidth
(
prefButtonWidth
);
Group
bottomButtonGroup
=
new
Group
();
bottomButtonGroup
.
getChildren
().
add
(
calculateButton
);
bottomButtonGroup
.
getChildren
().
add
(
clearButton
);
bottomButtonGroup
.
getChildren
().
add
(
exitButton
);
HBox
hbox
=
new
HBox
(
calculateButton
,
clearButton
,
exitButton
);
hbox
.
setAlignment
(
Pos
.
CENTER
);
hbox
.
setPrefWidth
(
680
);
bottomExample
.
add
(
hbox
,
4
,
2
);
bottomExample
.
relocate
(
50
,
520
);
//bottomButtonTitlePane.setText("Result");
//bottomButtonTitlePane.setAlignment(Pos.CENTER);
//bottomButtonTitlePane.setContent(bottomExample);
///////////////////////////////////////////////////////////////////////////
//check box action
checkBox
.
setOnAction
(
new
EventHandler
<
ActionEvent
>
()
{
@
Override
public
void
handle
(
ActionEvent
event
)
{
//update shape and UI
isFilled
=
checkBox
.
isSelected
();
if
(
shape
!=
null
)
shape
.
setFilled
(
isFilled
);
updateUI
(
shape
);
}
});
calculateButton
.
setOnAction
((
ActionEvent
event
)
->
calculateArea
());
clearButton
.
setOnAction
((
ActionEvent
event
)
->
{
//clear all fields and reset to circle
comboBox
.
getSelectionModel
().
select
(
0
);
checkBox
.
setSelected
(
false
);
radioButton1
.
setSelected
(
true
);
isFilled
=
false
;
selectedColor
=
"BLACK"
;
selectedShape
=
SHAPE_CIRCLE
;
if
(
shape
!=
null
)
{
shape
.
setColor
(
selectedColor
);
shape
.
setFilled
(
isFilled
);
}
handleShapeChange
(
selectedShape
);
});
//Exit Button ACTION
exitButton
.
setOnAction
((
ActionEvent
event
)
->
{
System
.
exit
(
0
);
});
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
//Retreiving and storing all children to mainScene
mainScene
.
getChildren
().
addAll
(
paneForComboBox
,
comboBox
,
gridTitlePane
,
gridExample
,
resultTitlePane
,
resultExample
,
bottomExample
);
//update shape initially to circle
handleShapeChange
(
SHAPE_CIRCLE
);
//Creating, setting, and displaying scene
Scene
scene
=
new
Scene
(
mainScene
);
stage
.
setScene
(
scene
);
stage
.
show
();
}
private
void
handleShapeChange
(
String
shape
)
{
//clear current data
clearFields
();
//enable fields relevant to shape
selectedShape
=
shape
;
switch
(
shape
)
{
case
SHAPE_CIRCLE
:
opacityLevel
.
setDisable
(
false
);
break
;
case
SHAPE_RECTANGLE
:
textFieldHeight
.
setDisable
(
false
);
textFieldWidth
.
setDisable
(
false
);
break
;
case
SHAPE_SQUARE
:
textFieldSide
.
setDisable
(
false
);
break
;
case
SHAPE_TRIANGLE
:
textFieldSide
.
setDisable
(
false
);
textFieldHeight
.
setDisable
(
false
);
textFieldWidth
.
setDisable
(
false
);
break
;
}
}