# Thread: Clicking on an oval in JPanel

1. Member
Join Date
Nov 2009
Posts
26
Rep Power
0

## Clicking on an oval in JPanel

I am making a paint applet, which draws shapes on a 'canvas' by storing shapes into an arraylist (using the Graphics class).

I need to be able te erase complete shapes by clicking them with the eraser tool.

I managed to make this work for rectangles, filled rectangles and lines. I am not managing to do this with ovals. This because the radius is not equal along the entire circumference. How can I calculate whether a user clicked withing the oval, or on the (variable) stroke of an open oval?

For an example this is what the code for the filled rectangle:
Java Code:
// p1 and p2 are startpoint and endpoint (class vars).
// p is the point clicked by the user
// iMargin is the amount of pixel the user is allowed to miss the shape by (class var).

private boolean fillRectRaak(Point p)
{
if(p.x <= this.p2.x + iStroke + iMargin &&
p.x >= this.p1.x - iStroke - iMargin)
{
if(p.y <= this.p2.y + iStroke + iMargin &&
p.y >= this.p1.y - iStroke - iMargin)
{
return true;
}
}
return false;
}

2. Member
Join Date
Nov 2009
Posts
26
Rep Power
0
I am not using the java.awt.geom. I am using the Graphics class. When trying to use a Ellipse2D.Double it tells me that the method Double(double, double, double, double) is undefined for the type Ellipse2D.

Is there a way to continue using the Graphics class or can someone help me implement the Ellipse2D class?

3. If you can, you should post the code that doesn't work, that's throwing the errors, and we can then help point out what's wrong. Also, if you can post a small compilable (or attempt at a compilable) program that we can compile, test and possibly run, then we could likely get you focused help a lot quicker. Much luck!

4. Member
Join Date
Nov 2009
Posts
26
Rep Power
0
Java Code:
switch (iToolID)
{
case PEN_TOOL: 										; break;
case LINE_TOOL: 		g.drawLine(p1.x, p1.y, p2.x, p2.y)	; break;
case RECT_TOOL: 		g.drawRect(xy.x, xy.y, wh.width, wh.height)	; break;
case FILL_RECT_TOOL: 	g.fillRect(xy.x, xy.y, wh.width, wh.height)	; break;
//case OVAL_TOOL:  		g.drawOval(xy.x, xy.y, wh.width, wh.height)	; break;
case OVAL_TOOL:  		Ellipse2D.Double(2.0,2.0,2.0,2.0)	; break;
case FILL_OVAL_TOOL:  	g.fillOval(xy.x, xy.y, wh.width, wh.height)	; break;
case TEXT_TOOL: 		g.drawString(s, xy.x, xy.y)		; break;
}
That is the part that doesn't work.

A link to my complete project till now:

The class that creates an object of a shape is "SchetsElementen". Most of the variable names are in Dutch, I can translate any words that give problems.

5. You need to add a new Ellipse2D into a List<Shape> and then iterate through this list in the paintComponent method drawing each Shape as you go. For instance, here's a simple example that draws an Ellipse2D with the left mouse button and erases the most recent shape with the right button:

Java Code:
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.List;

import javax.swing.*;

@SuppressWarnings("serial")
public class ShapeEg extends JPanel {
private List<Shape> shapeList = new ArrayList<Shape>();
private Shape tempShape = null;

public ShapeEg() {
setBackground(Color.white);
setPreferredSize(new Dimension(500, 500));
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(Color.lightGray);
if (tempShape != null) {
g2.draw(tempShape);
}
g2.setColor(Color.blue);
g2.setStroke(new BasicStroke(4));
for (Shape s : shapeList) {
g2.draw(s);
}
}

Point start = null;
Point end = null;

@Override
public void mousePressed(MouseEvent me) {
if (me.getButton() == MouseEvent.BUTTON1) {
start = me.getPoint();
}

// else if right mouse button pressed and there are shapes
// held in our shape list -- delete a shape if the button presses
// on top of one.
else if (me.getButton() == MouseEvent.BUTTON3 && shapeList.size() > 0) {
// iterate backwards to delete most recent shape
for (int i = shapeList.size() - 1; i >= 0; i--) {
if (shapeList.get(i).contains(me.getPoint())) {
shapeList.remove(i);
repaint();
break;
}
}
}
}

@Override
public void mouseDragged(MouseEvent me) {
if (start == null) {
return;
}
end = me.getPoint();
int x = Math.min(start.x, end.x);
int y = Math.min(start.y, end.y);
int w = Math.abs(start.x - end.x);
int h = Math.abs(start.y - end.y);
tempShape = new Ellipse2D.Double(x, y, w, h);
repaint();
}

@Override
public void mouseReleased(MouseEvent me) {
if (me.getButton() == MouseEvent.BUTTON1) {
end = me.getPoint();
int x = Math.min(start.x, end.x);
int y = Math.min(start.y, end.y);
int w = Math.abs(start.x - end.x);
int h = Math.abs(start.y - end.y);
start = null;
end = null;
tempShape = null;
repaint();
}
}

}

private static void createAndShowGUI() {
JFrame frame = new JFrame("ShapeEg Application");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}

public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});

}
}
Last edited by Fubarable; 03-17-2010 at 12:26 AM.

6. Member
Join Date
Nov 2009
Posts
26
Rep Power
0
A friend helped me out. I used the following method:

Java Code:
private boolean fillOvalRaak(Point p) {

Dimension wh = puntAfstand(p1, p2);
int x1=(p2.x+p1.x)/2;
int y1=(p2.y+p1.y)/2;
int xx=2*(p.x-x1)/wh.width;
int yy=2*(p.y-y1)/wh.height;
if (xx*xx+yy*yy<1)
{
return true;
}

return false;
}

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•