Prüfen ob 2 JLabel übereinander liegen. Performance Problem.

tschero

Aktives Mitglied
Hi Leute,

bei einer Drag and Drop Aktion möchte ich folgendes prüfen.

Wenn sich die aufgenommene DragKomponente(JLabel) über einer gültigen DropKomponente(JLabel) befindet, soll diese dort liegenbleiben.

Ich speichere derzeit von allen DropKomponenten die Fläche(jew. als Point) in einer LinkedList<Point>

Java:
/**
     * Speichert alle Drop Komponenten der Seite in einer LinkedList<JComponent> llDropComponents
      * Speichert die gesamte Flaeche der Komponente jew. als Point in einer LinkedList<Point> llDropComponentPoints
     * fertig
     */
    private void saveDropTargets()
    {
//        System.out.println("drin in saveDropTargets");

    for(Component comp : myJLayeredPane.getComponents())
    {
        //casten auf JComponent ist wichtig
        JComponent target = (JComponent)comp;

        if(target.getName().contains("drop_target_"))
        {
//                System.out.println("Name der Komponente = : " +target.getName());
            llDropComponents.add(target);
            for(int i=0; i<target.getWidth(); ++i)
            {
                for(int j=0; j<target.getHeight(); ++j)
                {//
                    llDropComponentPoints.add(new Point(target.getX()+i, target.getY()+j));
                }
            }
        }
    }
}

Das funktioniert auch gut.

Wie kann ich den jetzt am besten die gleiche Aktion mit den DRAGKOMPONENTEN durchführen.
Ein dauerhaftes ändern während des ziehens ist zu Unperformant, um nicht zu sagen funktioniert nicht.

Java:
private void dropTarget(MouseEvent e)
    {
        //zu verwendende Drag Komponente. Diese kommt aus dem Event e.
        JComponent comp = (JComponent)e.getComponent().getComponentAt(e.getPoint());

        //erzeugen eines ListIterators um durch die Liste mit DropKomponenten zu iterieren
        ListIterator li = llDropComponents.listIterator();

        while(li.hasNext())
        {
            JLabel target = (JLabel) li.next();
//
           System.out.println(target.getName());
            System.out.println(target.getBounds());
            
            //Hier soll die Pruefung stattfinden
            //pruefe ob sich ein DropTarget in Reichweite befindet

            //wenn ja, lege ab und schnappe ein

            //wenn nicht wandere zurueck
//
        }
    }

Über nen kleinen Denkanstoß würde ich mich freuen.

gruß
tschero
 
rechne nicht mit jedem einzelnen Pixel. Die Components sind doch alle quadratisch. Du brauchst einfach nur x/y/width/height vergleichen, das spart enorm viel performance. Und selbsts wenn sie nicht quadratisch wären gibt es immernoch tausendmal performantere algorithmen als die "bruteforce"-Methode die du da versuchtst.
 
Zuletzt bearbeitet:
Hi,

genau für diese "bruteforce" Methode suche ich eine elegantere Lösung.
Wenn ich (x,y,width, height) vergleiche bekomme ich doch nur das gewünschte Ergebnis wenn die Komponenten "direkt" übereinander liegen.

Ich möchte das die DragKomponente "einschnappt" wenn sie die DropKomponente auch nur berührt. Oder bin ich gerade blind?



Gruß
tschero
 
Hi,

ich werde mal die Position des Mauszeigers dazu verwenden anstatt sämtliche Points des Drag Objektes.
Das sollte funktionieren da das Drag Objekt beim Aufnehmen immer mittig unter dem Mauszeiger einrastet.


Contains nutze ich schon, intersect schaue ich mir mal an, das kenne ich noch nicht.

Vielen Dank schon mal.

Gruß
tschero
 
So,

jetzt hab ich´s.

Java:
/**
     * diese Funktion legt die uebergebene Komponente auf der Buehne ab.
     * Wenn sich die Komponente ueber einem regulaeren DropTarget befindet, wird diese dort abgelegt.
     * Ansonsten bewegt sich die Komponente wieder auf den Punkt zurueck, wo sie aufgenommen wurde.
     * @param e MouseEvent aus MouseReleased
     */
    private void dropTarget(MouseEvent e)
    {
        //zu verwendende Drag Komponente. Diese kommt aus dem Event e.
        JComponent dragTarget = (JComponent)e.getComponent().getComponentAt(e.getPoint());

        //erzeugen eines ListIterators um durch die Liste mit DropKomponenten zu iterieren
        ListIterator li = llDropComponents.listIterator();

        //definieren der Punkte
        //p1 links oben p2 rechts oben p3 rechts unten p4 links unten
        Point p1 = new Point(dragTarget.getX(), dragTarget.getY());
        Point p2 = new Point(dragTarget.getX() + dragTarget.getWidth(), dragTarget.getY());
        Point p3 = new Point(dragTarget.getX() + dragTarget.getWidth(), dragTarget.getY() + dragTarget.getHeight());
        Point p4 = new Point(dragTarget.getX(), dragTarget.getY() + dragTarget.getHeight());

        //Liste durchiterieren
        while(li.hasNext())
        {
            //DropKomponente
            JLabel target = (JLabel) li.next();
    //
    //           System.out.println(target.getName());
               //links oben
            if((p1.getX() > target.getX() && p1.getX() < target.getX()+target.getWidth())
                &&
                (p1.getY() > target.getY() && p1.getY() < target.getY()+target.getHeight())
              )
            {
                System.out.println("drauf links oben");
                break;

            }
            //rechts oben
            else if((p2.getX() > target.getX() && p2.getX() < target.getX()+target.getWidth())
                &&
                (p2.getY() > target.getY() && p2.getY() < target.getY()+target.getHeight())
              )
            {
                System.out.println("drauf rechts oben");
                break;

            }
            //rechts unten
            else if((p3.getX() > target.getX() && p3.getX() < target.getX()+target.getWidth())
                &&
                (p3.getY() > target.getY() && p3.getY() < target.getY()+target.getHeight())
              )
            {
                System.out.println("drauf rechts unten");
                break;

            }
            //rechts unten
            else if((p3.getX() > target.getX() && p3.getX() < drop_target_1.getX()+drop_target_1.getWidth())
                &&
                (p3.getY() > target.getY() && p3.getY() < drop_target_1.getY()+drop_target_1.getHeight())
              )
            {
                System.out.println("drauf rechts unten");
                break;

            }//links unten
            else if((p4.getX() > target.getX() && p4.getX() < target.getX()+target.getWidth())
                &&
                (p4.getY() > target.getY() && p4.getY() < target.getY()+target.getHeight())
              )
            {
                System.out.println("drauf links unten");
                break;

            }
            else
            {
                System.out.println("else");
                moveDragComponentToStartPoint(dragTarget);
            }
        }
    }

Funktioniert prima mit rechteckigen JLabels.

Gruß
tschero
 

Neue Themen


Zurück
Oben