2009-12-10 5 views
0

J'essaie d'avoir un cercle sur l'écran, puis lorsque l'utilisateur clique sur INSIDE dans le cercle, activer la possibilité pour eux de faire glisser le cercle où la souris va pendant qu'elle est pressée.Glisser un cercle sur un JFrame

Ceci est le code que j'ai jusqu'ici, le glisser fonctionne, mais il permet à l'utilisateur de faire glisser sans qu'ils pressent l'intérieur du cercle, juste quand n'importe où sur l'écran est pressé.

J'espère que je ne suis pas trop confus

est ici le code que j'ai, s'il vous plaît si quelqu'un pourrait me dire le code qui doit être corrigé, il me sauvera plus heures.

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

public class DragCircle extends JFrame { 
    private static final long serialVersionUID = 1L; 

    public static int size = 400; 

    public static int r = 10; 

    private int x; 

    private int y; 

    private int cX; 

    private int cY; 

    private int dX; 

    private int dY; 

    private MouseHandler mh; 

    boolean isCircleClicked = false; 

    public static void main(String[] args) { 
     DragCircle c1 = new DragCircle(); 
     c1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    } 

    public DragCircle() { 

     super("Drag circle"); 

     cX = r + 100; 
     cY = r + 100; 

     mh = new MouseHandler(); 
     addMouseListener(mh); 
     addMouseMotionListener(mh); 

     setSize(size, size); 
     setVisible(true); 

    } 

    public void paint(Graphics g) { 
     super.paint(g); 
     g.setColor(Color.RED); 
     g.fillOval(cX, cY, r * 2, r * 2); 

    } 

    private class MouseHandler extends MouseAdapter implements 
      MouseMotionListener { 
     public void mousePressed(MouseEvent me) 

     { 

      if ((cX - me.getX()) * (cX - me.getX()) + (cY - me.getY()) 
        * (cY - me.getY()) < r * r) { 
       isCircleClicked = true; 
      } 
     } 

     public void mouseDragged(MouseEvent me) { 
      if (isCircleClicked) { 

       x = me.getX() - dX; 
       y = me.getY() - dY; 
       cX = x + r; 
       cY = y + r; 
       repaint(); 
      } 
     } 

     public void mouseReleased(MouseEvent e) { 
      isCircleClicked = false; 
     } 

    } 

} 
+0

vous avez raison à propos de mouseReleased, je vais le mettre dedans, et il a compilé comme ceci. – Madison

Répondre

0

La structure de votre programme est erronée. Vous ne devez jamais remplacer la méthode paint (...) d'un JFrame. C'est un vieux truc AWT et ne devrait pas être utilisé avec Swing.

Lire la section du tutoriel Swing sur Custom Painting pour un exemple de la façon correcte de faire de la peinture. Les bases sont de remplacer la méthode paintComponent (...) d'un JPanel, puis d'ajouter le panneau au volet de contenu du cadre. En ce qui concerne votre question, une meilleure solution consiste à créer un objet Elllipse2D pour représenter votre cercle. Ensuite, la peinture personnalisée peut utiliser la méthode drawShape (...) de la classe Graphics2D. Ensuite, dans votre code MouseListener, vous pouvez utiliser la méthode Shape.contains (...) pour voir si la souris a été cliquée sur le cercle.

+0

Hit-tester un cercle est trivial cependant et le code de test de frappe me semble correct. Je suppose que cela ne se produit que si l'OP déplace d'abord le cercle et que * puis * essaie de le faire glisser (où 'isCircleClicked' est toujours défini sur' true', ce qui déplace le cercle.) – Joey

+0

Apparemment ce n'est pas trivial car vous avez dû modifier le code pour prendre en compte les coordonnées correctes C'est pourquoi il est plus simple d'utiliser un objet Shape afin de ne pas avoir à vous soucier des détails et vous invoquez simplement la méthode contains (...) J'essaie de recommander des solutions qui utilisent l'API plutôt que de réinventer la roue – camickr

2

Votre un problème avec

public void mouseDragged(MouseEvent me) { 
    if (isCircleClicked = true) { 

Ce que vous faites ici est la mise isCircleClicked à true chaque fois que vous faites glisser la souris. Aussi cette déclaration évalue à true qui est pourquoi vous pouvez traîner n'importe où et déplacer le cercle. Changez cela en

if (isCircleClicked) { 

et ça devrait aller.

Le problème suivant est que vous ne réinitialisez jamais isCircleClicked à false. Vous devriez faire cela soit dans mouseReleased ou de changer votre mousePressed comme suit:

public void mousePressed(MouseEvent me) { 
    isCircleClicked = 
     (cX - me.getX()) * (cX - me.getX()) + 
     (cY - me.getY)) * (cY - me.getY()) < r * r; 
} 

qui établira isCircleClicked en conséquence.

Il reste encore quelque chose à faire. Dans la forme actuelle, vous devez commencer à glisser vers le coin supérieur gauche du point central, comme illustré ci-dessous:

 
+------+ 
|  | 
| .-|-. 
| /| \ 
+------+ | 
    \ /
    '-_-' 

Ceci est à cause de votre dessin: fillOval prend un coin supérieur gauche de l'ovale et une largeur et hauteur du rectangle englobant. C'est pas le point central et les diamètres respectifs. Par conséquent vous devez adapter son comme suit:

g.fillOval(cX - r, cY - r, r * 2, r * 2); 

Notez le décalage par le rayon vers la gauche et le haut.

En outre, votre code de glissement nécessite un peu plus de travail.Vous supposez actuellement que l'utilisateur fait glisser le centre du centre. Ce que vous devez faire est de sauvegarder les coordonnées du clic de la souris et ensuite déplacer le cercle en fonction du mouvement de la souris par rapport au dernier point. Actuellement, vous vous déplacez par rapport au centre du cercle, donc pour que le mouvement soit agréable, vous devez commencer à traîner exactement au centre du cercle. Je vais laisser cela comme un exercice pour vous :-)

En outre, votre classe d'écouteurs hérite déjà de MouseAdapter, vous n'avez donc pas besoin d'implémenter explicitement MouseMotionListener puisque MouseAdapter l'implémente déjà.

+0

Je viens de mettre à jour le code .. J'ai édité le post pour montrer ce que j'ai fait .. mais son action bizarre, quand je l'exécute le cercle n'est pas traîné du tout – Madison

+0

Essayez de faire glisser un peu Ça marche pour moi, maintenant je dois juste savoir * pourquoi * ça ne frappe pas le cercle correctement – Joey

+0

J'ai trouvé le problème – Joey

Questions connexes