# Java2D-Komponenten



## roman63 (25. Feb 2008)

Ich möchte folgendes machen: 

Zwischen 2 Kreis-Figuren soll eine Verbindung gezeichnet werden. Sowohl die Kreis-Figuren als auch die Verbindungslinie stehen stellvertretend für Objekte, die eben ein paar Attribute haben. So könnte man (oder mann sollte können) mit einem Doppelklick auf den Kreis ein Dialog anzeigen, in dem die für das durch den Kreis dargestellte Objekt relevanten Informationen angezeigt werden. Das gleiche soll auch mit der Verbindungslinie möglich sein. 

*Beispiel*: 
Ein Geschäftsauto wird für 3 Aufträge gebraucht. Das Geschäftsauto-Objekt wird in der Mitte als ein Kreis dargestellt, während die drei Auftrag-Kreise um den Geschäftsauto-Kreis angeordnet werden. Jeder Auftrag-Kreis wird mit dem Geschäftsauto-Kreis verbunden, wobei die jeweilige Verbindung beispielsweise die Informationen darüber enthalten könnte, wann und wie Lange das Gäscheftsauto für den konkreten  Auftrag eingesetzt wurde. Mit einem Doppelklick auf eine solche Verbindung könnte man diese Informationen in einem Dialog anzeigen lassen. Das gleiche gilt auch für den Geschäftsauto-Kreis und die Auftrag-Kreise. 

Wie könnte so was realisiert werden? Könnte man die Kreis-Figuren und die Verbindungslinien als Komponenten definieren und zeichnen? Denn, mit einem Doppelklick auf eine Komponente könnte man das Anzeigen eines Dialogs initieren, würde ich meinen. Und, wie könnte man am einfachsten solche "Komponenten" in einem JPanel zeichnen lassen? 

Danke.


----------



## Marco13 (26. Feb 2008)

"Komponenten" im Sinne von Components sollten das wohl nicht sein. Abgesehen davon, dass man für einen Kreis nur Mittelpunkt+Radius braucht, und bei einer Component SEHR viele überflüssige Informationen dabei sind, bringt dir die Component spätestens bei der Linie auch nichts mehr: Ob die Linie durch einen Klick getroffen wurde, musst du so oder so "per Hand" ausrechnen.

Je nachdem, wie allgemein das ganze sein soll, gäbe es da verschiedene mögliche Ansätze. Auf Basis der wenigen Informationen, die du bisher gegeben hast, wäre sowas vielleicht denkbar...

```
interface Item
{
    public void draw(Graphics g); // Zum zeichnen

    public boolean isHitByClick(Point position); // Zum prüfen, ob das Objekt von einem Klick getroffen wird

    public String (???) getInformation(); // Liefert das, was im Dialog angezeigt wird (Könnte ggf. auch eine eigene Klasse "ItemInformation" sein!!!)
}

class CircleItem implements Item
{
    private Point center;
    private int radius;

...
    public void draw(Graphics g) { g.drawOval(...); }

    public boolean isHitByClick(Point position) { return (abstand zwischen center und position ist < radius); }
}

class LineItem implements Item
{
    private Point point0;
    private Point point1;

    public void draw(Graphics g) { g.drawLine(...); }

    public boolean isHitByClick(Point position) { return (abstand zwischen position Line(Point0,Point1) ist "klein"); }
}
```
Aber die genaue Implementierung ... musst du dir ausdenken :wink:


----------



## roman63 (27. Feb 2008)

Heisst, dass ich laufend die Position des Maus-Zeigers scannen muss und entsprechend reagieren, wenn sich der Mauszeiger in der Nähe eines Kreies / einer Linie befindet. Und, gerade dem wollte ich eben ausweichen   . Ich hoffe, dass die laufende Berechnung von Abständen einigermassen funktionieren wird und nicht allzuviele Ressorcen beanspruchen wird.

Vielen Dank und Gruss.


----------



## Marco13 (27. Feb 2008)

Nun, was heißt "scannen"... Man verwendet einen MouseMotionListener, und in der mouseMoved-Methode macht man die Abstandsberechnung. Bei ein paar Linien und kreisen ist das noch unproblematisch. Wenn es "viele" (vielleicht > 1000) Kreise und Linien werden, kann das schon langsam werden, aber dann muss man sich eben was überlegen, um es schneller zu kriegen... (Besser wäre natürlich, einen MouseListener zu verwenden, und die Berechnungen nur bei mouseClicked zu machen) Wenn man "viele" (>1000) Components hätte, wäre das noch weitaus schlimmer - was sollte man dann machen  :? an jede Component einen MouseMotionListener hängen  :?


----------



## roli_07 (29. Feb 2008)

Nun, das ist es eben. Meine "Veranschaulichung" mittels Geschäftsauto und Auftrag ist eine starke Vereinfachung. Die Anzahl von Figuren ist nach oben "nicht begrenzt". Des Weiteren muss ich auch *Tooltips *implementieren. Heisst, sobald ich über eine Linie oder eine andere Figur fahre, muss nach kurzer Zeit was angezegt werden. Darum reicht eben *mouseClicked* nicht. Und, wenn ich viele Linien habe, die in der Mitte zu einem Punkt alle "konvergieren", wird das Unterscheiden zwischen einzelnen Linien nicht mehr so einfach. 

Die Abstandberechnung ist an sich kein Problem. Jedoch muss beispielsweise berücksichtigt werden, dass die Gerade "unendlich" lang ist. Da ich eher mit "Strecken" arbeite, muss ich auch immer abfragen, ob die Strecke weiter geht oder nicht. Sonnst berechne ich den Abstand auch dann, wenn ich mich im Bereich befinde, in dem die Strecke gar nicht witer geht. 

Also, das sind meine Probleme. Wenn ich viele "Elemente" habe und dies alles "on the fly" berechnet werden muss, könnte es kritisch werden. 

Danke und Grusss


----------



## Marco13 (29. Feb 2008)

Nun, egal wie viele Objekte (Linien/Kreise) du hast: Wenn diese Objekte _zusätzlich_ noch den ganzen Ballast mit sich rumschleppen würden, der mit einer "Component" verbunden ist, wäre es vmtl. in jedem Fall deutlich langsamer, und mit Sicherheit EXTREM viel Speicher-fressender. Dass es um Strecken (und nicht um Geraden) geht, hattest du schon deutlich gesagt, aber das ist egal: Das wird ja alles vollkommen transparent in der "isHitByClick(Point position);"-Methode gemacht (die dann aber vielleicht "isHitByMouse(Point position);" heißen sollte  :? ). 

Mit den ToolTips hättest du mit Components vermutlich (!) sowieso ein Problem.... ein bißchen ASCIII-Art:

```
___________
|   ____    |
|  /    \   |
| /   ___\ _|_____
||   |\   | |     |
| \  |  \ / |     |
|  \_|__/ \X|     |
|____|______\     |
     |        \   |
     |          \ |
     |____________\
```
Dort, wo das X ist, würde die Component mit dem Kreis im Vordergrund liegen, aber das X liegt näher an der Linie - es gibt kaum eine vernünftige Möglichkeit, dort "rauszufinden" (oder auch zu beeinflussen) von welcher Comonent das ToolTip stammen soll, das dort angzeigt wird....


----------



## roli_07 (1. Mrz 2008)

Nun, da hast du allerdings recht. 

Danke.


----------

