Question

I am using a JPanel with an OverlayLayout to draw two unrelated components on top of each other. Specifically, I have a transparent component which contains my own line drawings, and beneath that, I am using a JMapViewer component, which displays OpenStreetMap tiles. This works.

Except when the JMapViewer loads tiles asynchronously. In that case, it calls repaint() on itself when the loading is finished, and it draws itself over my line layer. My line layer cannot know this, since it cannot know when the JMapViewer chooses to repaint itself.

Now I would have expected the JPanel to repaint my line layer when the map layer repaints, since it knows the correct drawing order and knows that my line layer has to be repainted. But it doesn't do this.

How would you solve this?

Was it helpful?

Solution

JMapViewer implements TileLoaderListener and simply calls repaint() when loading is finished. You should be able to update the map and then forward the event to your layer, as suggested below.

MyViewer map = new MyViewer();
...
private class MyViewer extends JMapViewer {

    @Override
    public void tileLoadingFinished(Tile tile, boolean success) {
        super.tileLoadingFinished(tile, success);
        lineLayer.repaint(); 
    }
}

OTHER TIPS

it calls repaint() on itself when the loading is finished,

Call repaint() on the parent panel instead.

This depends on how the JMapViewer repaints itself. If it just updates its content, the parent(s) might not even notice that something has changed.

I don't know if this is the best approach, but it's the only one I can think of. You could replace the RepaintManager for the JMapComponent with a custom one that also manages repaints of your overlayed component. That way, you can guarantee that your overlayed component always gets repainted last.

...do this from the AWT event thread via SwingUtilities

RepaintManager myManager = new RepaintManager() {
   public void  addDirtyRegion(JComponent c, int x, int y, int w, int h) {
....implemnt code here to guarentee your top level component gets repainted whenever 'c' is the JMapComponent
   }
}

RepaintManager.setCurrentManager(myManager);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top