2009-07-12 4 views
2

Ich habe mein Programm, das Rechtecke zeichnen kann. Ich habe zwei Probleme, die ich nicht lösen kann. Nachdem ich das Rechteck gezeichnet habe, bleibt es nicht stehen. Der einzige Code, den ich habe, löscht die Leinwand in unter Farbe, Repaint wird nur beim Ziehen der Maus aufgerufen. Warum, wenn ich die Maus loslasse oder meine Maus bewegt, wird meine Leinwand klar. Die zweite Sache ist nicht so ein Problem, aber etwas, das ich nicht herausfinden kann, wenn entweder die Höhe oder die Breite meines Rechtecks ​​negativ ist, ist das Rechteck in schwarz gefüllt.Wie zeichne ich ein Rechteck auf einem Java-Applet mit der Maus ziehen Ereignis und es bleiben

package pracpapp2; 


import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 

public class MouseTracker4July extends JFrame 
    implements MouseListener, MouseMotionListener { 


    private static final long serialVersionUID = 1L; 
    private JLabel mousePosition; 
    int x, y; 
    int x1, x2, y1, y2; 
    int w, h; 
    private JLabel recStart; 
    private JLabel recStop; 
    private JLabel cords; 
    // set up GUI and register mouse event handlers 
    public MouseTracker4July() 
    { 
     super("Rectangle Drawer"); 

     mousePosition = new JLabel(); 
     mousePosition.setHorizontalAlignment(SwingConstants.CENTER); 
     getContentPane().add(mousePosition, BorderLayout.CENTER); 


     JLabel text1 = new JLabel(); 
     text1.setText("At the center the mouse pointer's coordinates will be displayed."); 
     getContentPane().add(text1, BorderLayout.SOUTH); 

     recStart = new JLabel(); 
     getContentPane().add(recStart, BorderLayout.WEST); 

     recStop = new JLabel(); 
     getContentPane().add(recStop, BorderLayout.EAST); 

     cords = new JLabel(); 
     getContentPane().add(cords, BorderLayout.NORTH); 


     addMouseListener(this);  // listens for own mouse and 
     addMouseMotionListener(this); // mouse-motion events 

     setSize(800, 600); 
     setVisible(true); 
    } 

    // MouseListener event handlers 
    // handle event when mouse released immediately after press 
    public void mouseClicked(MouseEvent event) 
    { 
     mousePosition.setText("Clicked at [" + event.getX() + 
     ", " + event.getY() + "]"); 
    } 

    // handle event when mouse pressed 
    public void mousePressed(MouseEvent event) 
    { 

     mousePosition.setText("Pressed at [" +(x1 = event.getX()) + 
     ", " + (y1 = event.getY()) + "]"); 

     recStart.setText("Start: [" + x1 + 
     ", " + y1 + "]"); 
    } 

    // handle event when mouse released after dragging 
    public void mouseReleased(MouseEvent event) 
    { 
    mousePosition.setText("Released at [" +(x2 = event.getX()) + 
     ", " + (y2 = event.getY()) + "]"); 

    recStop.setText("End: [" + x2 + 
     ", " + y2 + "]"); 

    } 

    // handle event when mouse enters area 
    public void mouseEntered(MouseEvent event) 
    { 
     mousePosition.setText("Mouse entered at [" + event.getX() + 
     ", " + event.getY() + "]"); 
    } 

    // handle event when mouse exits area 
    public void mouseExited(MouseEvent event) 
    { 
     mousePosition.setText("Mouse outside window"); 
    } 

    // MouseMotionListener event handlers 
    // handle event when user drags mouse with button pressed 
    public void mouseDragged(MouseEvent event) 
    { 
     mousePosition.setText("Dragged at [" + (x = event.getX()) + 
     ", " + (y = event.getY()) + "]"); 
     // call repaint which calls paint 
     repaint(); 

    } 

    // handle event when user moves mouse 
    public void mouseMoved(MouseEvent event) 
    { 
     mousePosition.setText("Moved at [" + event.getX() + 
     ", " + event.getY() + "]"); 
    } 

    public void paint(Graphics g) 
    { 
     super.paint(g); // clear the frame surface 
     g.drawString("Start Rec Here", x1, y1); 
     g.drawString("End Rec Here", x, y); 

     w = x1 - x; 
     h = y1 - y; 
     w = w * -1; 
     h = h * -1; 

     g.drawRect(x1, y1, w, h); 

     cords.setText("w = " + w + ", h = " + h); 
    } 

    public static void main(String args[]) 
    { 
     MouseTracker4July application = new MouseTracker4July(); 
     application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 

} // end class MouseTracker 

Antwort

5

Ok, nachdem Ihre Frage neu zu lesen scheint, dass Sie weniger mehrere Rechtecke :)

Hier ist eine Lösung mit nur einer nach dem anderen (die nahe ist, was Sie für den Anfang hatte) haben könnte Betreuung :

import java.awt.BorderLayout; 
import java.awt.Graphics; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 
import java.awt.event.MouseMotionListener; 

import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.SwingConstants; 

public class MouseTracker4July extends JFrame implements MouseListener, MouseMotionListener { 

    private static final long serialVersionUID = 1L; 
    private final JLabel mousePosition; 
    int x1, x2, y1, y2; 
    int x, y, w, h; 
    private final JLabel recStart; 
    private final JLabel recStop; 
    private final JLabel cords; // set up GUI and register mouse event handlers 
    boolean isNewRect = true; 

    public MouseTracker4July() { 
     super("Rectangle Drawer"); 

     this.mousePosition = new JLabel(); 
     this.mousePosition.setHorizontalAlignment(SwingConstants.CENTER); 
     getContentPane().add(this.mousePosition, BorderLayout.CENTER); 

     JLabel text1 = new JLabel(); 
     text1.setText("At the center the mouse pointer's coordinates will be displayed."); 
     getContentPane().add(text1, BorderLayout.SOUTH); 

     this.recStart = new JLabel(); 
     getContentPane().add(this.recStart, BorderLayout.WEST); 

     this.recStop = new JLabel(); 
     getContentPane().add(this.recStop, BorderLayout.EAST); 

     this.cords = new JLabel(); 
     getContentPane().add(this.cords, BorderLayout.NORTH); 

     addMouseListener(this); // listens for own mouse and 
     addMouseMotionListener(this); // mouse-motion events 

     setSize(800, 600); 
     setVisible(true); 

    } 

// MouseListener event handlers // handle event when mouse released immediately after press 
    public void mouseClicked(final MouseEvent event) { 
     this.mousePosition.setText("Clicked at [" + event.getX() + ", " + event.getY() + "]"); 

     repaint(); 
    } 

// handle event when mouse pressed 
    public void mousePressed(final MouseEvent event) { 

     this.mousePosition.setText("Pressed at [" + (this.x1 = event.getX()) + ", " + (this.y1 = event.getY()) + "]"); 

     this.recStart.setText("Start: [" + this.x1 + ", " + this.y1 + "]"); 

     this.isNewRect = true; 

     repaint(); 
    } 

// handle event when mouse released after dragging 
    public void mouseReleased(final MouseEvent event) { 
     this.mousePosition.setText("Released at [" + (this.x2 = event.getX()) + ", " + (this.y2 = event.getY()) + "]"); 

     this.recStop.setText("End: [" + this.x2 + ", " + this.y2 + "]"); 

     repaint(); 
    } 

// handle event when mouse enters area 
    public void mouseEntered(final MouseEvent event) { 
     this.mousePosition.setText("Mouse entered at [" + event.getX() + ", " + event.getY() + "]"); 
     repaint(); 
    } 

// handle event when mouse exits area 
    public void mouseExited(final MouseEvent event) { 
     this.mousePosition.setText("Mouse outside window"); 
     repaint(); 
    } 

// MouseMotionListener event handlers // handle event when user drags mouse with button pressed 
    public void mouseDragged(final MouseEvent event) { 
     this.mousePosition.setText("Dragged at [" + (this.x2 = event.getX()) + ", " + (this.y2 = event.getY()) + "]"); // call repaint which calls paint repaint(); 

     this.isNewRect = false; 

     repaint(); 
    } 

// handle event when user moves mouse 
    public void mouseMoved(final MouseEvent event) { 
     this.mousePosition.setText("Moved at [" + event.getX() + ", " + event.getY() + "]"); 
     repaint(); 
    } 

    @Override 
    public void paint(final Graphics g) { 
     super.paint(g); // clear the frame surface 
     g.drawString("Start Rec Here", this.x1, this.y1); 
     g.drawString("End Rec Here", this.x2, this.y2); 

     int width = this.x1 - this.x2; 
     int height = this.y1 - this.y2; 

     this.w = Math.abs(width); 
     this.h = Math.abs(height); 
     this.x = width < 0 ? this.x1 
      : this.x2; 
     this.y = height < 0 ? this.y1 
      : this.y2; 

     if (!this.isNewRect) { 
      g.drawRect(this.x, this.y, this.w, this.h); 
     } 

     this.cords.setText("w = " + this.w + ", h = " + this.h); 

    } 

    public static void main(final String args[]) { 
     MouseTracker4July application = new MouseTracker4July(); 
     application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 

} // end class MouseTracker 
+0

Das ist genau das, was ich brauchte, ich wusste, dass ich in der Nähe war, ich konnte einfach nicht herausfinden, wie ich das Ding beenden sollte. Die math.abs ist cool, weil sie meine Breite und Höhe positiv hält. Danke vielmals. Noch eine Frage, ist alles "das". gute Form oder persönliche Vorliebe? Ich bin nur neugierig, weil ich nur einen JFrame benutze, ist es nicht überflüssig? Danke noch einmal. – Tyler

+0

Jedes Mal, wenn ich die Maus drehe, flackert es sehr stark, was durch das Überschreiben der paint() -Methode des Frames verursacht wird, wie ich bereits angedeutet habe. – camickr

+0

Persönlich würde ich sagen, dass die "diese" Verwendung ein bisschen Präferenz ist - es gibt andere, die militant widersprechen würden. Froh, dass ich Helfen kann. – javamonkey79

4

Sie müssen Ihre gezeichneten Elemente in einer Datenstruktur speichern und sicherstellen, dass jedes Element in der Struktur auf der Leinwand beim Repaint gemalt wird.

Außerdem müssen Sie jedes Ihrer Mausereignisse neu zeichnen.

Wie folgt: (Dies setzt voraus, dass Sie ALLE Rect's beibehalten möchten) - Sie können mit einem einzigen Rect arbeiten, indem Sie die Arraylist entfernen und durch eine einzelne rect-Instanz ersetzen.

import java.awt.BorderLayout; 
import java.awt.Graphics; 
import java.awt.Rectangle; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 
import java.awt.event.MouseMotionListener; 
import java.util.ArrayList; 

import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.SwingConstants; 

public class MouseTracker4July extends JFrame implements MouseListener, MouseMotionListener { 

    private static final long serialVersionUID = 1L; 
    private final JLabel mousePosition; 
    int x1, x2, y1, y2; 
    int w, h; 
    private final JLabel recStart; 
    private final JLabel recStop; 
    private final JLabel cords; // set up GUI and register mouse event handlers 
    private final ArrayList<Rectangle> rectangles = new ArrayList<Rectangle>(); 
    private boolean isNewRect = true; 

    public MouseTracker4July() { 
     super("Rectangle Drawer"); 

     this.mousePosition = new JLabel(); 
     this.mousePosition.setHorizontalAlignment(SwingConstants.CENTER); 
     getContentPane().add(this.mousePosition, BorderLayout.CENTER); 

     JLabel text1 = new JLabel(); 
     text1.setText("At the center the mouse pointer's coordinates will be displayed."); 
     getContentPane().add(text1, BorderLayout.SOUTH); 

     this.recStart = new JLabel(); 
     getContentPane().add(this.recStart, BorderLayout.WEST); 

     this.recStop = new JLabel(); 
     getContentPane().add(this.recStop, BorderLayout.EAST); 

     this.cords = new JLabel(); 
     getContentPane().add(this.cords, BorderLayout.NORTH); 

     addMouseListener(this); // listens for own mouse and 
     addMouseMotionListener(this); // mouse-motion events 

     setSize(800, 600); 
     setVisible(true); 

    } 

// MouseListener event handlers // handle event when mouse released immediately after press 
    public void mouseClicked(final MouseEvent event) { 
     this.mousePosition.setText("Clicked at [" + event.getX() + ", " + event.getY() + "]"); 

     repaint(); 
    } 

// handle event when mouse pressed 
    public void mousePressed(final MouseEvent event) { 

     this.mousePosition.setText("Pressed at [" + (this.x1 = event.getX()) + ", " + (this.y1 = event.getY()) + "]"); 

     this.recStart.setText("Start: [" + this.x1 + ", " + this.y1 + "]"); 

     repaint(); 
    } 

// handle event when mouse released after dragging 
    public void mouseReleased(final MouseEvent event) { 
     this.mousePosition.setText("Released at [" + (this.x2 = event.getX()) + ", " + (this.y2 = event.getY()) + "]"); 

     this.recStop.setText("End: [" + this.x2 + ", " + this.y2 + "]"); 

     Rectangle rectangle = getRectangleFromPoints(); 

     this.rectangles.add(rectangle); 

     this.w = this.h = this.x1 = this.y1 = this.x2 = this.y2 = 0; 
     this.isNewRect = true; 

     repaint(); 
    } 

    private Rectangle getRectangleFromPoints() { 
     int width = this.x1 - this.x2; 
     int height = this.y1 - this.y2; 
     Rectangle rectangle = new Rectangle(width < 0 ? this.x1 
      : this.x2, height < 0 ? this.y1 
      : this.y2, Math.abs(width), Math.abs(height)); 

     return rectangle; 
    } 

// handle event when mouse enters area 
    public void mouseEntered(final MouseEvent event) { 
     this.mousePosition.setText("Mouse entered at [" + event.getX() + ", " + event.getY() + "]"); 
     repaint(); 
    } 

// handle event when mouse exits area 
    public void mouseExited(final MouseEvent event) { 
     this.mousePosition.setText("Mouse outside window"); 
     repaint(); 
    } 

// MouseMotionListener event handlers // handle event when user drags mouse with button pressed 
    public void mouseDragged(final MouseEvent event) { 
     this.mousePosition.setText("Dragged at [" + (this.x2 = event.getX()) + ", " + (this.y2 = event.getY()) + "]"); // call repaint which calls paint repaint(); 

     this.isNewRect = false; 

     repaint(); 
    } 

// handle event when user moves mouse 
    public void mouseMoved(final MouseEvent event) { 
     this.mousePosition.setText("Moved at [" + event.getX() + ", " + event.getY() + "]"); 
     repaint(); 
    } 

    @Override 
    public void paint(final Graphics g) { 
     super.paint(g); // clear the frame surface 
     g.drawString("Start Rec Here", this.x1, this.y1); 
     g.drawString("End Rec Here", this.x2, this.y2); 

     Rectangle newRectangle = getRectangleFromPoints(); 
     if (!this.isNewRect) { 
      g.drawRect(newRectangle.x, newRectangle.y, newRectangle.width, newRectangle.height); 
     } 

     for(Rectangle rectangle : this.rectangles) { 
      g.drawRect(rectangle.x, rectangle.y, rectangle.width, rectangle.height); 
     } 

     this.cords.setText("w = " + this.w + ", h = " + this.h); 

    } 

    public static void main(final String args[]) { 
     MouseTracker4July application = new MouseTracker4July(); 
     application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 

} // end class MouseTracker 
+0

Dies ist mein erstes Mal, grafisch zu programmieren. Wie könnte ich das gesamte Rechteck speichern? Ich habe bereits die rechteckigen Teile (x, y, w, h) als int gespeichert, dann wird das Rechteck gezeichnet, aber es sind meine ganzen Zahlen, die ständig aktualisiert werden, ich bin nicht sicher, wie man sie in etwas statisches speichert, das gehalten werden kann auf der Leinwand. – Tyler

+0

Benutzerdefinierte Bemalung sollte auf einer JPanel oder JComponent erfolgen, nicht auf dem tatsächlichen JFrame und die paintComponent() -Methode sollte überschrieben werden, nicht die paint() -Methode. – camickr

+0

@camickr - Ich stimme zu, aber aus Gründen des Verständnisses des Problems weiß ich nicht, dass es Tyler in dieser Insistenz helfen wird (auf lange Sicht ja). – javamonkey79

1

Lesen Sie diese beiden Custom Painting Approaches. Ein Ansatz ist oben beschrieben und der zweite Ansatz zeigt, wie ein BufferedImage verwendet wird. Das für beide Ansätze verwendete Beispiel ermöglicht es Ihnen, dem Rahmen mehrere Rechtecke hinzuzufügen.

0

Wenn Sie in der Maus Zuhörer nicht einige Anzeigeinformationen kümmern, löschen Sie einfach alle "mousePosition.setText (...)", werden sie die unnötige repaint() callings führen.

Dann fügen Sie zwei Felder: "int rx, ry," Add/mehrere Methoden ändern, wie unten:

 public void mouseDragged(MouseEvent event) { 
//  mousePosition.setText("Dragged at [" + (x = event.getX()) + ", " 
//    + (y = event.getY()) + "]"); 
     // call repaint which calls paint 
     x = event.getX(); 
     y = event.getY(); 

     compRectPos(); 
     repaint(); 
    } 

    private void compRectPos() 
    { 
     rx = x1; 
     ry = y1; 

     w = x - x1; 
     h = y - y1; 

     if (w < 0) 
      rx += w; 
     if (h < 0) 
      ry += h; 

     w = Math.abs(w); 
     h = Math.abs(h); 

    } 

    public void paint(Graphics g) { 
     super.paint(g); // clear the frame surface 
     g.drawString("Start Rec Here", x1, y1); 
     g.drawString("End Rec Here", x, y); 

     g.drawRect(rx, ry, w, h); 

     cords.setText("w = " + w + ", h = " + h); 
    } 

Das einzige Problem, das ich gefunden wird, dass das Rechteck nicht angezeigt, wenn zuerst gezeichnet .

Verwandte Themen