Achsenskalierung in Koordinatensystem hängt Programm auf

CptK

Bekanntes Mitglied
Hallo, ich habe folgenden MouseMotionListner, der mir die Achsen eines Koordinatensystems bei gedrückter Maus skalieren soll:
Java:
addMouseMotionListener(new MouseMotionAdapter() {
            @Override
            public void mouseDragged(MouseEvent e) {
                setCursor(new Cursor(Cursor.NE_RESIZE_CURSOR));
                startPos = (startPos == null) ? e.getPoint() : startPos;
                currentPos = e.getPoint();
              
                int distX = (currentPos.x - startPos.x) / 50;
                int distY = (currentPos.y - startPos.y) / 50;
              
                CoordinateSystemSettings.scaleX = (CoordinateSystemSettings.scaleX
                        + distX > CoordinateSystemSettings.scaleMax) ? CoordinateSystemSettings.scaleMax
                                : CoordinateSystemSettings.scaleX + distX;
                CoordinateSystemSettings.scaleX = (CoordinateSystemSettings.scaleX < CoordinateSystemSettings.scaleMin)
                        ? CoordinateSystemSettings.scaleMin
                        : CoordinateSystemSettings.scaleX;

                CoordinateSystemSettings.scaleY = (CoordinateSystemSettings.scaleY
                        + distY > CoordinateSystemSettings.scaleY) ? CoordinateSystemSettings.scaleMax
                                : CoordinateSystemSettings.scaleY + distY;
                CoordinateSystemSettings.scaleX = (CoordinateSystemSettings.scaleY < CoordinateSystemSettings.scaleMin)
                        ? CoordinateSystemSettings.scaleMin
                        : CoordinateSystemSettings.scaleY;

                repaint();
            }
        });

Das Problem ist nur, dass der sehr viele, wohl zu viele Berechnungen vornimmt und sich mein Programm immer aufhängt. Wie würde man so was effektiver gestalten?
 

Robert Zenz

Top Contributor
Ich habe die Swing-Event-Loop nicht mehr im Kopf, aber ich glaube "mouseDragged" wird *oft* gefeuert. Wenn du dann jedes mal ein repaint() machst, bleibt effektiv das gesamte Swing System stehen. Was eine bessere Variante waere, ist wenn du das Ereignis annimmst, und dein Update dann "spaeter" machst. Hierfuer gibt es SwingUtilities.invokeLater(Runnable) welches den Runnable am *Ende* der Swing Event-Verarbeitung ausfuehrt. Ich habe die Regel nicht mehr ganz im Kopf, aber ich glaube die Swing-Event-Loop muss leerlaufen damit dann dieser Runnable ausgefuehrt wird. Also in etwa so:

Java:
private volatile boolean udpateQueued = false;

private void performUpdate() {
    // TODO Logic of the UI update goes here.
    updateQueued = false;
}

// Inside the MouseMotionListener.mouseDragged
if (!updateQueued) {
    updateQueued = true;
    SwingUtilities.invokeLater(this::performUpdate);
}

Eventuell kannst du auch schon viel gewinnnen wenn du einfach nur das "repaint" auf die Art und Weise hinten anstellst.

Java:
// Inside the MouseMotionListener.mouseDragged
// TODO Update logic goes here.
if (!updateQueued) {
    updateQueued = true;
    SwingUtilities.invokeLater(this::repaint);
}

Man muss sich bei solchen Sachen ein wenig in Swing einlesen, damit man mit der Event-Loop richtig umgeht.
 

mrBrown

Super-Moderator
Mitarbeiter
Ich habe die Swing-Event-Loop nicht mehr im Kopf, aber ich glaube "mouseDragged" wird *oft* gefeuert. Wenn du dann jedes mal ein repaint() machst, bleibt effektiv das gesamte Swing System stehen. Was eine bessere Variante waere, ist wenn du das Ereignis annimmst, und dein Update dann "spaeter" machst. Hierfuer gibt es SwingUtilities.invokeLater(Runnable) welches den Runnable am *Ende* der Swing Event-Verarbeitung ausfuehrt. Ich habe die Regel nicht mehr ganz im Kopf, aber ich glaube die Swing-Event-Loop muss leerlaufen damit dann dieser Runnable ausgefuehrt wird. Also in etwa so:

[...]

Eventuell kannst du auch schon viel gewinnnen wenn du einfach nur das "repaint" auf die Art und Weise hinten anstellst.

[...]

Man muss sich bei solchen Sachen ein wenig in Swing einlesen, damit man mit der Event-Loop richtig umgeht.

Das dürfte effektiv keine wirkliche Verbesserung bewirken. In mouseDragged passiert aktuell nicht wirklich mehr als das Repaint-Event in die Queue zu legen, da repaint() nicht direkt neu zeichnet, die Berechnung ist aus Perfomance-Sicht ja irrelevant.


Man müsste die Änderungen in mouseDragged puffern, und erst nach X Änderungen bzw X Zeiteinheiten neu zeichnen lassen. In etwa wie dein erster Vorschlag, nur würde der in der Form auch einige MouseDragged-Events überspringen.


@UnknownInnocent: das langsame ist in deinem Fall das Neuzeichnen – dort müsstest du ansetzen, am ehesten in dem du teure Teile identifizierst und wenn möglich reduzierst oder sogar ganz vermeidest. Da hilft entweder genaues Draufschauen oder Nutzung eines Profilers :) Oder eben Events in mouseDragged puffern, dürfte aber schnell relativ komplex sein, und im Gegensatz zu einer generellen Optimierung hat das dann nur in diesem speziellen Fall einen Effekt.
 

CptK

Bekanntes Mitglied
Das dürfte effektiv keine wirkliche Verbesserung bewirken. In mouseDragged passiert aktuell nicht wirklich mehr als das Repaint-Event in die Queue zu legen, da repaint() nicht direkt neu zeichnet, die Berechnung ist aus Perfomance-Sicht ja irrelevant.


Man müsste die Änderungen in mouseDragged puffern, und erst nach X Änderungen bzw X Zeiteinheiten neu zeichnen lassen. In etwa wie dein erster Vorschlag, nur würde der in der Form auch einige MouseDragged-Events überspringen.


@UnknownInnocent: das langsame ist in deinem Fall das Neuzeichnen – dort müsstest du ansetzen, am ehesten in dem du teure Teile identifizierst und wenn möglich reduzierst oder sogar ganz vermeidest. Da hilft entweder genaues Draufschauen oder Nutzung eines Profilers :) Oder eben Events in mouseDragged puffern, dürfte aber schnell relativ komplex sein, und im Gegensatz zu einer generellen Optimierung hat das dann nur in diesem speziellen Fall einen Effekt.
Okay das klingt kompliziert.... ^^
Ich habe das jetzt anders gelöst: Ich habe eine Menüleiste mit Schiebereglern für die Skalierung eingefügt, das funktioniert bisher einwandfrei.

Beim MouseMotionListner hätte ich ja gerne auch eine Vorschau auf dem Screen, wenn ich da hin und her ziehe, allerdings muss das nicht bei jeder Berechnung sein. Wie effektiv wäre es, wenn ich sage, ich rufe repaint() nur auf, wenn ich vorher eine Strecke x mit der Maus zurückgelegt habe, wobei das dann nach jedem repaint wieder von vorne gezählt wird?
 
G

Gelöschtes Mitglied 65838

Gast
du könntest einfach eine scrollbar einbauen und mit deren property die zwischen 0 und 1 liegt die skalierung durchführen anstatt auf dem koordinaten system
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
M ist das Koordinatensystem von Zeichenebene und Mouseposition verschoben ? Java Basics - Anfänger-Themen 1
H Koordinatensystem Java Basics - Anfänger-Themen 0
T Koordinatensystem zeichnen - Variablen merken? Quadratische Funktion zeichnen? Java Basics - Anfänger-Themen 5
D Koordinatensystem dynamisch anpassen Java Basics - Anfänger-Themen 17
D Koordinatensystem Java Basics - Anfänger-Themen 4
D Berechnung des Abstandes von zwei Punkten in einem Koordinatensystem Java Basics - Anfänger-Themen 14
Z Koordinatensystem zur Roboterorientierung Java Basics - Anfänger-Themen 7
P anordnung in einem koordinatensystem Java Basics - Anfänger-Themen 7
K Koordinatensystem Java Basics - Anfänger-Themen 3
M Koordinatensystem erstellen Java Basics - Anfänger-Themen 2
A koordinatensystem Java Basics - Anfänger-Themen 3
S Anfängerproblem: JButton und Raster/Koordinatensystem Java Basics - Anfänger-Themen 14
berserkerdq2 Spiel hängt sich immer in der 4 Runde auf, obwohl ich jede Runde das gleiche mache Java Basics - Anfänger-Themen 1
D GUI hängt Java Basics - Anfänger-Themen 5
N httpclient - Verbindung hängt ? Java Basics - Anfänger-Themen 13
Fishmeaker Methoden mit Methoden aufrufen - Programm hängt sich auf Java Basics - Anfänger-Themen 5
Lord.Djerun (Netbeans) Bei TimeUnit.Seconds,Sleep() hängt sich das komplette Programm auf.. Java Basics - Anfänger-Themen 8
P Eingabeaufforderung hängt sich auf Java Basics - Anfänger-Themen 2
S Programm hängt sich auf Java Basics - Anfänger-Themen 2
D Programm hängt evtl. Deadlock? Java Basics - Anfänger-Themen 8
J JFRAME hängt sich auf Java Basics - Anfänger-Themen 12
O java.util.Scanner hängt sich auf Java Basics - Anfänger-Themen 5
R Netbeans hängt sich beim profilen auf Java Basics - Anfänger-Themen 4
P BlueJ hängt sich beim compilen auf Java Basics - Anfänger-Themen 9
F Primitiver Lucas-Lehmer-Test hängt sich auf Java Basics - Anfänger-Themen 7
S JDK hängt beim Ausführen von Dateien Java Basics - Anfänger-Themen 13
R JFileChooser hängt java Programm auf Java Basics - Anfänger-Themen 6
O Editor hängt sich auf Java Basics - Anfänger-Themen 21
T BufferedReader oder Prozess, wer hängt sich auf? Java Basics - Anfänger-Themen 6
D Runtime Prozeß hängt sich auf. in der Kommandozeile gehts Java Basics - Anfänger-Themen 5
G GUI hängt sich auf! Java Basics - Anfänger-Themen 20
W sleep "hängt" bei vielen Threads Java Basics - Anfänger-Themen 2
G Compiler hängt schon wieder Java Basics - Anfänger-Themen 14

Ähnliche Java Themen


Oben