2017-07-19 4 views
0

Ich versuche, ein Polygon in javafx zu zeichnen, zu seinem Array von Punkt die Mauskoordinaten hinzufügen. Mein Problem ist, dass ich nicht weiß, wie ich es stoppen kann, wenn ich etwas anderes von der linken Maustaste klicke.Zeichnen Sie ein Polygon in 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

Um zu verdeutlichen, wird der Code, den Sie an einen Event-Handler übergeben (z. B. 'onMouseClicked') * jedes Mal * ausgeführt, wenn das Ereignis eintritt. Sie brauchen hier keine Schleife. –

Antwort

2

Sie können einen Verweis auf ein Polygon erstellen. Wenn es der erste Klick ist, dann ist das Polygon null, also erstellen Sie ein neues und fügen Sie es zu Ihrem Bereich hinzu. Fügen Sie dann solange Punkte hinzu, bis Sie mit der rechten Maustaste klicken. An diesem Punkt setzen Sie das Polygon einfach auf null zurück, so dass der nächste Linksklick ein neues Polygon erneut startet.

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

Sie mit verschiedenen Ideen um diese spielen können unterschiedliche Benutzererfahrungen zu erhalten, zum Beispiel

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

Das Problem ist, dass Ihr Code in einem einzigen Ereignis stecken bleibt. Auch wenn Sie die Maus bewegen oder die Maustaste loslassen, werden sich die Werte der Ereignisinstanz, mit der Sie arbeiten, nicht ändern.

Denken Sie an das Ereignis als einen einzelnen Zustand. Wenn etwas Wichtiges passiert (in Ihrem Fall wird eine Maustaste geklickt), ruft javafx Ihren mausEventHandler mit einer MouseEvent-Instanz mit dem Status der Maus in diesem Moment auf. Wenn Sie erneut klicken, erstellt javafx eine neue Instanz mit neuen Werten und ruft den eventHandler erneut auf.

Damit dies funktioniert, benötigen Sie ein anderes Mausereignis (oder ändern Sie es geringfügig, so dass nur ein Punkt mit einem einzigen Mausklick gesetzt werden kann). Sie müssen die (unendliche) while-Schleife verlieren, da sie sowohl das EventThread blockiert als auch nicht für die Dinge arbeitet, die Sie dafür benötigen. So etwas könnte ein bisschen besser funktionieren.

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

Jetzt gibt es eine MouseDragEvent, aber das ist vor allem für Daten zu bewegen (wie Bilder und Dateien), aber ich würde es nicht empfehlen. In Ihrem Fall ist es nicht sehr nützlich, und sein Verhalten ist immer noch Buggy.

Ich hoffe, dass dies Ihnen in die richtige Richtung geholfen hat.

Verwandte Themen