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]

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.
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
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.
}
}
Thnx gonna give it a try :)
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);
}
}
}
}
}
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();
}
}
}
}
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