2009-07-12 8 views
2

J'ai mon programme qui peut dessiner des rectangles. J'ai deux problèmes que je ne peux pas résoudre. Après avoir dessiné le rectangle, il ne restera pas. Le seul code que j'ai qui efface la toile sous la peinture, repeindre est seulement appelé sur la souris glisser. Pourquoi quand je lance la souris ou déplace la souris, ma toile est-elle claire? La deuxième chose n'est pas autant un problème, mais quelque chose que je ne peux pas comprendre, quand soit la hauteur ou la largeur de mon rectangle est négatif, le rectangle est rempli en noir.Comment dessiner un rectangle sur une applet Java en utilisant l'événement de glisser de la souris et le faire rester

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 

Répondre

5

Ok, après avoir relu votre question, il semble que vous pourriez occuper moins d'avoir plusieurs rectangles :)

Voici une solution avec une seule à la fois (ce qui est proche de ce que vous avez dû commencer) :

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

C'est exactement ce dont j'avais besoin, je savais que j'étais proche, je n'arrivais pas à comprendre comment finir la chose. Le math.abs est cool car il garde ma largeur et ma hauteur positives. Merci beaucoup. Une question de plus, est tout le "ceci". bonne forme ou préférence personnelle? Je suis juste curieux parce que puisque j'utilise seulement un JFrame n'est-ce pas redondant? Merci encore. – Tyler

+0

Il y a beaucoup de scintillement chaque fois que je fais glisser la souris, ce qui est dû au fait que je surcharge la méthode paint() du cadre comme je l'ai suggéré plus tôt. – camickr

+0

Personnellement, je dirais que l'utilisation de 'this' est un peu préférée - il y en a d'autres qui seraient en désaccord militairement. Heureux de vous aider. – javamonkey79

4

Vous devez stocker vos éléments dessinés dans une structure de données et vous assurer que chaque élément de la structure est peint dans la zone lors de la peinture.

De plus, vous devez ajouter repeindre à chacun de vos événements de souris.

Comme ceci: (ceci suppose que vous voulez garder TOUT rect) - vous pouvez aller avec un seul rect en éliminant l'arraylist et en remplaçant par une seule instance rect.

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

Ceci est ma première programmation graphique. Comment pourrais-je stocker le rectangle entier. J'ai déjà les parties rectangle (x, y, w, h) stockées en int, puis le rectangle est en train d'être dessiné, mais mes entiers sont constamment mis à jour, je ne sais pas comment les stocker pour quelque chose de statique sur la toile. – Tyler

+0

La peinture personnalisée doit être effectuée sur un JPanel ou JComponent, pas sur le JFrame réel et la méthode paintComponent() doit être redéfinie, pas la méthode paint(). – camickr

+0

@camickr - Je suis d'accord, mais pour comprendre le problème, je ne sais pas si cela aidera Tyler dans cette affaire (à long terme, oui). – javamonkey79

1

Lisez sur ces deux Custom Painting Approaches. Une approche est décrite ci-dessus et la seconde approche montre comment utiliser une image tamponnée. L'exemple utilisé pour les deux approches vous permet d'ajouter plusieurs Rectangles au cadre.

0

Si vous ne vous souciez pas des informations d'affichage, il suffit de supprimer tous les « mousePosition.setText (...) » dans les écouteurs de la souris, ils le repeindre inutiles entraîner() appels.

Ensuite, ajoutez deux champs: « int rx, ry, », ajouter/modifier plusieurs méthodes comme ci-dessous:

 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); 
    } 

Le seul problème que je trouve est que le rectangle ne semble pas lors de la première tirée .

Questions connexes