Drawing multiple circles which you can drag

Wot I want is the following:

-A JPanel which add's multiple JComponents to his container. The components must be draggable;

Problem that I have

- I have set the layout manager of the JPanel to null (because I want to drag component over the hole screen). But in paintComponent of the JComponent I have to set the x and y coordinates of the circle to 0 otherwhise the components dont be drawed. When I set it 0 components cant be dragged because the x , y positions are wrong

publicclass NodePanelextends JPanelimplements MouseListener, MouseMotionListener

{

private List nodeComponents;

privateboolean canDrag;

public JFrame aFrame;

int xPos,yPos;

private NodeComponent[] nodeComponent;

public NodePanel()

{

setLayout(null);

setBorder(BorderFactory.createLineBorder(Color.BLUE,8));

setBackground(Color.WHITE);

setPreferredSize(new Dimension(1400,1050));

nodeComponents =new ArrayList();

nodeComponent =new NodeComponent[ 10 ];

for (int a = 0; a < 1; a++ )

{

nodeComponent[a] =new NodeComponent(this,this);

nodeComponents.add(nodeComponent[a]);

add(nodeComponent[a]);

}

}

publicvoid setNodes()

{

}

publicvoid mouseClicked(MouseEvent e)

{

}

publicvoid deselectNodes()

{

for(int i = 0; i<nodeComponents.size();i++)

{

NodeComponent tempNode;

tempNode = (NodeComponent)nodeComponents.get(i);

tempNode.setState(NodeComponent.DESELECTED);

}

}

publicboolean checkNodeSelected()

{

int count=0;

for(int i = 0; i><nodeComponents.size();i++)

{

NodeComponent tempNode;

tempNode = (NodeComponent)nodeComponents.get(i);

if(tempNode.getState()==NodeComponent.SELECTED)

{

count+=1;

}

}

if(count==0)

returntrue;

returnfalse;

}

publicvoid mousePressed(MouseEvent e)

{

NodeComponent nodeComponent = (NodeComponent) (e.getSource());

if(nodeComponent.isSelected(e.getX(),e.getY()))

{

if(!checkNodeSelected())

{

deselectNodes();

nodeComponent.setState(NodeComponent.SELECTED);

canDrag=true;

}

else

{

nodeComponent.setState(NodeComponent.SELECTED);

}

}

else

{

deselectNodes();

canDrag=false;

}

}

publicvoid mouseReleased(MouseEvent e)

{

}

publicvoid mouseEntered(MouseEvent e)

{

}

publicvoid mouseExited(MouseEvent e)

{

canDrag=false;

}

publicvoid mouseDragged(MouseEvent e)

{

if(canDrag)

{

NodeComponent nodeComponent = (NodeComponent) (e.getSource());

nodeComponent.setX(e.getX());

nodeComponent.setY(e.getY());

}

}

publicvoid mouseMoved(MouseEvent e)

{

}

}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

publicclass NodeComponentextends JComponent

{

privatestaticfinallong serialVersionUID = 7885668531540377778;

publicstaticfinalint DESELECTED = 0, SELECTED = 1;

privateint state;

publicint x;

publicint y;

privateint diameter;

private Random r =new Random();

public NodeComponent(MouseListener mouseListener,MouseMotionListener mouseMotionListener)

{

diameter=20;

x=r.nextInt(1400-40);

y=r.nextInt(1050-20);

setPreferredSize(new Dimension(diameter,diameter));

setBounds(x,y,40,20);

this.setLocation(x,y);

setState(DESELECTED);

setVisible(true);

addMouseListener(mouseListener);

addMouseMotionListener(mouseMotionListener);

}

publicvoid paintComponent(Graphics g)

{

super.paintComponents(g);

//System.out.println("Paintcomponent " + x +" "+ y + " " + diameter);

System.out.println(this.getX());

g.fillOval(0,0,diameter,diameter);

if(state==SELECTED)

{

g.setColor(Color.RED);

g.drawRect(x,y,diameter,diameter);

}

if(state==DESELECTED)

{

}

}

publicint getState()

{

return state;

}

publicvoid setState(int state)

{

this.state = state;

switch (state)

{

case DESELECTED:

state=DESELECTED;

repaint();

break;

case SELECTED:

state=SELECTED;

repaint();

break;

}

}

publicboolean isSelected(int mouseX,int mouseY)

{

if(mouseX>=x && mouseX<=(x+diameter) && mouseY<= (y+diameter) && mouseY>= y)

{

returntrue;

}

returnfalse;

}

publicvoid setX(int x)

{

this.x=x;

repaint();

}

publicvoid setY(int y)

{

this.y=y;

repaint();

}

}

Hope somebody can help me

[11064 byte] By [BennoTa] at [2007-10-3 8:56:35]
# 1
If I was writing a panel where you could drag circles I wouldn't use components for the circles. I'd just maintain a list of shapes and have a single mouse handler. It'd make the implementation a lot easier and the code would be more efficient in terms of memory and speed.
itchyscratchya at 2007-7-15 4:06:52 > top of Java-index,Desktop,Core GUI APIs...
# 2
Dont get it wot you mean. Using paint from JPanel ?Maybe you can explain it with a small piece of source code Wanna make an overlay of a wireless networkGreetzMessage was edited by: BennoT
BennoTa at 2007-7-15 4:06:52 > top of Java-index,Desktop,Core GUI APIs...
# 3

eg

public class Circles extends JPanel

{

private final Set shapes = new LinkedHashSet();

public Circles()

{

MouseHandler h = new MouseHandler();

addMouseListener(h);

addMouseMotionListener(h);

}

protected void paintComponent(Graphics g)

{

super.paintComponent(g);

for (Iterator i = this.shapes.iterator(); i.hasNext(); )

{

((Graphics2d) g).draw((Shape) i.next());

}

}

// Implement whatever methods required to add and remove

// your circles contained in the 'shapes' set.

private final class MouseHandler extends MouseInputAdapter

{

// Implement methods using an iterator and shape.contains()

// to determine what's under the mouse. If you're detecting

// interaction with the circle edges (lines) then instead of

// storing circles directly in the 'shapes' set you'll need to

// store stroked shapes (see Stroke.createStrokedShape())

// so that "contains()" operates on the line rather than the

// whole area within the circle.

}

}

itchyscratchya at 2007-7-15 4:06:52 > top of Java-index,Desktop,Core GUI APIs...
# 4
Thnx gonna give it a try :)
BennoTa at 2007-7-15 4:06:52 > top of Java-index,Desktop,Core GUI APIs...
# 5

I made this now...But changing a shape his position dont have a clue yet how to do it.

class CirclePanel extends JPanel

{

private double xPos,yPos;

private List placeList;

private Shape shape,shape1;

private Circle circle;

private final Set shapes = new LinkedHashSet();

private boolean canDrag=false;

public CirclePanel()

{

setBackground(Color.BLUE);

MouseHandler h = new MouseHandler();

addMouseListener(h);

addMouseMotionListener(h);

shape= new Ellipse2D.Double(xPos,yPos,20.0,20.0);

shape1= new Ellipse2D.Double(xPos,yPos+30,20.0,20.0);

this.addShape(shape);

this.addShape(shape1);

}

public void paintComponent(Graphics g)

{

Graphics2D g2 = (Graphics2D)g;

for(Iterator i = shapes.iterator(); i.hasNext();)

{

((Graphics2D) g).draw((Shape)i.next());

}

}

public void addShape(Shape shape)

{

shapes.add(shape);

}

public void removeShape(Shape shape)

{

shapes.remove(shape);

}

public void setX(int x)

{

xPos=x;

}

public void setY(int y)

{

yPos=y;

}

private final class MouseHandler extends MouseInputAdapter

{

public void mousePressed(MouseEvent e)

{

Point p = e.getPoint();

for(Iterator i = shapes.iterator(); i.hasNext();)

{

Shape shape = (Shape) i.next();

if(shape.contains(p))

{

canDrag=true;

System.out.println("clicked");

}

else

{

canDrag=false;

}

}

}

public void mouseDragged(MouseEvent e)

{

if(canDrag)

{

Point p = e.getPoint();

for(Iterator i = shapes.iterator(); i.hasNext();)

{

Shape shape = (Shape) i.next();

setX(p.x);

setY(p.y);

}

}

}

}

}

BennoTa at 2007-7-15 4:06:52 > top of Java-index,Desktop,Core GUI APIs...
# 6

import java.awt.BasicStroke;

import java.awt.Color;

import java.awt.Graphics;

import java.awt.Graphics2D;

import java.awt.Paint;

import java.awt.Point;

import java.awt.Shape;

import java.awt.Stroke;

import java.awt.event.MouseEvent;

import java.awt.geom.Ellipse2D;

import java.util.Iterator;

import java.util.LinkedHashMap;

import java.util.Map;

import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.SwingUtilities;

import javax.swing.event.MouseInputAdapter;

public class CirclePanel extends JPanel

{

private final Map shapesToLocations = new LinkedHashMap();

private final Stroke stroke = new BasicStroke(3.0f);

private final Paint paint = Color.BLACK;

public static final void main(String[] args)

{

SwingUtilities.invokeLater(new Runnable()

{

public void run()

{

CirclePanel p = new CirclePanel();

p.addShape(new Ellipse2D.Double(10.0, 10.0, 20.0, 20.0));

p.addShape(new Ellipse2D.Double(10.0, 40.0, 20.0, 20.0));

JFrame f = new JFrame();

f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

f.setContentPane(p);

f.setSize(300, 300);

f.setLocationRelativeTo(null);

f.setVisible(true);

}

});

}

public CirclePanel()

{

MouseHandler h = new MouseHandler();

addMouseListener(h);

addMouseMotionListener(h);

}

public void paintComponent(Graphics g)

{

super.paintComponent(g);

Graphics2D g2d = ((Graphics2D) g);

Paint p = g2d.getPaint();

Stroke s = g2d.getStroke();

g2d.setPaint(this.paint);

g2d.setStroke(this.stroke);

for (Iterator i = this.shapesToLocations.keySet().iterator(); i.hasNext();)

{

Shape shape = (Shape) i.next();

Point location = (Point) this.shapesToLocations.get(shape);

g2d.translate(location.x, location.y);

g2d.draw(shape);

g2d.translate(- location.x, - location.y);

}

g2d.setPaint(p);

g2d.setStroke(s);

}

public void addShape(Shape shape)

{

this.shapesToLocations.put(shape, new Point());

}

public void removeShape(Shape shape)

{

this.shapesToLocations.remove(shape);

}

private final class MouseHandler extends MouseInputAdapter

{

private Shape dragShape = null;

private Point lastPoint = null;

public void mousePressed(MouseEvent e)

{

lastPoint = e.getPoint();

Point p = new Point();

for (Iterator i = shapesToLocations.keySet().iterator(); (this.dragShape == null) && i.hasNext();)

{

Shape shape = (Shape) i.next();

Point location = (Point) shapesToLocations.get(shape);

p.x = lastPoint.x - location.x;

p.y = lastPoint.y - location.y;

if (shape.contains(p))

{

this.dragShape = shape;

}

}

}

public void mouseReleased(MouseEvent e)

{

this.dragShape = null;

this.lastPoint = null;

}

public void mouseDragged(MouseEvent e)

{

if (this.dragShape != null)

{

Point location = (Point) shapesToLocations.get(this.dragShape);

location.x += (e.getX() - lastPoint.x);

location.y += (e.getY() - lastPoint.y);

this.lastPoint = e.getPoint();

repaint();

}

}

}

}

itchyscratchya at 2007-7-15 4:06:52 > top of Java-index,Desktop,Core GUI APIs...
# 7

It works great. Although I have some development issues.

Wanna monitor a zigbee network ( wireless nodes).

Each circle must represent a node. Would be handy if I can give each node a name. also wanna draw lines between nodes which represent the connection between them.

You think the setup like it is now is fine so I can use it.

That why I have chosen for JComponents first... but painting the nodes correctly went wrong.

Message was edited by:

BennoT

BennoTa at 2007-7-15 4:06:52 > top of Java-index,Desktop,Core GUI APIs...