Selektionsfenster in SwingX-WS / JXMapKit

Um in der Mapkomponente von JXMapKit eine Selektion (Rechteck mit Rahmen und leicht transparenter Füllung) zu zeichnen, wird lediglich ein entsprechender Painter und ein Mouseadapter benötigt. Der Code dazu sieht folgendermaßen aus:

Der Painter & MouseListener:

public class SelectionPainter extends MouseAdapter implements Painter<JXMapViewer> {

    private Rectangle rect, start, end;
    private Color borderColor = new Color(0, 0, 200);
    private Color regionColor = new Color(0, 0, 200, 75);

    public SelectionPainter() {
    }

    @Override
    public void mousePressed(MouseEvent e) {
        if (e.getButton() != MouseEvent.BUTTON1) {
            rect = null;
            start = null;
        } else {
            start = new Rectangle(e.getPoint());
            ((JXMapViewer) e.getSource()).setPanEnabled(false);
        }
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        if (start != null) {
            end = new Rectangle(e.getPoint());
            rect = start.union(end);
        }
        ((JXMapViewer) e.getSource()).repaint();
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        if (start == null) {
            return;
        }
        end = new Rectangle(e.getPoint());
        rect = start.union(end);
        ((JXMapViewer) e.getSource()).setPanEnabled(true);
        ((JXMapViewer) e.getSource()).repaint();
    }

    @Override
    public void paint(Graphics2D gd, JXMapViewer t, int i, int i1) {
        if (rect != null) {
            gd.setColor(regionColor);
            gd.fillRect(rect.x, rect.y, rect.width, rect.height);
            gd.setColor(borderColor);
            gd.drawRect(rect.x, rect.y, rect.width, rect.height);
        }
    }
}

Verbindung zur Map-Komponente:

 SelectionPainter sp = new SelectionPainter();
mapKit.getMainMap().addMouseListener(sp);
mapKit.getMainMap().addMouseMotionListener(sp);
mapKit.getMainMap().setOverlayPainter(sp);

mapKit ist dabei eine Instanz von org.jdesktop.swingx.JXMapKit.

Artikel mit gepatchtem SwingX-WS

9 thoughts on “Selektionsfenster in SwingX-WS / JXMapKit”

  1. Hi, ich habe Probleme die jar files zu bekommen, die auf dem Oracle-Server nicht zu finden sind. Hast Du Links zu den benötigten Jars um den JXMapViewer nutzen zu können?
    Danke vorab,
    Steff

  2. irgendwie meint er bei mir immer die paint methode aus dem Code von hier sei keine Gültige überschreibung, Eclipse legt mir als Gültige Kopfzeile immer:
    paint(Graphics2D, Object, int,int) vor. wie “überrede” ich mein programm dennoch die hier verwendete Methodensignatur anzuerkennen? alternativ könnt ich auch einfach den Override flag entfernen aber ich glaub dann gehts erst recht nichtmehr oder?

    1. Ach – das liegt daran, dass die Generic-Deklaration hiner “implements Painter” gefehlt hat.

  3. hello Dr. Franz,
    I will put my problem here:
    JXMapViewer provides the method calculateZoomFrom(Set positions) which helps me to shift my focus to the center and adjust zoom level such that my waypoints are inside view port bounds, For view port bounds it creates outer rectangle. for waypoint bounds it creates inner rectangle. Now even if waypoints are inside view port bounds (so that outer.contains(inner) condition is satisfied) and zoom is at some maximum level so that my waypoint inner rectangle is not exactly fitting into view port bounds, JxMapViewer does nothing. In this case JxMapViewer assumes that waypoints are inside view port bounds irrespective of zoom level and stops there. I am trying to fix this issue. But no luck. I tried to implement my own calculateFromZoom method. But not able to find any way with which I can make sure that my inner rectangle for waypoints fits exactly into viewPortBounds given by JxMapViewer. Here is my code:
    int zoom = mainMap.getZoom();
    Rectangle2D inner = generateBoundedRectangleForLine(positionSet, mainMap.getZoom());

    int count = 0;
    Rectangle outer = mainMap.getViewportBounds();
    while(!outer.contains(inner) || (outer.contains(inner) && !(inner.getHeight() >= mainMap.getHeight() – 50))) {
    Point2D center = new Point2D.Double(
    inner.getX() + inner.getWidth()/2,
    inner.getY() + inner.getHeight()/2);
    GeoPosition px = mainMap.getTileFactory().pixelToGeo(center,zoom);
    mainMap.setCenterPosition(px);
    count++;
    if(count > 30) break;
    if(outer.contains(inner)) {
    if (!(inner.getHeight() >= mainMap.getHeight() – 50)) {
    zoom = zoom – 1;
    if(zoom 15) {
    break;
    }
    }

    mainMap.setZoom(zoom);
    inner = generateBoundedRectangleForLine(positionSet, zoom);
    }

    Kindly let me know any hint on how to proceed.

    1. HI, regarding the link in Stackoverflow I guess you managed to solve your problem, right?

      1. Yes Dr. Franz. Its very difficult for a newbie like me to work on JxMapViewer as we have very less information available over the internet and API documentation itself. We appreciate your posts and guidelines on using JxMapViewer. Thank you very much!

Comments are closed.