I have a list of Shape drawn on a JPanel and I need to change the color of those which contain a point obtained via mouse click, but I really can't understand how to use repaint() to do that.
This is the test class:
public class TestShapeViewer
{
public static void main(String[] args)
{
List<Shape> figure = new ArrayList<Shape>();
Utils util = new Utils();
figure.add(new Rect(new P2d(200,200), new P2d(90,40)));
figure.add(new Circle(new P2d (150,150), new P2d (300,150)));
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
createAndShowWindow(figure);
}
});
}
private static void createAndShowWindow(List<Shape> figure)
{
JFrame window = new JFrame("TestShapeViewer");
window.setSize(500,500);
window.setLocationRelativeTo(null);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.add(new Viewer(figure));
window.pack();
window.setVisible(true);
}
}
This is my JPanel class
public class Viewer extends JPanel implements ShapeViewer
{
private List<Shape> shapesToDraw;
private List<Shape> shapeToColor;
private Utils utility = new Utils();
private Color colorToUse;
public Viewer(List<Shape> shapes)
{
this.shapesToDraw = shapes;
this.colorToUse = Color.BLACK;
addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e) {
repaintShapes(e.getX(), e.getY());
}
});
}
public void update(List<Shape> shapes)
{
this.shapesToDraw = shapes;
}
public Dimension getPreferredSize()
{
return new Dimension(500,500);
}
public void paintComponent(Graphics shape)
{
super.paintComponent(shape);
shape.setColor(colorToUse);
shapesToDraw.stream().forEach(x -> DrawShape(shape,x));
}
public void DrawShape(Graphics shape, Shape s)
{
BBox box = s.getBBox();
if (s instanceof Line)
{
shape.drawLine(box.getUpperLeft().getX(),
box.getUpperLeft().getY(),
box.getBottomRight().getX(),
box.getBottomRight().getY());
}
else if(s instanceof Rect)
{
int[] xpoints = {box.getUpperLeft().getX(),
box.getBottomRight().getX(),
box.getBottomRight().getX(),
box.getUpperLeft().getX()};
int[] ypoints = {box.getUpperLeft().getY(),
box.getUpperLeft().getY(),
box.getBottomRight().getY(),
box.getBottomRight().getY()};
Polygon rect = new Polygon(xpoints, ypoints, 4);
shape.drawPolygon(rect);
}
else if(s instanceof Circle)
{
int raggio = (int)(new Line(box.getUpperLeft(),
new P2d(box.getBottomRight().getX(),
box.getUpperLeft().getY())).getPerim())/2;
shape.drawOval(box.getUpperLeft().getX(),
box.getUpperLeft().getY(),
raggio*2, raggio*2);
}
else if(s instanceof Combo)
{
Combo co = (Combo) s;
co.getComp().stream().forEach(x -> DrawShape(shape,x));
}
}
private void repaintShapes(int x, int y)
{
shapeToColor = utility.getContaining(shapesToDraw,new P2d(x,y));
this.colorToUse = Color.RED;
repaint();
}
}
My purpose is to click in a point, check what shapes contain that point and change only their color.
For clarity:
I have a list of Shape drawn on a JPanel and I need to change the color of those which contain a point
Instead of keeping a List of Shapes. You can keep a List of "ColoredShapes". You would create a custom class that contains two properties: 1) Shape, 2) Color and add this object to the List. Of course you would also need to modify the painting code to get the Color information before painting the Shape.
Then when you use the mouse to click on a point you iterate through the List to find any Shape that contains the mouse point and you update the Color. Then you simply invoke repaint() on your custom painting panel.
Check out the DrawOnComponent
example from Custom Painting Approaches. This approach uses a "ColoredRectangle" to keep track of the two properties, so the approach is very similar to what you need.