I have a Canvas.java class where I have a mousemove code to track the mouse position, and have it saved to an array. If I print this code out from this class itself, the mouse position is correctly printed. However, is there any way I can access this array from another class, and have it printed still (eg. I want it to appear as a Vaadin label in MainLayout.java)? It seems that the label is only showing '[]' in place of the coordinates I want printed.
Canvas.java:
package com.vaadin.starter.beveragebuddy.ui.components;
import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.HasSize;
import com.vaadin.flow.component.HasStyle;
import com.vaadin.flow.component.Tag;
import com.vaadin.flow.component.html.Label;
import com.vaadin.flow.dom.Element;
import com.vaadin.flow.dom.ElementFactory;
import elemental.json.JsonObject;
import java.util.ArrayList;
/**
* Canvas component that you can draw shapes and images on. It's a Java wrapper
* for the
* <a href="https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API">HTML5
* canvas</a>.
* <p>
* Use {#link #getContext()} to get API for rendering shapes and images on the
* canvas.
* <p>
*/
#Tag("canvas")
#SuppressWarnings("serial")
public class Canvas extends Component implements HasStyle, HasSize {
private CanvasRenderingContext2D context;
private Element element;
private boolean isDrawing = false;
private boolean mouseIsDown = false;
private double endX;
private double endY;
public static ArrayList <BoundingBox> arrayBoxes = new ArrayList<BoundingBox>();
public static ArrayList <MousePosition> mousePosArray = new ArrayList<MousePosition>();
public static ArrayList<BoundingBox> getArrayBoxes() {
return arrayBoxes;
}
public static ArrayList<MousePosition> getMousePosArray() {
return mousePosArray;
}
public static void setMousePosArray(ArrayList<MousePosition> mousePosArray) {
Canvas.mousePosArray = mousePosArray;
}
/**
* Creates a new canvas component with the given size.
* <p>
* Use the API provided by {#link #getContext()} to render graphics on the
* canvas.
* <p>
* The width and height parameters will be used for the canvas' coordinate
* system. They will determine the size of the component in pixels, unless
* you explicitly set the component's size with {#link #setWidth(String)} or
* {#link #setHeight(String)}.
*
* #param width
* the width of the canvas
* #param height
* the height of the canvas
*/
public Canvas(int width, int height) {
context = new CanvasRenderingContext2D(this);
element = getElement();
element.getStyle().set("border", "1px solid");
getElement().setAttribute("width", String.valueOf(width));
getElement().setAttribute("height", String.valueOf(height));
element.addEventListener("mousedown", event -> { // Retrieve Starting Position on MouseDown
Element boundingBoxResult = ElementFactory.createDiv();
element.appendChild(boundingBoxResult);
JsonObject evtData = event.getEventData();
double xBox = evtData.getNumber("event.x");
double yBox = evtData.getNumber("event.y");
boundingBoxResult.setAttribute("data-x", String.format("%f", xBox));
boundingBoxResult.setAttribute("data-y", String.format("%f", yBox));
BoundingBox newBox = new BoundingBox(0, xBox, yBox, 0.0, 0.0);
arrayBoxes.add(newBox);
isDrawing = true;
mouseIsDown=true;
}).addEventData("event.x").addEventData("event.y");
element.addEventListener("mouseup", event -> { // Draw Box on MouseUp
Element boundingBoxResult2 = ElementFactory.createDiv();
element.appendChild(boundingBoxResult2);
JsonObject evtData2 = event.getEventData();
endX = evtData2.getNumber("event.x");
endY = evtData2.getNumber("event.y");
boundingBoxResult2.setAttribute("end-x", String.format("%f", endX));
boundingBoxResult2.setAttribute("end-y", String.format("%f", endY));
double xcoordi = 0;
double ycoordi = 0;
double boxWidth = 0;
double boxHeight = 0;
for (int i = 0; i < arrayBoxes.size(); i++) {
arrayBoxes.get(i).setName(i + 1);
arrayBoxes.get(i).setWidth(endX, arrayBoxes.get(i).xcoordi);
arrayBoxes.get(i).setHeight(endY, arrayBoxes.get(i).ycoordi);
xcoordi = arrayBoxes.get(i).getXcoordi();
ycoordi = arrayBoxes.get(i).getYcoordi();
boxWidth = arrayBoxes.get(i).getWidth();
boxHeight = arrayBoxes.get(i).getHeight();
}
mouseIsDown=false;
context.beginPath();
context.setFillStyle("limegreen");
context.setLineWidth(2);
context.strokeRect(xcoordi, ycoordi, boxWidth, boxHeight);
context.fill();
System.out.println(arrayBoxes.toString());
}).addEventData("event.x").addEventData("event.y");
element.addEventListener("mousemove", event -> { // Retrieve Mouse Position when Moving
JsonObject mousePos = event.getEventData();
double mouseX = mousePos.getNumber("event.x");
double mouseY = mousePos.getNumber("event.y");
MousePosition currentPos = new MousePosition(mouseX, mouseY);
mousePosArray.add(0, currentPos);
setMousePosArray(mousePosArray);
System.out.println(mousePosArray.get(0));
// System.out.println(mousePosArray.get(mousePosArray.size() -1));
}).addEventData("event.x").addEventData("event.y");
}
MainLayout.java:
package com.vaadin.starter.beveragebuddy.backend;
import com.vaadin.flow.component.dependency.HtmlImport;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.html.H2;
import com.vaadin.flow.component.html.Label;
import com.vaadin.flow.component.html.NativeButton;
import com.vaadin.flow.router.Route;
import com.vaadin.starter.beveragebuddy.ui.components.BoundingBox;
import com.vaadin.starter.beveragebuddy.ui.components.Canvas;
import com.vaadin.starter.beveragebuddy.ui.components.CanvasRenderingContext2D;
import com.vaadin.starter.beveragebuddy.ui.components.MousePosition;
import com.vaadin.flow.component.textfield.TextField;
import java.util.ArrayList;
#HtmlImport("frontend://styles/shared-styles.html")
#Route("")
public class MainLayout extends Div {
private CanvasRenderingContext2D ctx;
private Canvas canvas;
ArrayList<MousePosition> mousePosArray = Canvas.getMousePosArray();
ArrayList<BoundingBox> bb = Canvas.getArrayBoxes();
public MainLayout() {
H2 title = new H2("Annotation UI");
title.addClassName("main-layout__title");
canvas = new Canvas(1580, 700);
ctx = canvas.getContext();
Label label = new Label("Coordinates: " + mousePosArray);
canvas.addComponent(label);
add(label);
}
}
CanvasRenderingContext2D.java:
package com.vaadin.starter.beveragebuddy.ui.components;
import java.io.Serializable;
import java.util.ArrayList;
/**
* The context for rendering shapes and images on a canvas.
* <p>
* This is a Java wrapper for the <a href=
* "https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D">same
* client-side API</a>.
*/
public class CanvasRenderingContext2D {
private Canvas canvas;
public static ArrayList<BoundingBox> arrayBoxes = new ArrayList<BoundingBox>();
protected CanvasRenderingContext2D(Canvas canvas) {
this.canvas = canvas;
}
public void setFillStyle(String fillStyle) {
setProperty("fillStyle", fillStyle);
}
public void setStrokeStyle(String strokeStyle) {
setProperty("fillStyle", strokeStyle);
}
public void setLineWidth(double lineWidth) {
setProperty("lineWidth", lineWidth);
}
public void setFont(String font) {
setProperty("font", font);
}
public void arc(double x, double y, double radius, double startAngle,
double endAngle, boolean antiClockwise) {
callJsMethod("arc", x, y, radius, startAngle, endAngle, antiClockwise);
}
public void beginPath() {
callJsMethod("beginPath");
}
public void clearRect(double x, double y, double width, double height) {
callJsMethod("clearRect", x, y, width, height);
Canvas.arrayBoxes.clear();
}
public void closePath() {
callJsMethod("closePath");
}
/**
* Fetches the image from the given location and draws it on the canvas.
* <p>
* <b>NOTE:</b> The drawing will happen asynchronously after the browser has
* received the image.
*
* #param src
* the url of the image to draw
* #param x
* the x-coordinate of the top-left corner of the image
* #param y
* the y-coordinate of the top-left corner of the image
*/
public void drawImage(String src, double x, double y) {
runScript(String.format(
"var zwKqdZ = new Image();" + "zwKqdZ.onload = function () {"
+ "$0.getContext('2d').drawImage(zwKqdZ, %s, %s);};"
+ "zwKqdZ.src='%s';",
x, y, src));
}
/**
* Fetches the image from the given location and draws it on the canvas.
* <p>
* <b>NOTE:</b> The drawing will happen asynchronously after the browser has
* received the image.
*
* #param src
* the url of the image to draw
* #param x
* the x-coordinate of the top-left corner of the image
* #param y
* the y-coordinate of the top-left corner of the image
* #param width
* the width for the image
* #param height
* the height for the image
*/
public void drawImage(String src, double x, double y, double width,
double height) {
runScript(String.format("var zwKqdZ = new Image();"
+ "zwKqdZ.onload = function () {"
+ "$0.getContext('2d').drawImage(zwKqdZ, %s, %s, %s, %s);};"
+ "zwKqdZ.src='%s';", x, y, width, height, src));
}
public void fill() {
callJsMethod("fill");
}
public void fillRect(double x, double y, double width, double height) {
callJsMethod("fillRect", x, y, width, height);
}
public void fillText(String text, double x, double y) {
callJsMethod("fillText", text, x, y);
}
public void lineTo(double x, double y) {
callJsMethod("lineTo", x, y);
}
public void moveTo(double x, double y) {
callJsMethod("moveTo", x, y);
}
public void rect(double x, double y, double width, double height) {
callJsMethod("rect", x, y, width, height);
}
public void restore() {
callJsMethod("restore");
}
public void rotate(double angle) {
callJsMethod("rotate", angle);
}
public void save() {
callJsMethod("save");
}
public void scale(double x, double y) {
callJsMethod("scale", x, y);
}
public void stroke() {
callJsMethod("stroke");
}
public void strokeRect(double x, double y, double width, double height) {
callJsMethod("strokeRect", x, y, width, height);
}
public void strokeText(String text, double x, double y) {
callJsMethod("strokeText", text, x, y);
}
public void translate(double x, double y) {
callJsMethod("translate", x, y);
}
protected void setProperty(String propertyName, Serializable value) {
runScript(String.format("$0.getContext('2d').%s='%s'", propertyName,
value));
}
/**
* Runs the given js so that the execution order works with callJsMethod().
* Any $0 in the script will refer to the canvas element.
*/
private void runScript(String script) {
canvas.getElement().getNode().runWhenAttached(
// This structure is needed to make the execution order work
// with Element.callFunction() which is used in callJsMethod()
ui -> ui.getInternals().getStateTree().beforeClientResponse(
canvas.getElement().getNode(),
context -> ui.getPage().executeJavaScript(script,
canvas.getElement())));
}
protected void callJsMethod(String methodName, Serializable... parameters) {
canvas.getElement().callFunction("getContext('2d')." + methodName,
parameters);
}
}
BoundingBox.java:
package com.vaadin.starter.beveragebuddy.ui.components;
public class BoundingBox {
public double xcoordi = 0;
public double ycoordi = 0;
public double boxWidth = 0;
public double boxHeight = 0;
public int name;
public BoundingBox(int name, double xcoordi, double ycoordi, double boxWidth, double boxHeight) {
this.name = name;
this.xcoordi = xcoordi;
this.ycoordi = ycoordi;
this.boxWidth = boxWidth;
this.boxHeight = boxHeight;
}
public int getName() {
return name;
}
public void setName(int name) {
this.name = name;
}
public double getXcoordi() {
return xcoordi;
}
public void setXcoordi(double xcoordi) {
this.xcoordi = xcoordi;
}
public double getYcoordi() {
return ycoordi;
}
public void setYcoordi(double ycoordi) {
this.ycoordi = ycoordi;
}
public double getWidth() {
return boxWidth;
}
public void setWidth(double endX, double xcoordi) {
boxWidth = endX - xcoordi;
}
public double getHeight() {
return boxHeight;
}
public void setHeight(double endY, double ycoordi) {
boxHeight = endY - ycoordi;
}
#Override
public String toString() {
return "{" +
"Box=" + name +
", X=" + xcoordi +
", Y=" + ycoordi +
", Width=" + boxWidth +
", Height=" + boxHeight +
'}';
}
}
MousePosition.java:
package com.vaadin.starter.beveragebuddy.ui.components;
public class MousePosition {
public double mouseX;
public double mouseY;
public MousePosition(double mouseX, double mouseY) {
this.mouseX = mouseX;
this.mouseY = mouseY;
}
public double getMouseX() {
return mouseX;
}
public void setMouseX(double mouseX) {
this.mouseX = mouseX;
}
public double getMouseY() {
return mouseY;
}
public void setMouseY(double mouseY) {
this.mouseY = mouseY;
}
#Override
public String toString() {
return "MousePosition{" +
"mouseX=" + mouseX +
", mouseY=" + mouseY +
'}';
}
}
Any help is much appreciated, thank you!
Alright, with the updated code it seems your problem is that you never update the label.
You set the label text initially, but it will not be automatically updated when the array changes. What you can do is allow adding a listener to the canvas, and notify it when the value changes.
In the simplest case, a listener can be just a Java Runnable (or Supplier if you want to pass a value). My example returns a Vaadin Registration, which can be used to remove the listener by calling registration.remove().
In Canvas.java
private List<Runnable> mouseMoveListeners = new ArrayList<>(0);
...
public Registration addMouseMoveListener(Runnable listener) {
mouseMoveListeners.add(listener);
return () -> mouseMoveListeners.remove(listener);
}
And in your current mousemove listener
// Your current code in the mousemove listener
MousePosition currentPos = new MousePosition(mouseX, mouseY);
mousePosArray.add(0, currentPos);
setMousePosArray(mousePosArray);
System.out.println(mousePosArray.get(0));
// Add this to run all the listeners that have been added to the canvas
mouseMoveListeners.forEach(Runnable::run);
Then at the end of your MainLayout constructor, something like this
canvas.addMouseMoveListener(() -> label.setValue("Coordinates: " + mousePosArray));
This is untested code, but an approach similar to this should work. The point being that you somehow must notify the MainLayout when the array has changed.
the exception cannot appear, I apparently don't know where is the problem. I want to make own exception for circle radius. For example, if my input is negative value, then the exception need to appear. I made 3 classes. TestCircle.java, Circle.java and IllegalRadiusException.java
TestCircle.java
package circle;
public class TestCircle {
public static void main(String[] args) {
double newRad;
try {
Circle A = new Circle();
A.InputRadius();
A.Calculation();
newRad = A.getRadius();
A.Result();
} catch (IllegalRadiusException e) {
System.out.println(e);
}
}
}
Circle.java
package circle;
import java.util.Scanner;
public class Circle {
Scanner input = new Scanner(System.in);
private double radius;
private double area;
//this is consturctor method
public Circle() throws IllegalRadiusException {
if (radius >= 0) {
this.radius = radius;
this.area = area;
} else {
throw new IllegalRadiusException("Radius Cannot be Negative");
}
}
public void setRadius(double radius) {
this.radius = radius;
}
public double getRadius() {
return radius;
}
public void setArea(double area) {
this.area = area;
}
public double getArea() {
return area;
}
//------------------------------------------------------------//
public void Calculation() {
area = 3.142 * radius * radius;
}
public void InputRadius() {
System.out.print("Radius: ");
radius = input.nextDouble();
}
public void Result() {
System.out.println("");
System.out.println("Radius: " + radius);
System.out.println("Area: " + area);
}
}
IllegalRadiusException.java
package circle;
public class IllegalRadiusException extends Exception {
//Extra kena tambah 'extends Exception'
//WAJIB KENA LETAK untuk CREATE OWN EXCEPTION
public IllegalRadiusException() {
super();
}
public IllegalRadiusException(String message) {
super(message);
}
}
In your code, the constructor would be called only once, at the time of object's instantiation.
You've added the check for exception, only in this constructor.
For your example to work as needed, you need to throw exceptions from your InpurRadius method too, if the user enters an invalid value.
Change your method to this.
public void InputRadius() throws IllegalRadiusException {
System.out.print("Radius: ");
double entered_radius = input.nextDouble();
if (entered_radius >= 0) {
this.radius = entered_radius;
this.area = area;
} else {
throw new IllegalRadiusException("Radius Cannot be Negative");
}
}
You do not pass value to radius in constructor so it is not initialized (0). So the if statement will always pass since 0 == 0 :). Pass
public Circle(double radius) // something like this
and assign it inside constructor to radius
I have an interface that has one ordinary method and one generic method. I have implemented ordinary method for two different classes, but do not now how to do that with generic method. Here is my code:
Sphere.java:
public class Sphere implements GeometricShape<Sphere> {
private double radius;
public Sphere (double radius) {
this.radius = radius;
}
public double volume() {
return (4.0 / 3.0) * Math.PI * radius * radius * radius;
}
public void describe() {
System.out.println("Sphere[radius=" + radius + "]");
}
#Override
public Sphere supersize()
{
this.radius*=2;
return new Sphere(radius);
}
}
Rectangle.java
public class Rectangle implements TwoDShape {
private double width, height;
public Rectangle (double width, double height) {
this.width = width;
this.height = height;
}
public double area()
{
return width * height;
}
public double perimeter()
{
return 2.0 * (width + height);
}
public void describe()
{
System.out.println("Rectangle[width=" + width + ", height=" + height + "]");
}
#Override
public Rectangle supersize()
{
this.width*=2;
this.height*=2;
return new Rectangle(width, height);
}
}
TwoDShape.java:
public interface TwoDShape extends GeometricShape
{
public double area();
}
ThreeDShape.java:
public interface ThreeDShape extends GeometricShape<ThreeDShape>
{
public double volume();
}
GeometricShape.java:
public interface GeometricShape<T extends GeometricShape<T>>
{
public void describe();
public T supersize();
}
and finally main class ArrayListExample.java:
import java.util.ArrayList;
public class ArrayListExample {
public static void describe_all( ArrayList<? extends GeometricShape> shapes )
{
for(int i=0;i<shapes.size();i++)
{
shapes.get(i).describe();
}
System.out.println("Total number of shapes:"+ shapes.size());
}
public static void main(String[] args) {
System.out.println("The describe() method:");
System.out.println();
System.out.println("Example rectangles");
ArrayList<Rectangle> rects = new ArrayList<Rectangle>();
rects.add(new Rectangle(2.0, 3.0));
rects.add(new Rectangle(5.0, 5.0));
describe_all(rects);
System.out.println();
ArrayList<Sphere> spheres = new ArrayList<Sphere>();
spheres.add(new Sphere(10.0));
spheres.add(new Sphere(50.0));
spheres.add(new Sphere(0.0));
System.out.println("Example spheres");
describe_all(spheres);
System.out.println();
System.out.println("The supersize() method:");
System.out.println();
ArrayList<Rectangle> double_rects = supersize_list(rects);
describe_all(double_rects);
System.out.println();
ArrayList<Sphere> double_spheres = supersize_list(spheres);
describe_all(double_spheres);
}
}
How can I implement supersize_list method that it takes supersize method from both rectangle and sphere and outputs like
Rectangle[width=4.0, height=6.0]
Rectangle[width=10.0, height=10.0]
Total number of shapes: 2
Sphere[radius=20.0]
Sphere[radius=100.0]
Sphere[radius=0.0]
Total number of shapes: 3
Could you help me with this, please? I greatly appreciate your help!
The class hierarchy looks inconsistent. For example, you have ThreeDShape extends GeometricShape<ThreeDShape> and TwoDShape extends GeometricShape at the same time, for no obvious reason. It's not fun to write a generic method for these types.
Here's a less-confusing version. (I hope) Note: I choose not to change the size of the shape itself in supersize method, instead let it return a bigger shape while keeping the original unchanged.
1. GeometricShape
/**
* A geometric shape interface. You can do two things with it.
* 1. Ask it to describe itself (to stdout);
* 2. Ask it to return a bigger version of itself (double the size).
*/
public interface GeometricShape<T extends GeometricShape<T>> {
/**
* Print a description to STDOUT
*/
void describe();
/**
* Returns a bigger shape.
* #return Something that's a GeometricShape
*/
T supersize();
}
2. Shape2D and Rectangle
/**
* A 2-dimensional shape.
* It has area.
* Its supersize() method should return a Shape2D instance.
*/
public interface Shape2D<T extends Shape2D<T>> extends GeometricShape<T> {
double area();
}
/**
* A rectangle.
*/
public final class Rectangle implements Shape2D<Rectangle> {
private final double width;
private final double height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
#Override
public String toString() {
return "Rectangle{" +
"width=" + width +
", height=" + height +
'}';
}
#Override
public void describe() {
System.out.println(this);
}
#Override
public Rectangle supersize() {
return new Rectangle(width*2, height*2);
}
#Override
public double area() {
return width * height;
}
}
3. Shape3D and Sphere
/**
* A 3-dimensional shape.
* It has volume.
* Its supersize() method should return a Shape3D instance.
*/
public interface Shape3D<T extends Shape3D<T>> extends GeometricShape<T> {
double volume();
}
/**
* A sphere
*/
public final class Sphere implements Shape3D<Sphere> {
private final double radius;
public Sphere(double radius) {
this.radius = radius;
}
#Override
public String toString() {
return "Sphere{" +
"radius=" + radius +
'}';
}
#Override
public void describe() {
System.out.println(this);
}
#Override
public Sphere supersize() {
return new Sphere(radius*2);
}
#Override
public double volume() {
return 4*Math.PI*Math.pow(radius, 3)/3;
}
}
Now the generic method that transforms a list
public static <T extends GeometricShape<T>>
List<T> supersize_list(List<T> list) {
List<T> result = new ArrayList<>();
for (T shape : list) {
result.add(shape.supersize());
}
return result;
}
You do not need to return a new Object. For Rectangle for example
#Override
public void supersize()
{
this.width*=2;
this.height*=2;
}
is sufficient
What's up guys,
I keep receiving this error, cannot find symbol Circle aCircle = new Circle(); , when trying to compile the driver code my professor gave us. I'm wondering if it is because I haven't added it to my circle.java method. This is the circle driver.
package lab7;
public class CircleDriver {
public static void main(String[] args) {
Circle aCircle = new Circle();
aCircle.setColor("green");
aCircle.setRadius(10);
aCircle.display();
Double circleArea = aCircle.computeArea();
Double circumference = aCircle.computeCircumference();
System.out.println("circle area: " + circleArea);
System.out.println("circle circumference: " + circumference);
System.out.println();
}
}
This is my circle method.`
public class Circle {
private String color;
private int radius;
public Circle(String color, int radius) {
this.color = color;
this.radius = radius;
}
public Circle() {
Circle aCircle = new Circle();
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getRadius() {
return radius;
}
public void setRadius(int radius) {
this.radius = radius;
}
public void display() {
System.out.println("I am a circle");
System.out.println("My color is " + color);
System.out.println("My radius is " + radius);
}
public double computeArea() {
return (Math.PI * Math.pow(radius, 2));
}
public double computeCircumference() {
return (2 * Math.PI * radius);
}
}
You need to call a super() constructor when calling a circle. When you call
Circle aCircle = new Circle();
You are trying to initialize a circle in the local aspect. I think you are trying to inherit the Circle class that is already in java.
Leaving the circle constructor as
public Circle() {}
Should theoretically work to instantiate your class.
Use this code. You have mistake in constructor. I hope it will solve your issue.
In Circle.java, instead of
public Circle() {
Circle aCircle = new Circle();
}
Use this code
public Circle() {
super();
// TODO Auto-generated constructor stub
}
CircleDriver.java
public class CircleDriver {
public static void main(String[] args) {
Circle aCircle = new Circle();
aCircle.setColor("green");
aCircle.setRadius(10);
aCircle.display();
Double circleArea = aCircle.computeArea();
Double circumference = aCircle.computeCircumference();
System.out.println("circle area: " + circleArea);
System.out.println("circle circumference: " + circumference);
System.out.println();
}
}
Circle.java
public class Circle {
private String color;
private int radius;
public Circle() {
super();
// TODO Auto-generated constructor stub
}
public Circle(String color, int radius) {
super();
this.color = color;
this.radius = radius;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getRadius() {
return radius;
}
public void setRadius(int radius) {
this.radius = radius;
}
public void display() {
System.out.println("I am a circle");
System.out.println("My color is " + color);
System.out.println("My radius is " + radius);
}
public double computeArea() {
return (Math.PI * Math.pow(radius, 2));
}
public double computeCircumference() {
return (2 * Math.PI * radius);
}
}
Output:
I am a circle
My color is green
My radius is 10
circle area: 314.1592653589793
circle circumference: 62.83185307179586
I need to take information from a file and create them into objects and put them into an array so I can compare the areas of the objects and list in the array which object has the largest area and its location in the array.
I'm confused on how I take the information from the file and create each one into a object (circle or rectangle) and then assign that object into an array after it has been created. I think my other classes are fine, I'm just stuck on finishing the driver.
Normally, I would do something like Circle c1 = new Circle(); to create a new object, but how do I do that from a file with predefined information and assign it to an array?
Data:
“CIRCLE”, 1, “blue”, true
“RECTANGLE”, 1, 2, “blue”, true
“RECTANGLE”, 10, 2, “red”, true
“CIRCLE”, 2, “green”
“RECTANGLE”
“CIRCLE”
Driver:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;
public class Driver {
public static void main(String[] args) throws FileNotFoundException {
Scanner input = new Scanner(new File("C:/Users/Charles/Desktop/GeometricObjectsData.txt"));
ArrayList<GeometricObject> list = new ArrayList<GeometricObject>();
while (input.hasNext()) {
String line = input.nextLine();
System.out.println(line);
}
}
}
GeometricObject:
public abstract class GeometricObject {
//class variables
private String color;
private boolean filled;
//constructors
public GeometricObject() {
super();
color = "white";
filled = false;
}
public GeometricObject(String color, boolean filled) {
super();
this.color = color;
this.filled = filled;
}
//mutators
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public boolean isFilled() {
return filled;
}
public void setFilled(boolean filled) {
this.filled = filled;
}
//user-defined methods
public abstract double getArea();
public abstract double getPerimeter();
#Override
public String toString() {
return super.toString() + " \tColor=" + this.getColor() + " \tFilled=" + this.isFilled();
}
}
Circle:
public class Circle extends GeometricObject {
//class variables
private double radius;
//constructors
public Circle() {
super();
radius = 1;
}
public Circle(double radius, String color, boolean filled) {
super(color, filled);
this.radius = radius;
}
//mutators
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
//user-defined methods
#Override
public double getArea() {
//area of a circle
return (radius * radius * Math.PI);
}
#Override
public double getPerimeter() {
//perimeter of a circle
return (2 * radius * Math.PI);
}
#Override
public String toString() {
return super.toString() + "\nCircle: Radius=" + this.getRadius();
}
}
Rectangle:
public class Rectangle extends GeometricObject {
//class variables
private double height;
private double width;
//constructors
public Rectangle() {
super();
height = 1;
width = 1;
}
public Rectangle(double height, double width, String color, boolean filled) {
super(color,filled);
this.height = height;
this.width = width;
}
//mutators
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public double getWidth() {
return width;
}
public void setWidth(double width) {
this.width = width;
}
//user-defined methods
#Override
public String toString() {
return super.toString() + "\nRectangle: Height=" + this.height + "\tWidth=" + this.width;
}
#Override
public double getArea() {
return (height * width);
}
#Override
public double getPerimeter() {
return (2 * height + 2 * width);
}
}
In your text file, you have special quotes around your shape items. This will make your life more difficult, so you should change that, if possible
Example of how to make objects (from your main method):
while (input.hasNext()) {
String line = input.nextLine();
System.out.println(line);
String[] parts = line.split(",");
if (parts[0].indexOf("Circle") != -1) {
Circle c = new Circle();
// ... parse the rest of the attributes to set up your circle
} else if ... // fill in the other shape cases
}