2010-12-30 9 views
2

Ich habe Probleme beim Zeichnen von Rechtecken an der Mausposition. Das gemalte Rechteck liegt hinter dem Mauszeiger, wenn die Maus bewegt wird. Gibt es eine Möglichkeit sicherzustellen, dass sich das Rechteck genau auf der Maus bewegt und nicht hinterherhinkt?Verzögerung beim Zeichnen von Objekten zum Bewegen mit der Maus

Hier ist ein kleines Beispiel, obwohl, da dies nur ein einzelnes Rechteck ist, die Verzögerung sehr gering ist, aber es ist da. In dem größeren Programm male ich eine Menge von ihnen auf einmal, obwohl ich nur die eine bewege.

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseMotionListener; 

import javax.swing.*; 

public class MouseTest { 
    JFrame window; 
    DrawPanel content; 

    public MouseTest(){ 
     window = new JFrame("Test"); 
     content = new DrawPanel(); 
     window.setContentPane(content); 
     window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     window.setVisible(true); 
     window.pack(); 
    } 

    public static void main (String[] args){ 
     MouseTest test = new MouseTest(); 
    } 

    private class DrawPanel extends JPanel implements MouseMotionListener { 
     int mouseX; 
     int mouseY; 

     private DrawPanel(){ 
      setBackground(Color.BLUE); 
      setPreferredSize(new Dimension(400,400)); 
      addMouseMotionListener(this); 
     } 

     public void paintComponent(Graphics g){ 
      super.paintComponent(g); 
      g.setColor(Color.RED); 
      g.fillRect(mouseX, mouseY, 20, 20); 
     } 

     @Override 
     public void mouseDragged(MouseEvent e) { 
      // TODO Auto-generated method stub 

     } 

     @Override 
     public void mouseMoved(MouseEvent e) { 
      mouseX = e.getX(); 
      mouseY = e.getY(); 
      repaint(); 

     } 
    } 

} 
+0

ist die Option "doppelt gepuffert" Standard? ... nur dies auf einmal zu beweisen –

+0

konnte nicht Ihre Verzögerung reproduzieren. – Favonius

Antwort

0

Auch wenn das mehr Arbeit ist, empfehle ich für jede solche Aufgabe, dass Sie nur die Region ungültig machen und neu streichen, die sich geändert hat. Dies wird viele Zyklen sparen (stellen Sie sich vor, dass Sie immer den kompletten Hintergrund zeichnen ...).

Sie werden große Verbesserungen sehen.

EDIT

ich es getestet mich mit diesem Beispiel

public void mouseMoved(MouseEvent e) { 
     repaint(mouseX, mouseY, 20, 20); 
     mouseX = e.getX(); 
     mouseY = e.getY(); 
     repaint(mouseX, mouseY, 20, 20); 
    } 

und müssen die Verbesserungen sind ein wenig akademisch (zumindest für meinen Computer) zugeben. Wie auch immer, diese Technik sollte auf komplexere Lackverfahren verwendet werden .. (wo man schließlich Verbesserungen sehen)

EDIT

Und mehr Cheat: Wenn Sie immer noch die Diskrepanz zwischen Wenigsten, wo Sie denken, der Cursor ist und was Das System denkt, versuchen Sie, den Cursor (http://www.java2s.com/Code/Java/2D-Graphics-GUI/HidethemecursoruseusetransparentGIFasthecursor.htm) zu deaktivieren, um dem Benutzer eine bessere Rückmeldung zu geben.

+0

Danke für die Hinweise, die ganz gut funktionieren! – weichsem

2

Das erste, was zu tun ist, bewegen Sie alle Ihre Swing/AWT-Code in den EDT. In Ihrer Anwendung ist es Mai egal, aber es ist eine gute Gewohnheit, in zu bekommen.

Ich konnte jedoch nicht Ihre Verzögerung mit beiden Ansatz reproduzieren.

public static void main (String[] args) 
{ 
    SwingUtilities.invokeLater(
     new Runnable() 
     { 
      public void run() 
      { 
       MouseTest test = new MouseTest(); 
      } 
     }); 
} 

Siehe this article Weitere Informationen zu Swing-Threading.

+0

Danke für den Link und den Code, ich werde das untersuchen – weichsem

1

Vielleicht weg davon, aber wenn Sie sagen "Lag hinter" meinst du der Cursor ist nicht in der Mitte des Rechtecks? Ihr Code weist den Cursor auf die obere linke Ecke des Rechtecks, Sie müssen ihn versetzen, um ihn zu zentrieren.

+0

Nein, ich wollte nur, dass der Cursor immer auf dem obersten Punkt sein soll und nicht die linke obere Ecke des Rechtecks ​​manchmal hinter den Cursor fallen. – weichsem

0

Das Rechteck bleibt zurück, weil Ihre Klasse jedes Bewegungsereignis verarbeitet. Wenn nur das letzte Ereignis verarbeitet wird, ist das Rechteck auf dem neuesten Stand (obwohl es große Sprünge in der Position haben könnte). Eine Möglichkeit besteht darin, einen separaten Thread auszuführen, der das Rechteck basierend auf der aktuellen Mausposition zeichnet, die von der mouseMoved() -Methode aktualisiert wird. Sie müssen den Zugriff auf die Mauspositionsvariable synchronisieren.

+0

Danke, ich werde es versuchen. – weichsem

Verwandte Themen