Question

I have a Swing app with a glass pane over a map.

It paints dots at certain positions. When I click somewhere on the map, and the glass pane receives the message CONTROLLER_NEW_POLYGON_MARK I want do display an additional dot at the position specified in the event data (see MyGlassPane.propertyChange).

The glass pane class is called MyGlassPane. Using the debugger I validated that addPointToMark is actually called in propertyChange.

But no additional dots appear on the screen.

How can I change the code so that PointSetMarkingGlassPane.paintComponent is called whenever an event (IEventBus.CONTROLLER_NEW_POLYGON_MARK) is fired?

public class PointSetMarkingGlassPane extends JComponent implements IGlassPane {
    private final ILatLongToScreenCoordinatesConverter latLongToScreenCoordinatesConverter;
    private final List<Point.Double> pointsToMark = new LinkedList<Point.Double>();

    public PointSetMarkingGlassPane(final ILatLongToScreenCoordinatesConverter aConverter) {
        this.latLongToScreenCoordinatesConverter = aConverter;
    }

    protected void addPointToMark(final Point.Double aPoint)
    {
        if (aPoint != null)
        {
            pointsToMark.add(aPoint);
        }
    }

    @Override
    protected void paintComponent(final Graphics aGraphics) {
        for (final Point.Double pointToMark : pointsToMark)
        {
            final Point positionInScreenCoords = latLongToScreenCoordinatesConverter.getScreenCoordinates(pointToMark);
            drawCircle(aGraphics, positionInScreenCoords, Color.red);
        }
    }

    private void drawCircle(Graphics g, Point point, Color color) {
        g.setColor(color);
        g.fillOval(point.x, point.y, 10, 10);
    }

}

public class MyGlassPane extends PointSetMarkingGlassPane implements PropertyChangeListener {
    public MyGlassPane(ILatLongToScreenCoordinatesConverter aConverter) {
        super(aConverter);

        addPointToMark(DemoGlassPane.ARTYOM);
    }

    @Override
    public void propertyChange(PropertyChangeEvent evt) {
        if (IEventBus.CONTROLLER_NEW_POLYGON_MARK.equals(evt.getPropertyName()))
        {
            addPointToMark((Point.Double)evt.getNewValue());
            invalidate();
        }
    }
}
Was it helpful?

Solution

As I think invalidate() only flags your component to check sizes and layout. You should call repaint() to repaint your pane.

Also I am wondering why you use propertyChangeListener for mouse clicks. I would prefer just simple mouse listener + MouseAdapter and MouseEvent x, y, buttons state.

OTHER TIPS

invalidate() probably won't help you, as it flags a component for layout changes, not painting changes. Why not call repaint() instead?

For better performance, you could call the repaint method which takes a Rectangle (or four ints representing a rectangle), so that only the newly added point is repainted; I would suggest changing the return type of addPointToMark from void to java.awt.Point, and have it return the result of latLongToScreenCoordinatesConverter.getScreenCoordinates, so MyGlassPane can derive a rectangle from that Point which can then be passed to a repaint method.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top