Selektierbare Shapes

HimBromBeere

Top Contributor
Tach,

wie der Titel bereits erwähnt, suche ich nach ´ner Möglichkeit, meine innerhalb eines JPanels gezeichneten Geometrien selektieren zu können (oder zu verschieben, oder weiß der Kuckuck, was man mit der Maus auf ´ner Geometrie noch anstellen kann).

Ich speichere also sämtliche Geomtrien (Punkte, (Poly-)Linien, Polygone) in eine Liste, lege einen MouseListener auf mein Panel und prüfe nun bei jedem Mausklick, ob irgendeine Geometrie in meiner Liste die Bedingung shape.intersects(MouseRectangle) erfüllt (MouseRectangle ist jetzt erstmal nur ein Platzhalter für ´nen Puffer um die Mausposition).
Das scheint mir doc irgendwie ein wenig umständlich zu sein, hauptsächlich deswegen, weil ich bereits eine Schleife hab, die alle Geometrien iteriert und zeichnet (permormancetechnisch wäre es also wahrscheinlich schlau, diese Überprüfung innerhalb der Zeichenschleife mitzuerledigen, allerdings find ich das jetzt nicht wirklich stilvoll und elegant... ). Also in anderen Worten: zeichne eine Geometrie und prüfe dabei gleich mal, ob sie selektiert wurde.
Gibt es denn nicht eine Möglichkeit, das ganze über ´nen eigenen MouseListener zu regeln, der auf alle Geometrien draufgelegt wird. Aber wie leg ich einen solchene Listener auf mehrere hundert Objekte und unterscheide dann, wo sie herkommen?


Denkanstöße fände ich hier echt nett... danke schonmal
 

Schandro

Top Contributor
permormancetechnisch wäre es also wahrscheinlich schlau, diese Überprüfung innerhalb der Zeichenschleife mitzuerledigen
Nein, das pure iterieren macht ja nicht die Last aus, sondern das was innerhalb der Schleife passiert. Und selbst wenn es für die performance besser wäre wäre es ein grauenvoller Ort, sowas gehört definitiv nicht da rein.
 

HimBromBeere

Top Contributor
Nein, das pure iterieren macht ja nicht die Last aus, sondern das was innerhalb der Schleife passiert. Und selbst wenn es für die performance besser wäre wäre es ein grauenvoller Ort, sowas gehört definitiv nicht da rein.

Naja, so stimmt das auch nicht ganz, es macht schon eines Unterschied, ob ich zwei Schleifen nacheiandner ausführen, oder ob ich den INHALT der einen in die andere inkludiere (aber nur den Inhalt, nicht die gesamte Schleife natürlich). Stiltechnisch hast du natürlich Recht, ich fand´s eben auch grausig...
 

hdi

Top Contributor
Gibt es denn nicht eine Möglichkeit, das ganze über ´nen eigenen MouseListener zu regeln, der auf alle Geometrien draufgelegt wird. Aber wie leg ich einen solchene Listener auf mehrere hundert Objekte und unterscheide dann, wo sie herkommen?
Wäre genau das selbe wie das, was du jetzt machst, nur andersrum aufgezogen. Ich sehe an deinem Ansatz überhaupt kein Problem. Ob Java nun intern über einen MouseListener auf einem Objekt prüft, ob dieser gefeuert werden soll, oder du die Prüfung selbst vornimmst macht auch keinen Unterschied in der Performance. Die Idee mit Zeichen/Selektieren vermischen vergiss mal schnell wieder. Das ist schon gut so, wie du es machst. Eine Schleifen-Iteration mit einem intersects() dauert nicht so lange. Mach dir doch mal testweise eine Dummy-Liste mit x Elementen und mach ne Zeitstoppung (System.currentTimeMillis() vor und nach Schleife, und Differenz berechnen). Du wirst sehen dass du wohl niemals soviele Objekte haben wirst, dass man sich da über Performance den Kopf zerbrechen muss.
 

Michael...

Top Contributor
Einen MouseListener auf gezeichnete Geometrien legen geht nicht. Aber man kann durchaus in einer Schleife prüfen ob mit der Maus auf eine Geometrie geklickt wurde.
Hier mal ein Bsp. welchen eine Klasse Polyline verwendet und ermitteln kann ob ein Punkt auf der Geometrie liegt, um das ganze zu beschleunigen wird zunächst geprüft, ob der Mausclick überhaupt in der Boundingbox bzw. im Boundingrect liegt:
http://www.java-forum.org/java-basics-anfaenger-themen/104049-polygon-polyline-2.html#post663976
 

Marco13

Top Contributor
Man könnte den Unterschied etwas plakativ auf den zwischen O(2*n) und O(n*2) zurückführen. Ganz so einfach ist es in der Praxis nicht, aber es kommt auf was ähnliches raus. Wie schon gesagt wurde ist das Teure hierbei nicht das drüberiterieren an sich, sondern das contains/intersects zu überprüfen. Wenn man "viele" Objekte hat, kann es sich lohnen, sich da was geschickteres zu überlegen. Je nachdem, welche Shapes das sind, KÖNNTE (!) es sich z.B. lohnen, erstmal die BoundingBox zu testen, also sowas wie
Java:
if (shape.getBounds().contains(mousePoint))
{
    // Vielleicht ein Treffer...
    if (shape.contains(mousePoint))
    {
        // Treffer
    }
    else
    {
        // KEIN Treffer
    }
}
else
{
    // KEIN Treffer
}

Wenn alle Objekte z.B. "Ellipse2D" oder komplexe Path2D-Objekte sind, könnte das schneller sein, weil die meisten schon beim BoundingBox-Test durchfallen. Wenn alle Objekte Rectangle2D sind, macht man alle Tests doppelt, was dann auch wieder blöd wäre...

Wenn das alles nicht hilft, hängen die weiteren Möglichkeiten auch davon ab, ob sich die Objekte z.B. bewegen oder so...
 

HimBromBeere

Top Contributor
Was macht O(2n) und O(n*2) für ´nen Unterschied? Linear sind ´se beide, und das mit Faktor 2...

Mein Shapes sind nahezu ausschließlich Punkte, Polylinine und Polygone (welche aber recht unregelmäßig ausfallen können). Rechtecke werden eher die Seltenheit sein, Ellipsen oder elliptic Arcs zum Glück aber auch. Die Idee der Boundbox versteht sich fast von selbst, das wollte ich also sowieso noch einbauen (Stichwort Spatial Index, aber das führt zu weit).

Bin gerade dabei, mir meine Shape-Liste zusammenzuschustern, den Geschwindigkeitstest mach ich dann wahrscheinlich morgen mal...
 

Marco13

Top Contributor
Was macht O(2n) und O(n*2) für ´nen Unterschied? Linear sind ´se beide, und das mit Faktor 2...

Darum ging's ja - ob man
Java:
for (Object object : objects) 
{
    render(object);
    pickTest(object);
}
oder
Java:
for (Object object : objects) 
{
    render(object);
}
for (Object object : objects) 
{
    pickTest(object);
}
macht ist wurscht... ;)
 

HimBromBeere

Top Contributor
Achso... ne, ich dachte, dass das einen Unterschied macht, weil ich ja im unteren Fall doppelt so oft da durch renne... genau das wollt ich wissen, irgendwie...

Aaaah, hat BING gemacht von wegen O(2n) und O(n*2)... im ersten Fall läuft man nur einmal durch eine Schleife mit doppeltem Inhalt, beim zweiten mal läuft man je einmal durch eine Schleife mit einfachem Inhalt... Summa Summarum beides identisch... Danke
 

HimBromBeere

Top Contributor
So, nachdem ich nun alle meine Geometrien in einer rieseigen HashMap untergebracht hab (ich musste die nämlich noch nach Ebenen aufdröseln), hab ich mal auf einer dieser Ebenen das neu eingebaute Click-Event probiert und es läuft... JAU, so muss das sein.

Danke für die moralische Unterstützung :D
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
X Geometrien und Shapes Java Basics - Anfänger-Themen 5

Ähnliche Java Themen


Oben