From b6b5f78247775eaa7911ab35ef73101e2e7bba38 Mon Sep 17 00:00:00 2001
From: jgsteplujr Circle
is a {@link Geometry}
+ * object that represents a circle on a plane
+ * with the center at one point through another,
+ * with the distance between these points the radius
+ * of the circle. The position of a circle must be
+ * dynamically computed, meaning the two {@link Point}
+ * that defines the object must also have computed
+ * or fixed values.
+ */
+
+
+public class Circle
+ extends Geometry {
+
+ /**
+ * The width of the circle's stroke when it's hovered
+ */
+
+ private static final int THICK_STROKE_WIDTH;
+
+
+ static {
+ THICK_STROKE_WIDTH = 4;
+ }
+
+ /**
+ * The two points that defines the circle
+ */
+
+ private Point center, throughPoint;
+
+
+ /**
+ *
+ */
+
+ Circle(Point center, Point throughPoint) {
+ this.center = center;
+ this.throughPoint = throughPoint;
+ }
+
+
+ private double radius(ViewPort viewPort) {
+ return ViewPort.mag(viewPort.computeX(throughPoint.getX()) - viewPort.computeX(center.getX()),
+ viewPort.computeY(throughPoint.getY()) - viewPort.computeY(center.getY()));
+ }
+
+ /**
+ * Paints the geometry entity
+ *
+ * @param g the graphic context to be drawn on
+ * @param viewPort the viewport context to determine position
+ */
+
+ @Override
+ public void paint(Graphics g, ViewPort viewPort) {
+
+ if (!isHidden()) {
+ int cx, cy, r;
+
+ cx = viewPort.computeX(center.getX());
+ cy = viewPort.computeY(center.getY());
+ r = (int) radius(viewPort);
+
+ g.setColor(getColor());
+ g.drawOval(cx - r, cy - r, r * 2, r * 2);
+
+ }
+ }
+
+
+ /**
+ * Determines if a mouse position is hovering over the geometry
+ *
+ * @param mouseX the X position of the mouse
+ * @param mouseY the Y position of the mouse
+ * @param viewPort the viewport context to determine position
+ * @return if the mouse is over geometry
+ */
+
+ @Override
+ public boolean isMouseOver(int mouseX, int mouseY, ViewPort viewPort) {
+ return Math.abs(radius(viewPort) - ViewPort.mag(mouseX - viewPort.computeX(center.getX()),
+ mouseY - viewPort.computeY(center.getY()))) < THICK_STROKE_WIDTH;
+ }
+
+}
diff --git a/src/ca/wtcs/ics3u/gc/Geometry.java b/src/ca/wtcs/ics3u/gc/Geometry.java
index 2d50718..a90e0ea 100644
--- a/src/ca/wtcs/ics3u/gc/Geometry.java
+++ b/src/ca/wtcs/ics3u/gc/Geometry.java
@@ -19,11 +19,31 @@
* also be able to add itself into a {@link GraphView}
*
* @author Yu Liu
- * @see Geometry1D
*/
-public interface Geometry {
+abstract class Geometry {
+
+
+ /**
+ * The selected state of the geometry
+ */
+
+ private boolean selected;
+
+
+ /**
+ * The hidden state of the geometry
+ */
+
+ private boolean hidden;
+
+
+ /**
+ * The hovered state of the geometry
+ */
+
+ private boolean hovered;
/**
@@ -33,7 +53,7 @@ public interface Geometry {
* @param viewPort the viewport context to determine position
*/
- void paint(Graphics g, ViewPort viewPort);
+ abstract void paint(Graphics g, ViewPort viewPort);
/**
@@ -45,7 +65,7 @@ public interface Geometry {
* @return if the mouse is over geometry
*/
- boolean isMouseOver(int mouseX, int mouseY, ViewPort viewPort);
+ abstract boolean isMouseOver(int mouseX, int mouseY, ViewPort viewPort);
/**
@@ -54,7 +74,9 @@ public interface Geometry {
* @return if the geometry is selected
*/
- boolean getSelected();
+ boolean isSelected() {
+ return selected;
+ }
/**
* Sets the selected state of geometry
@@ -62,7 +84,9 @@ public interface Geometry {
* @param selected the selected state of geometry
*/
- void setSelected(boolean selected);
+ void setSelected(boolean selected) {
+ this.selected = selected;
+ }
/**
* Determines if the geometry is hidden
@@ -70,16 +94,29 @@ public interface Geometry {
* @return if the geometry is hidden
*/
- boolean getHidden();
+ boolean isHidden() {
+ return hidden;
+ }
/**
* Sets the hidden state of geometry
*
- * @param hidden the hidden state of geometry
+ * @param hidden the hidden state of the geometry
*/
- void setHidden(boolean hidden);
+ void setHidden(boolean hidden) {
+ this.hidden = hidden;
+ }
+
+ /**
+ * Determines if the geometry is on mouseover
+ *
+ * @return if the geometry is hidden
+ */
+ boolean isHovered() {
+ return hovered;
+ }
/**
* Sets the hovered state of geometry
@@ -87,6 +124,19 @@ public interface Geometry {
* @param hovered the hovered state of geometry
*/
- void setHovered(boolean hovered);
+ void setHovered(boolean hovered) {
+ this.hovered = hovered;
+ }
+
+ /**
+ * Determines the color of the geometric object according to its state.
+ * Overriding paint method should call this method to determine color
+ *
+ * @return The unified colour of the object
+ */
+
+ Color getColor() {
+ return hovered || selected ? Color.BLUE : Color.BLACK;
+ }
}
\ No newline at end of file
diff --git a/src/ca/wtcs/ics3u/gc/Geometry1D.java b/src/ca/wtcs/ics3u/gc/Geometry1D.java
deleted file mode 100644
index 69127f1..0000000
--- a/src/ca/wtcs/ics3u/gc/Geometry1D.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package ca.wtcs.ics3u.gc;
-
-
-/*
- * Created by Yu Liu on 2017-06-06
- * ICS3U - Culminating Project - A compass-and-straightedge construction tool
- *
- * More information at https://github.com/yuliu2016/GeometryConstructor
- */
-
-
-/**
- * Geometry1D
is a currently empty interface that represent
- * a 1 dimensional object. Useful later when a geometry can only be a point
- *
- * @author Yu Liu
- * @see Geometry
- */
-
-
-interface Geometry1D
- extends Geometry {
-
-
-}
diff --git a/src/ca/wtcs/ics3u/gc/GeometryConstructor.java b/src/ca/wtcs/ics3u/gc/GeometryConstructor.java
index f92ba2b..b4d8a3c 100644
--- a/src/ca/wtcs/ics3u/gc/GeometryConstructor.java
+++ b/src/ca/wtcs/ics3u/gc/GeometryConstructor.java
@@ -41,7 +41,7 @@ public class GeometryConstructor {
static {
- DEFAULT_DIMENSION = new Dimension(600, 450);
+ DEFAULT_DIMENSION = new Dimension(800, 600);
TITLE = "Geometry Constructor";
}
@@ -54,33 +54,33 @@ public class GeometryConstructor {
public static void main(String[] args) {
- Frame application = new Frame(TITLE);
+ Frame app = new Frame(TITLE);
GraphView graphView = new GraphView();
- application.setSize(DEFAULT_DIMENSION);
- application.setLayout(null);
- application.setResizable(true);
+ app.setSize(DEFAULT_DIMENSION);
+ app.setLayout(null);
+ app.setResizable(true);
- application.add(graphView);
+ app.add(graphView);
- application.addWindowListener(new WindowAdapter() {
+ app.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
- application.dispose();
+ app.dispose();
System.exit(0);
}
});
- application.addComponentListener(new ComponentAdapter() {
+ app.addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
- Dimension newSize = application.getSize();
+ Dimension newSize = app.getSize();
graphView.setSize(newSize.width, newSize.height);
}
});
- application.setMinimumSize(GraphView.MINIMUM_DIMENSION);
- application.setVisible(true);
+ app.setMinimumSize(GraphView.MINIMUM_DIMENSION);
+ app.setVisible(true);
}
}
diff --git a/src/ca/wtcs/ics3u/gc/GraphView.java b/src/ca/wtcs/ics3u/gc/GraphView.java
index 66ee77f..69aa2e2 100644
--- a/src/ca/wtcs/ics3u/gc/GraphView.java
+++ b/src/ca/wtcs/ics3u/gc/GraphView.java
@@ -25,13 +25,12 @@
* The component can be resized and would update accordingly,
* including a new default scale. See {@link ViewPort} for more details.
* This component receives events from its window, component, keyboard, and mouse;
- * it is not tested how it will respond to these events when it is used in another container.
*
* This class keeps track of objects relating to the viewport,
* values relating to the mouse and key events, and a list of objects that implement
* {@link Geometry} to be created, displayed, and modified by the user through
- * interations with this component
+ * interactions with this component
* The class is declared final
because much of the code in this design
* are not reusable for extensions
*
@@ -135,7 +147,6 @@ public final class GraphView
GraphView() {
-
addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
@@ -154,11 +165,20 @@ public void componentResized(ComponentEvent e) {
setMinimumSize(MINIMUM_DIMENSION);
- entities.clear();
- entities.add(new Point(0.5, 0));
- entities.add(new Point(-0.5, 0));
+ Point p1 = new Point(0.5, 0);
+ Point p2 = new Point(-0.5, 0);
+
+ points.add(p1);
+ points.add(p2);
+
+ shapes.add(new Circle(p1, p2));
+ shapes.add(new Circle(p2, p1));
+
+ selected = 0;
+ hidden = 0;
Timer timer = new Timer(true);
+
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
@@ -167,7 +187,8 @@ public void run() {
}
}, 0, FRAME_RATE);
- setVisible(true);
+ requestFocus();
+ requestFocusInWindow();
}
@@ -183,6 +204,8 @@ private String getToolLabel() {
switch (tool) {
case 1:
return "Point Tool";
+ case 2:
+ return "Circle Tool";
default:
return "Selection Tool";
}
@@ -210,16 +233,6 @@ private String getViewLabel() {
*/
private String getNumericalLabel() {
-
- int selected = 0, hidden = 0;
-
- for (Geometry entity : entities) {
- if (entity.getSelected())
- selected++;
- if (entity.getHidden())
- hidden++;
- }
-
return selected + " Selected, " + hidden + " Hidden";
}
@@ -230,12 +243,16 @@ private String getNumericalLabel() {
* @return if the mouse is hovering on any entities
*/
- private boolean mouseIsOverEntities() {
+ private boolean anyEntityHovered() {
- for (Geometry entity : entities)
+ for (Geometry entity : shapes)
if (entity.isMouseOver(mouseX, mouseY, viewPort))
return true;
+ for (Point point : points)
+ if (point.isMouseOver(mouseX, mouseY, viewPort))
+ return true;
+
return false;
}
@@ -246,10 +263,14 @@ private boolean mouseIsOverEntities() {
* @return if any entities are selected
*/
- private boolean hasSelection() {
+ private boolean anyEntitySelected() {
- for (Geometry entity : entities)
- if (entity.getSelected())
+ for (Geometry entity : shapes)
+ if (entity.isSelected())
+ return true;
+
+ for (Point point : points)
+ if (point.isSelected())
return true;
return false;
@@ -267,11 +288,28 @@ private boolean hasSelection() {
private void selectEntities() {
- boolean over = mouseIsOverEntities();
+ boolean over = anyEntityHovered();
+ selected = 0;
+
+ for (Point point : points) {
+ point.setSelected(over && point.isSelected() ^ point.isMouseOver(mouseX, mouseY, viewPort));
+ selected += point.isSelected() ? 1 : 0;
+ }
+
+ for (Geometry entity : shapes) {
+ entity.setSelected(over && entity.isSelected() ^ entity.isMouseOver(mouseX, mouseY, viewPort));
+ selected += entity.isSelected() ? 1 : 0;
+ }
+
+
+ }
- for (Geometry entity : entities)
- entity.setSelected(over && entity.getSelected() ^ entity.isMouseOver(mouseX, mouseY, viewPort));
+ /**
+ * Adds a fixed point onto the graph
+ */
+ private void addFixedPoint(double x, double y) {
+ points.add(new Point(x, y));
}
@@ -281,26 +319,26 @@ private void selectEntities() {
private void insertPoint() {
- if (!mouseIsOverEntities())
- entities.add(new Point(viewPort.computeFromX(mouseX), viewPort.computeFromY(mouseY)));
+ if (!anyEntityHovered())
+ addFixedPoint(viewPort.computeFromX(mouseX), viewPort.computeFromY(mouseY));
}
/**
* Creates a list that include all item selected to be removed,
- * then subtract it from the {@link GraphView#entities} list
+ * then subtract it from the {@link GraphView#shapes} list
*/
private void deleteSelected() {
LinkedList