2017-07-19 4 views
0

J'essaye de dessiner un polygone en javafx en ajoutant à son tableau de coordonnées de la souris. Mon problème est que je ne sais pas comment l'arrêter quand je clique sur quelque chose d'autre à partir du clic gauche de la souris.Dessiner un polygone dans javafx

Polygon polygon = new Polygon(); 
rootPane.setOnMouseClicked((MouseEvent mouseEvent) -> { 
    do { 
     polygon.getPoints().addAll(mouseEvent.getX(),mouseEvent.getY()); 
    } while(mouseEvent.getButton().equals(mouseEvent.isSecondaryButtonDown()));  
}); 
rootPane.getChildren().add(polygon); 
+0

Pour clarifier, le code que vous passez dans un gestionnaire d'événements (tel que 'onMouseClicked') est exécuté * chaque fois que l'événement se produit. Vous n'avez pas besoin d'une boucle ici. –

Répondre

2

Vous pouvez créer une référence à un polygone. Si c'est le premier clic, le polygone sera null, créez-en un nouveau et ajoutez-le à votre volet. Ensuite, continuez à ajouter des points jusqu'à ce que vous obteniez un clic droit, auquel point vous venez de remettre le polygone à null, de sorte que le clic gauche suivant recommence un nouveau polygone.

SSCCE:

import javafx.application.Application; 
import javafx.scene.Scene; 
import javafx.scene.input.MouseButton; 
import javafx.scene.layout.Pane; 
import javafx.scene.paint.Color; 
import javafx.scene.shape.Polygon; 
import javafx.stage.Stage; 

public class DrawPolygon extends Application { 

    private Polygon currentPolygon ; 

    @Override 
    public void start(Stage primaryStage) { 
     Pane rootPane = new Pane(); 
     rootPane.setMinSize(600, 600); 
     rootPane.setOnMouseClicked(e -> { 
      if (e.getButton() == MouseButton.PRIMARY) { 
       if (currentPolygon == null) { 
        currentPolygon = new Polygon(); 
        currentPolygon.setStroke(Color.BLACK); 
        rootPane.getChildren().add(currentPolygon); 
       } 
       currentPolygon.getPoints().addAll(e.getX(), e.getY()); 
      } else { 
       currentPolygon = null ; 
      } 
     }); 
     Scene scene = new Scene(rootPane); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 

Vous pouvez jouer avec différentes idées autour de ce pour obtenir différentes expériences utilisateur, par exemple

rootPane.setOnMouseClicked(e -> { 
     if (e.getButton() == MouseButton.PRIMARY) { 
      if (currentPolygon == null) { 
       currentPolygon = new Polygon(); 
       currentPolygon.getPoints().addAll(e.getX(), e.getY()); 
       currentPolygon.setStroke(Color.BLACK); 
       rootPane.getChildren().add(currentPolygon); 
      } 
      currentPolygon.getPoints().addAll(e.getX(), e.getY()); 
     } else { 
      currentPolygon = null ; 
     } 
    }); 
    rootPane.setOnMouseMoved(e -> { 
     if (currentPolygon != null) { 
      currentPolygon.getPoints().set(currentPolygon.getPoints().size()-2, e.getX()); 
      currentPolygon.getPoints().set(currentPolygon.getPoints().size()-1, e.getY()); 
     } 
    }); 
1

Le problème est que votre code est bloqué dans un seul événement. Même lorsque vous déplacez la souris ou relâchez le bouton de la souris, les valeurs de l'instance d'événement avec laquelle vous travaillez ne vont pas changer.

Considérez l'événement comme un état unique. Quand quelque chose d'important arrive (dans votre cas, un clic de souris est cliqué), javafx appellera votre mouseEventHandler en utilisant une instance MouseEvent avec l'état de la souris à ce moment. Lorsque vous cliquez à nouveau, javafx créera une nouvelle instance avec de nouvelles valeurs et appellera à nouveau le gestionnaire d'événements. Pour que cela fonctionne, vous avez besoin d'un autre événement de souris (ou modifiez-le légèrement afin de définir un seul point sur un seul clic de souris). Vous devez perdre la boucle while (infinie) car elle bloque à la fois EventThread et ne fonctionne pas pour les choses dont vous avez besoin. Donc, quelque chose comme ça pourrait fonctionner un peu mieux.

// this will add a point for every (secondary)mousebutton click 
rootPane.setOnMouseClicked((MouseEvent me) -> { 
    if(me.isSecondaryButtonDown()) 
     polygon.getPoints().addAll(me.getX(),me.getY()); 
    }); 

// this will add a point for every mousemovement while the secondary mousebutton is down. 
rootPane.setOnMouseMoved((MouseEvent) me -> { 
    if(me.isSecondaryButtonDown()) 
     polygon.getPoints().addAll(me.getX(),me.getY()); 
}); 

Maintenant, il y a un MouseDragEvent, mais c'est la plupart du temps pour déplacer des données (comme les images et les fichiers), mais je ne le recommanderais ce. Dans votre cas, il n'est pas très utile, et son comportement est encore buggé. J'espère que cela vous a aidé dans la bonne direction.