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

SwingX-WS mit JXMapKit auf der SIGMOD 2010 / PAROS: Pareto Optimal Route Selection

Zusammen mit meinen Kollegen haben wir eine Demo auf einer der wichtigsten Datenbank Konferenzen eingereicht, die ich letzte Woche in Indianapolis auf der SIGMOD (ACM Special Interest Group on Management of Data) zeigen durfte. Die Demo firmiert übrigens unter dem Titel PAROS: Pareto Optimal Route Selection.

Im Wesentlichen ging es dabei darum, einen von meinen Kollegen entwickelten Skyline-Algorithmus auf Straßennetzen anzuwenden um damit Wege unter mehreren Einschränkungen zu finden. Die klassische, einfache Wegsuche ist ja zum Beispiel “finde den kürzesten oder schnellsten Weg”. Bei der Skyline-Abfrage, geht es dabei darum, alle die Wege zu finden, die unter mehreren Attributen optimal sind. Also zum Beispiel alle kürzesten und schnellsten Wege, die gleichzeitig möglichst wenig Ampeln enthalten. Es müssen also mehrere Attribute gleichzeitig optimiert werden.

Da Datenmasse in der Wissenschaft oft Mangelware ist, habe ich zusammen mit etwas studentischer Hilfe einen Konverter für OpenStreetMap-Daten geschrieben um beliebig viele Daten erhalten zu können. Visualisiert wurde das Ganze mit Hilfe der JXMapKit-Komponente aus SwingX-WS! Die Gui-Entwicklung ging dank dem NetBeans Gui-Builder wie erwartet erfreulich einfach, so dass ich mich in der knappen Zeit auf die Integration des Algorithmus und auf die Architektur konzentrieren konnte. Die Architektur sollte es ermöglichen, Model und View  möglichst so zu kapseln, dass die Entwicklung und Integration neuer Algorithmen so einfach wie möglich und möglichst Unabhängig von jeglicher GUI-Programmierung ist, so dass auch Studenten schnell und einfach neue Algorithmen entwickeln und testen können.

Ich habe zwar (wie erwartet) nicht den Best-Demo-Preis bekommen, allerdings waren wirklich viele interessierte Leute auf den Demo-Sessions. Überrascht hat mich, dass ich sehr oft gefragt wurde, ob wir die Demo online stellen würden, bzw. ob die Demo OpenSource ist. Nach Rücksprache mit den Kollegen, kamen wir zu dem Schluss, dass das eine gute Idee sei und ich das machen werde. Ich werde in den nächsten Wochen also noch etwas den Code aufräumen, dokumentieren, online stellen und hoffen, dass jemand die Demo interessant und nützlich findet – vielleicht sogar so, dass es die Basis für ein oder mehre Zitationen bringt (ist immer wichtig bei Veröffentlichungen).

UPDATE: endlich ist der – äh – unschöne Code online. Da ich auch in absehbarer Zeit nicht die Zeit habe, ihn schön sauber und dokumentiert zu machen, kann ich ihn auch gleich online stellen. zum Download gehts hier lang.

Relevante Links:

Wegpunkte mit JXMapKit zeichnen

Im Artikel “Erste Schritte mit JavaX JXMapKit” habe ich schon kurz beschrieben, wie man mit NetBeans und SwingX-WS schnell und einfach eine Kartendarestllung á la GoogleMaps in Java bauen kann.

Wenn man nicht nur eine Karte anzeigen sondern auch Punkte einzeichnen will, hat man die Möglichkeiten, per jXMapKit.setAddressLocation(new GeoPosition(lat, lon)); die Koordinaten setzen, zeichnen und die Karte dorthin zentrieren. Allerdings wird die Karte damit auch immer gleich zentriert und vor allem kann man nur einen einzelnen Punkt setzen.

Mehrere Wegpunkte setzt man mithilfe des WaypointPainters:

Set set = new HashSet();
WaypointPainter waypointPainter = new WaypointPainter();
waypointPainter.setWaypoints(set);
set.add(new Waypoint(47.76098, 11.55932));
jXMapKit.getMainMap().setOverlayPainter(waypointPainter);
repaint();

Das repaint() am Ende sollte immer erfolgen, wenn neue Punkte in das Set gesetzt werden, damit die Änderung auch sofort sichtbar ist. Andernfalls muss man die Karte etwas verschieben um ein repaint zu erzwingen. Will man jetzt noch die Darstellung der Wegpunkte verändern, muss man sich noch mit dem WaypointRenderer beschäftigen.

JXMapviewer bald ohne SwingX-WS?

Wer mit JXMapviewer (aus SwingX-WS) gearbeitet hat (siehe früherer Post), wird früher oder später darauf gekommen sein, dass SwingX-WS nicht/kaum mehr maintained ist und man irgendwann anfangen darf, selbst zu patchen – mit der Gewissheit, dass die Änderung wohl nie in die offizielle Distribution zurückfließen wird.

Fabrizio Giudici hat dasselbe Problem – und wie es scheint, würde er sich daran machen, die MapViewer-Komponente auszugliedern und separat weiterzuführen. Entsprechende Hinweise finden sich in seinem Blog und im Java.Net-Forum. Bleibt zu hoffen, dass er es durchzieht!

improved ButtonUI

In the JavaGraphics Blog there are some very nice examples of how Java Buttons can be made nicely. The code is also available. So it’ a nice starting point for learning how to make own UIs! Features include:

  • cross-platform.
  • pure Java
  • Resizable
  • Vertical segments
  • Java 1.4 compatible

See the BlogPost here.