Code example for transformation by mouse dragging

W

Wolfgang

I'm looking for a simple code example that uses the mouse to grab a
hold of geometric shape, say a circle (but can be something else), and
while dragging the mouse rotates and transforms the shape to reflect
it's new rotational position (in the case of a circle this would be
some ellipse) .

Can someone point me to a code example for this?

Thanks.

Wolfgang
 
A

Andrew Hobbs

Wolfgang said:
I'm looking for a simple code example that uses the mouse to grab a
hold of geometric shape, say a circle (but can be something else), and
while dragging the mouse rotates and transforms the shape to reflect
it's new rotational position (in the case of a circle this would be
some ellipse) .

Can someone point me to a code example for this?

Thanks.

Wolfgang

Shapes as you are talking about have no reality apart from being drawn on a
surface. If you want to do something like this then you need to give such
shapes some sort of reality. If you are talking about a single circle etc,
then it is easy to do it within the panel itself.

The following code is one way to start a circle on a panel and move it
around and get it drawn as an ellipse etc. It isn't what you asked for, but
it indicates how to get it drawn etc.

class JPanelToDrawOn extends JPanel {
int x1 = 0;
int y1 = 0;
int x2 = 0;
int y2 = 0;
boolean drawing = false;

public JPanelToDrawOn() {
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
panelMousePressed(e);
}
public void mouseReleased(MouseEvent e) {
panelMouseReleased(e);
}
});
addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
panelMouseDragged(e);
}
});
}
public void panelMousePressed(MouseEvent e) {
x1 = e.getX();
y1 = e.getY();
drawing = true;
}

public void panelMouseReleased(MouseEvent e) {
x2 = e.getX() - x1;
y2 = e.getY() - y1;
drawing = false;
repaint();
}
public void panelMouseDragged(MouseEvent e) {
if(drawing) {
x2 = e.getX() - x1;
y2 = e.getY() - y1;
repaint();
}
}

public void paintComponent(Graphics g) {
if(drawing) {
g.setColor(Color.blue);
g.fillRect(0, 0, 300, 300);
g.setColor(Color.red);
g.drawArc(x1, y1, x2, y2, 0, 360);
}
}


If you have multiple preexisting circles that you might want to drag around
as they are or reshape etc. then it would be much easier if you make each an
actual object. I would suggest writing classes for each type of object
which encapsulate the behaviour. Each would have their own specifications,
their own drawing methods (ie draw(Graphics g) ) and a method which can
accept the x and y positions of a mouse click for example and indicate
whether the mouse click was on itself.

Then the panel paintComponent() method would simply iterate through the
array of objects calling their draw(Graphics g) method.

Since you want only one of your circles to respond (presumably) to a mouse
dragged event then I would suggest that you have a class variable called
selectedObject and when one indicates that it is the correct object you set
selectedObject to that circle. Then you write all the mouse events to be
passed into the selectedObject. If you have a number of different types of
object (eg circle, square, triagle etc) then you might even want to get them
to implement an interface (eg DrawableObject) in which you specify each of
the methods you expect these objects to have.

NOTE the following is simply an outline to give you some ideas.


class JPanelToDrawOn extends JPanel {
ArrayList list = new ArrayList();
DrawableObject selectedObject = null;

public void addDrawableObject(DrawableObject g) {
list.add(g);
}


public void panelMousePressed(MouseEvent e) {
// iterate through list to find one that responds.
for( etc etc etc)
if(DrawableObject.isSelected(e.getX(), e.getY())
// if one does then make it the selectedObject;
selectedObject = list.get(n);
// Then tell the selectedObject that it was selected;
selectedObject.mousePressed(e);
}
public void panelMouseDragged(MouseEvent e) {
selectedObject.mouseDragged(e);
}
public void panelMouseReleased(MouseEvent e) {
selectedObject.mouseReleased(e);
selectedObject = null;
}
public void paintComponent(Graphics g) {
// iterate (with a for loop) through the list calling each draw
method in turn.
}


Then each drawableObject needs to implement an interface something like

public interface DrawableObject{

public boolean isSelected(int x, int y);

public void mouseDragged(int x, int y);

public void mouseReleased( int x, int y);

public void draw(Graphics g);
}

Cheers

Andrew


--
********************************************************
Andrew Hobbs PhD

MetaSense Pty Ltd - www.metasense.com.au
12 Ashover Grove
Carine W.A.
Australia 6020

61 8 9246 2026
metasens AntiSpam @iinet dot net dot au


*********************************************************
 
S

S Manohar

I'm looking for a simple code example that uses the mouse to grab a
hold of geometric shape, say a circle (but can be something else), and
while dragging the mouse rotates and transforms the shape to reflect
it's new rotational position (in the case of a circle this would be
some ellipse) .

Can someone point me to a code example for this?

Thanks.

Wolfgang

Hi, I wrote some code for this a while back, using the Java
2D API. Here's a snipped version (might need a bit of tinkering
to get it to work... but the framework is there) It's
missing the code that checks it's positioned ok within its
parent container.


public class TransformableComponent
extends JComponent
implements MouseListener, MouseMotionListener {

/** Transformed shape, as drawn */
private Shape drawnshape;

/** Setup mouse handler */
public TransformableComponent() {
setShape(new Ellipse2D.Double(10,10,10,10));
addMouseMotionListener(this);
addMouseListener(this);
}

/** Last mouse pos */
private Point mouse;

/** Change the last mouse pos */
public void mousePressed(MouseEvent e){ mouse=e.getPoint(); }

/** Calls drag with the movement vector */
public void mouseDragged(MouseEvent e){
Point p=e.getPoint();
drag(p.x-mouse.x, p.y-mouse.y);
mouse=p;
}

// Fill in other blank Mouse methods here

/** Set this variable to rotate or translate the object */
public boolean rotating=true;

/** Centre of shape is centre of rotation */
protected Point getMidpoint(Shape s){
return new Point(s.getBounds().width/2, s.getBounds().height/2);
}

/**
* Set the shape, adjust the position and size of the JComponent
* such that the centre is unaltered.
*/
public void setShape(Shape s){
drawnshape=s;
Dimension sz=drawnshape.getBounds().getSize();
Dimension osz=getBounds().getSize();
Point oloc = getLocation();
setLocation(oloc.x + (osz.width-sz.width)/2,
oloc.y + (osz.height-sz.height)/2);
setSize(sz.width+1, sz.height+1);
}

/** Return the current Shape */
public Shape getShape(){return drawnshape;}

/** Customise this to change appearance of shape */
public void paintComponent(Graphics g){ ((Graphics2D)g).fill(drawnshape); }

/**
* Do the transformation: Rotation is done by translating to the
* centre, rotating by the x-offset, then untranslating the
* current shape. Change this to customise the way mouse movement
* causes rotation.
*/
protected void drag(int dx, int dy){
if(rotating){
try{
if(dx>5)dx=5;if(dx<-5)dx=-5; // prevent megaspins!
Point c = getMidpoint(shape); // centre of rotation
AffineTransform tra = AffineTransform.getTranslateInstance(c.x,c.y),
rot = AffineTransform.getRotateInstance(dx*0.05),
ttr = (AffineTransform)tra.clone();
ttr.concatenate(rot); ttr.concatenate(tra.createInverse());
setShape( ttr.createTransformedShape(shape) );
}catch(NoninvertibleTransformException e){e.printStackTrace();}
return;
}
else { // translates the JComponent
Point loc=getLocation();
setLocation(loc.x+dx, loc.y+dy);
}
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top