Make different things occur on Mouse Pressed depending on Object in Javafx - java

I want the mouse clicked event to either drag the existing circle or create a new circle if the mouse clicked event occurs outside of an existing circle. Right now the code will drag the circle, but also creates a new one on top of the other circle. I would really appreciate any help on cleaning the code up and making it do one or the other. Here is the code. Ive been trying to do all kinds of different things to get it to work, but I can't figure out how to get it to only do one or the other.
import javafx.application.Application;
import javafx.scene.Cursor;
import javafx.scene.Group;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.scene.control.ChoiceBox;
import javafx.collections.FXCollections;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
public class Main extends Application {
double orgSceneX, orgSceneY;
double orgTranslateX, orgTranslateY;
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Drawing Operations Test");
Group root = new Group();
Pane canvas = new Pane();
canvas.setStyle("-fx-background-color: black;");
canvas.setPrefSize(200,200);
Rectangle rectangle = new Rectangle(100,100,Color.RED);
rectangle.relocate(70,70);
canvas.getChildren().add(rectangle);
canvas.addEventHandler(MouseEvent.MOUSE_PRESSED,
new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent e) {
Object source = e.getSource();
if (!(source instanceof Circle)) {
Circle circle = new Circle(20,Color.BLUE);
circle.setCursor(Cursor.MOVE);
circle.setOnMousePressed(circleOnMousePressedEventHandler);
circle.setOnMouseDragged(circleOnMouseDraggedEventHandler);
circle.relocate((e.getX()-10),(e.getY()-10));
canvas.getChildren().add(circle);
System.out.println(source);
}
}
});
root.getChildren().add(canvas);
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
EventHandler<MouseEvent> circleOnMousePressedEventHandler =
new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent t) {
orgSceneX = t.getSceneX();
orgSceneY = t.getSceneY();
orgTranslateX = ((Circle)(t.getSource())).getTranslateX();
orgTranslateY = ((Circle)(t.getSource())).getTranslateY();
System.out.println(t.getSource());
}
};
EventHandler<MouseEvent> circleOnMouseDraggedEventHandler =
new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent t) {
double offsetX = t.getSceneX() - orgSceneX;
double offsetY = t.getSceneY() - orgSceneY;
double newTranslateX = orgTranslateX + offsetX;
double newTranslateY = orgTranslateY + offsetY;
((Circle)(t.getSource())).setTranslateX(newTranslateX);
((Circle)(t.getSource())).setTranslateY(newTranslateY);
}
};
}

I found it! the answer for me was creating an if else statement and consuming the event on the circle. I'm sure there is a much more elegant way to do this, but I'm not too elegant in Java..... yet.
public class Main extends Application {
double orgSceneX, orgSceneY;
double orgTranslateX, orgTranslateY;
Pane canvas;
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Drawing Operations Test");
Group root = new Group();
canvas = new Pane();
canvas.setStyle("-fx-background-color: black;");
canvas.setPrefSize(200,200);
Rectangle rectangle = new Rectangle(100,100,Color.RED);
rectangle.relocate(70,70);
canvas.getChildren().add(rectangle);
canvas.setOnMousePressed(MousePressedEventHandler);
root.getChildren().add(canvas);
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
EventHandler<MouseEvent> MousePressedEventHandler =
new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent e) {
if (e.getSource() instanceof Circle) {
orgSceneX = e.getSceneX();
orgSceneY = e.getSceneY();
orgTranslateX = ((Circle)(e.getSource())).getTranslateX();
orgTranslateY = ((Circle)(e.getSource())).getTranslateY();
e.consume();
System.out.println(e.getSource());
}
else {
Circle circle = new Circle(20,Color.BLUE);
circle.setCursor(Cursor.MOVE);
circle.setOnMousePressed(MousePressedEventHandler);
circle.setOnMouseDragged(MouseDraggedEventHandler);
circle.relocate((e.getX()-10),(e.getY()-10));
canvas.getChildren().add(circle);
System.out.println(e.getSource());
}
}
};
EventHandler<MouseEvent> MouseDraggedEventHandler =
new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent t) {
double offsetX = t.getSceneX() - orgSceneX;
double offsetY = t.getSceneY() - orgSceneY;
double newTranslateX = orgTranslateX + offsetX;
double newTranslateY = orgTranslateY + offsetY;
((Circle)(t.getSource())).setTranslateX(newTranslateX);
((Circle)(t.getSource())).setTranslateY(newTranslateY);
}
};
}

You can consume the event on the child node (circle) before it delegates to the Parent (pane).
EventHandler<MouseEvent> circleOnMousePressedEventHandler = event -> {
orgSceneX = event.getSceneX();
orgSceneY = event.getSceneY();
orgTranslateX = ((Circle) (event.getSource())).getTranslateX();
orgTranslateY = ((Circle) (event.getSource())).getTranslateY();
event.consume();
};

Related

Drag-to-draw line Javafx

I'm want to be able to drag-to-draw a line that ends in the center of each of two nodes (circles). I have two event handlers that I'm thinking listen for new mouse clicks, but whenever I click, nothing happens.
Here is the Start method:
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.input.MouseEvent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.shape.Line;
import javafx.scene.shape.Circle;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.layout.Pane;
#Override
public void start(Stage primaryStage) {
Group root = new Group();
Canvas canvas = new Canvas(500,500);
GraphicsContext gc = canvas.getGraphicsContext2D();
//Draw Circles onto a Pane:
Pane overlay = new Pane();
for (int i = 50; i < xDim; i+=50) {
for (int j = 50; j < yDim; j+=50) {
Circle c1 = new Circle();
c1.setCenterX(i);
c1.setCenterY(j);
c1.setRadius(5);
overlay.getChildren().add(c1);
}
}
drawLine(overlay);
root.getChildren().addAll(canvas,overlay);
primaryStage.setScene(new Scene(root, 500, 500));
primaryStage.show();
}
And here is drawLine():
Line l = new Line();
overlay.addEventHandler(MouseEvent.MOUSE_PRESSED,
new EventHandler<MouseEvent>() {
public void handle(MouseEvent t) {
if (t.getSource() instanceof Circle) {
Circle p = ((Circle) (t.getSource()));
double circleX = p.getCenterX();
double circleY = p.getCenterY();
l.setStartX(circleX);
l.setStartY(circleY);
} else {
Node p = ((Node) (t.getSource()));
double orgTranslateX = p.getTranslateX();
double orgTranslateY = p.getTranslateY();
}
}
});
overlay.addEventHandler(MouseEvent.MOUSE_RELEASED,
new EventHandler<MouseEvent>() {
public void handle(MouseEvent t) {
if (t.getSource() instanceof Circle) {
Circle p = ((Circle) (t.getSource()));
double circleX = p.getCenterX();
double circleY = p.getCenterY();
l.setEndX(circleX);
l.setEndY(circleY);
overlay.getChildren().add(l);
} else{}
}
});
};
You can see draw line has two different event handlers, one for a click and one for release, and the only thing that changes is myLine.setEndX().
Any help would be appreciated! I apologize in advance for any unknown transgressions.

How to identify objects with the same variable name in javaFX? [duplicate]

I have a set of Nodes, Circles, on the stage.
I want to be able to click on one of them and 'select it' (just get a reference to it so I can move it around, change color etc.)
Pane root = new Pane();
root.getChildren().addAll( /* an array of Circle objects */ );
Scene scene = new Scene(root, 500, 500, BACKGROUND_COLOR);
scene.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent mouseEvent) {
// how do I get which Circle I clicked on?
}
});
stage.setTitle(TITLE);
stage.setScene(scene);
stage.show();
I would simply register a listener with each circle itself. Then you already have the reference to the circle with which the listener was registered.
This example pushes the limit a little as to usability, because it has 10,000 circles shown all at once, but it demonstrates the technique:
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.css.PseudoClass;
import javafx.geometry.Point2D;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.stage.Stage;
public class GridOfCircles extends Application {
private static final PseudoClass SELECTED_P_C = PseudoClass.getPseudoClass("selected");
private final int numColumns = 100 ;
private final int numRows = 100 ;
private final double radius = 4 ;
private final double spacing = 2 ;
private final ObjectProperty<Circle> selectedCircle = new SimpleObjectProperty<>();
private final ObjectProperty<Point2D> selectedLocation = new SimpleObjectProperty<>();
#Override
public void start(Stage primaryStage) {
selectedCircle.addListener((obs, oldSelection, newSelection) -> {
if (oldSelection != null) {
oldSelection.pseudoClassStateChanged(SELECTED_P_C, false);
}
if (newSelection != null) {
newSelection.pseudoClassStateChanged(SELECTED_P_C, true);
}
});
Pane grid = new Pane();
for (int x = 0 ; x < numColumns; x++) {
double gridX = x*(spacing + radius + radius) + spacing ;
grid.getChildren().add(new Line(gridX, 0, gridX, numRows*(spacing + radius + radius)));
}
for (int y = 0; y < numRows ; y++) {
double gridY = y*(spacing + radius + radius) + spacing ;
grid.getChildren().add(new Line(0, gridY, numColumns*(spacing + radius + radius), gridY));
}
for (int x = 0 ; x < numColumns; x++) {
for (int y = 0 ;y < numRows ; y++) {
grid.getChildren().add(createCircle(x, y));
}
}
Label label = new Label();
label.textProperty().bind(Bindings.createStringBinding(() -> {
Point2D loc = selectedLocation.get();
if (loc == null) {
return "" ;
}
return String.format("Location: [%.0f, %.0f]", loc.getX(), loc.getY());
}, selectedLocation));
BorderPane root = new BorderPane(new ScrollPane(grid));
root.setTop(label);
Scene scene = new Scene(root);
scene.getStylesheets().add("grid.css");
primaryStage.setScene(scene);
primaryStage.show();
}
private Circle createCircle(int x, int y) {
Circle circle = new Circle();
circle.getStyleClass().add("intersection");
circle.setCenterX(x * (spacing + radius + radius) + spacing);
circle.setCenterY(y * (spacing + radius + radius) + spacing);
circle.setRadius(radius);
circle.addEventHandler(MouseEvent.MOUSE_CLICKED, e -> {
selectedCircle.set(circle);
selectedLocation.set(new Point2D(x, y));
});
return circle ;
}
public static void main(String[] args) {
launch(args);
}
}
with the file grid.css:
.intersection {
-fx-fill: blue ;
}
.intersection:selected {
-fx-fill: gold ;
}
You can get the reference by using getSource of the MouseEvent.
Example in which you can drag a Circle and any other Node:
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
Circle circle = new Circle( 100,100,50);
circle.setStroke(Color.BLUE);
circle.setFill(Color.BLUE.deriveColor(1, 1, 1, 0.3));
Rectangle rectangle = new Rectangle( 0,0,100,100);
rectangle.relocate(200, 200);
rectangle.setStroke(Color.GREEN);
rectangle.setFill(Color.GREEN.deriveColor(1, 1, 1, 0.3));
Text text = new Text( "Example Text");
text.relocate(300, 300);
Pane root = new Pane();
root.getChildren().addAll(circle, rectangle, text);
MouseGestures mouseGestures = new MouseGestures();
mouseGestures.makeDraggable(circle);
mouseGestures.makeDraggable(rectangle);
mouseGestures.makeDraggable(text);
Scene scene = new Scene(root, 1024, 768);
primaryStage.setScene(scene);
primaryStage.show();
}
public static class MouseGestures {
class DragContext {
double x;
double y;
}
DragContext dragContext = new DragContext();
public void makeDraggable( Node node) {
node.setOnMousePressed( onMousePressedEventHandler);
node.setOnMouseDragged( onMouseDraggedEventHandler);
node.setOnMouseReleased(onMouseReleasedEventHandler);
}
EventHandler<MouseEvent> onMousePressedEventHandler = event -> {
if( event.getSource() instanceof Circle) {
Circle circle = (Circle) (event.getSource());
dragContext.x = circle.getCenterX() - event.getSceneX();
dragContext.y = circle.getCenterY() - event.getSceneY();
} else {
Node node = (Node) (event.getSource());
dragContext.x = node.getTranslateX() - event.getSceneX();
dragContext.y = node.getTranslateY() - event.getSceneY();
}
};
EventHandler<MouseEvent> onMouseDraggedEventHandler = event -> {
if( event.getSource() instanceof Circle) {
Circle circle = (Circle) (event.getSource());
circle.setCenterX( dragContext.x + event.getSceneX());
circle.setCenterY( dragContext.y + event.getSceneY());
} else {
Node node = (Node) (event.getSource());
node.setTranslateX( dragContext.x + event.getSceneX());
node.setTranslateY( dragContext.y + event.getSceneY());
}
};
EventHandler<MouseEvent> onMouseReleasedEventHandler = event -> {
};
}
public static void main(String[] args) {
launch(args);
}
}

Javafx click on a Circle and get it's reference

I have a set of Nodes, Circles, on the stage.
I want to be able to click on one of them and 'select it' (just get a reference to it so I can move it around, change color etc.)
Pane root = new Pane();
root.getChildren().addAll( /* an array of Circle objects */ );
Scene scene = new Scene(root, 500, 500, BACKGROUND_COLOR);
scene.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent mouseEvent) {
// how do I get which Circle I clicked on?
}
});
stage.setTitle(TITLE);
stage.setScene(scene);
stage.show();
I would simply register a listener with each circle itself. Then you already have the reference to the circle with which the listener was registered.
This example pushes the limit a little as to usability, because it has 10,000 circles shown all at once, but it demonstrates the technique:
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.css.PseudoClass;
import javafx.geometry.Point2D;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.stage.Stage;
public class GridOfCircles extends Application {
private static final PseudoClass SELECTED_P_C = PseudoClass.getPseudoClass("selected");
private final int numColumns = 100 ;
private final int numRows = 100 ;
private final double radius = 4 ;
private final double spacing = 2 ;
private final ObjectProperty<Circle> selectedCircle = new SimpleObjectProperty<>();
private final ObjectProperty<Point2D> selectedLocation = new SimpleObjectProperty<>();
#Override
public void start(Stage primaryStage) {
selectedCircle.addListener((obs, oldSelection, newSelection) -> {
if (oldSelection != null) {
oldSelection.pseudoClassStateChanged(SELECTED_P_C, false);
}
if (newSelection != null) {
newSelection.pseudoClassStateChanged(SELECTED_P_C, true);
}
});
Pane grid = new Pane();
for (int x = 0 ; x < numColumns; x++) {
double gridX = x*(spacing + radius + radius) + spacing ;
grid.getChildren().add(new Line(gridX, 0, gridX, numRows*(spacing + radius + radius)));
}
for (int y = 0; y < numRows ; y++) {
double gridY = y*(spacing + radius + radius) + spacing ;
grid.getChildren().add(new Line(0, gridY, numColumns*(spacing + radius + radius), gridY));
}
for (int x = 0 ; x < numColumns; x++) {
for (int y = 0 ;y < numRows ; y++) {
grid.getChildren().add(createCircle(x, y));
}
}
Label label = new Label();
label.textProperty().bind(Bindings.createStringBinding(() -> {
Point2D loc = selectedLocation.get();
if (loc == null) {
return "" ;
}
return String.format("Location: [%.0f, %.0f]", loc.getX(), loc.getY());
}, selectedLocation));
BorderPane root = new BorderPane(new ScrollPane(grid));
root.setTop(label);
Scene scene = new Scene(root);
scene.getStylesheets().add("grid.css");
primaryStage.setScene(scene);
primaryStage.show();
}
private Circle createCircle(int x, int y) {
Circle circle = new Circle();
circle.getStyleClass().add("intersection");
circle.setCenterX(x * (spacing + radius + radius) + spacing);
circle.setCenterY(y * (spacing + radius + radius) + spacing);
circle.setRadius(radius);
circle.addEventHandler(MouseEvent.MOUSE_CLICKED, e -> {
selectedCircle.set(circle);
selectedLocation.set(new Point2D(x, y));
});
return circle ;
}
public static void main(String[] args) {
launch(args);
}
}
with the file grid.css:
.intersection {
-fx-fill: blue ;
}
.intersection:selected {
-fx-fill: gold ;
}
You can get the reference by using getSource of the MouseEvent.
Example in which you can drag a Circle and any other Node:
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
Circle circle = new Circle( 100,100,50);
circle.setStroke(Color.BLUE);
circle.setFill(Color.BLUE.deriveColor(1, 1, 1, 0.3));
Rectangle rectangle = new Rectangle( 0,0,100,100);
rectangle.relocate(200, 200);
rectangle.setStroke(Color.GREEN);
rectangle.setFill(Color.GREEN.deriveColor(1, 1, 1, 0.3));
Text text = new Text( "Example Text");
text.relocate(300, 300);
Pane root = new Pane();
root.getChildren().addAll(circle, rectangle, text);
MouseGestures mouseGestures = new MouseGestures();
mouseGestures.makeDraggable(circle);
mouseGestures.makeDraggable(rectangle);
mouseGestures.makeDraggable(text);
Scene scene = new Scene(root, 1024, 768);
primaryStage.setScene(scene);
primaryStage.show();
}
public static class MouseGestures {
class DragContext {
double x;
double y;
}
DragContext dragContext = new DragContext();
public void makeDraggable( Node node) {
node.setOnMousePressed( onMousePressedEventHandler);
node.setOnMouseDragged( onMouseDraggedEventHandler);
node.setOnMouseReleased(onMouseReleasedEventHandler);
}
EventHandler<MouseEvent> onMousePressedEventHandler = event -> {
if( event.getSource() instanceof Circle) {
Circle circle = (Circle) (event.getSource());
dragContext.x = circle.getCenterX() - event.getSceneX();
dragContext.y = circle.getCenterY() - event.getSceneY();
} else {
Node node = (Node) (event.getSource());
dragContext.x = node.getTranslateX() - event.getSceneX();
dragContext.y = node.getTranslateY() - event.getSceneY();
}
};
EventHandler<MouseEvent> onMouseDraggedEventHandler = event -> {
if( event.getSource() instanceof Circle) {
Circle circle = (Circle) (event.getSource());
circle.setCenterX( dragContext.x + event.getSceneX());
circle.setCenterY( dragContext.y + event.getSceneY());
} else {
Node node = (Node) (event.getSource());
node.setTranslateX( dragContext.x + event.getSceneX());
node.setTranslateY( dragContext.y + event.getSceneY());
}
};
EventHandler<MouseEvent> onMouseReleasedEventHandler = event -> {
};
}
public static void main(String[] args) {
launch(args);
}
}

javafx timeline and mouse event

when I run this code this, the action will stop when the mouse click.
The ball will stop action when I click mouse. how do I make the ball do the action continuously although I click the mouse to add other balls.
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Bounds;
import javafx.scene.Scene;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
import javafx.util.Duration;
public class GamePractice extends Application {
public static Circle circle;
public static Pane canvas;
#Override
public void start(final Stage primaryStage) {
canvas = new Pane();
final Scene scene = new Scene(canvas, 800, 600);
primaryStage.setTitle("Game");
primaryStage.setScene(scene);
primaryStage.show();
circle = new Circle(15, Color.BLUE);
circle.relocate(100, 100);
canvas.getChildren().addAll(circle);
final Timeline loop = new Timeline(new KeyFrame(Duration.millis(10), new EventHandler<ActionEvent>() {
double deltaX = (double)(Math.random()*10) + 3;
double deltaY = (double)(Math.random()*10) + 3;
#Override
public void handle(final ActionEvent t) {
circle.setLayoutX(circle.getLayoutX() + deltaX);
circle.setLayoutY(circle.getLayoutY() + deltaY);
final Bounds bounds = canvas.getBoundsInLocal();
final boolean atRightBorder = circle.getLayoutX() >= (bounds.getMaxX() - circle.getRadius());
final boolean atLeftBorder = circle.getLayoutX() <= (bounds.getMinX() + circle.getRadius());
final boolean atBottomBorder = circle.getLayoutY() >= (bounds.getMaxY() - circle.getRadius());
final boolean atTopBorder = circle.getLayoutY() <= (bounds.getMinY() + circle.getRadius());
if (atRightBorder || atLeftBorder) {
deltaX *= -1;
}
if (atBottomBorder || atTopBorder) {
deltaY *= -1;
}
}
}));
scene.setOnMousePressed(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
if (event.getButton() == MouseButton.PRIMARY) {
if (!(canvas.getChildren().isEmpty())) {
canvas.getChildren().remove(0);
}
}
else {
int red = (int)(Math.random()*256);
int green = (int)(Math.random()*256);
int blue = (int)(Math.random()*256);
int x = (int)(Math.random()*801);
int y = (int)(Math.random()*601);
circle = new Circle(15, Color.rgb(red, green, blue));
circle.relocate(x, y);
canvas.getChildren().addAll(circle);
}
}
});
loop.setCycleCount(Timeline.INDEFINITE);
loop.play();
}
public static void main(final String[] args) {
launch(args);
}
}
Just create an animation for each circle:
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Bounds;
import javafx.scene.Scene;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
import javafx.util.Duration;
public class GamePractice extends Application {
private Pane canvas;
#Override
public void start(final Stage primaryStage) {
canvas = new Pane();
final Scene scene = new Scene(canvas, 800, 600);
primaryStage.setTitle("Game");
primaryStage.setScene(scene);
primaryStage.show();
addCircle(100, 100, Color.BLUE);
scene.setOnMousePressed(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
if (event.getButton() == MouseButton.PRIMARY) {
if (!(canvas.getChildren().isEmpty())) {
canvas.getChildren().remove(0);
}
}
else {
int red = (int)(Math.random()*256);
int green = (int)(Math.random()*256);
int blue = (int)(Math.random()*256);
int x = (int)(Math.random()*801);
int y = (int)(Math.random()*601);
addCircle(x, y, Color.rgb(red, green, blue));
}
}
});
}
private void addCircle(double x, double y, Color color) {
Circle circle = new Circle(15, color);
circle.relocate(x, y);
canvas.getChildren().addAll(circle);
final Timeline loop = new Timeline(new KeyFrame(Duration.millis(10), new EventHandler<ActionEvent>() {
double deltaX = (double)(Math.random()*10) + 3;
double deltaY = (double)(Math.random()*10) + 3;
#Override
public void handle(final ActionEvent t) {
circle.setLayoutX(circle.getLayoutX() + deltaX);
circle.setLayoutY(circle.getLayoutY() + deltaY);
final Bounds bounds = canvas.getBoundsInLocal();
final boolean atRightBorder = circle.getLayoutX() >= (bounds.getMaxX() - circle.getRadius());
final boolean atLeftBorder = circle.getLayoutX() <= (bounds.getMinX() + circle.getRadius());
final boolean atBottomBorder = circle.getLayoutY() >= (bounds.getMaxY() - circle.getRadius());
final boolean atTopBorder = circle.getLayoutY() <= (bounds.getMinY() + circle.getRadius());
if (atRightBorder || atLeftBorder) {
deltaX *= -1;
}
if (atBottomBorder || atTopBorder) {
deltaY *= -1;
}
}
}));
loop.setCycleCount(Timeline.INDEFINITE);
loop.play();
}
public static void main(final String[] args) {
launch(args);
}
}

Move undecorated stage on mouse drag

I set the style of stage as
stage.initStyle(StageStyle.UNDECORATED);
But now I want to able to move the stage window. How to do that?
Let's say root is your parent node, the one that you use while creating Scene. xOffset and yOffset are double type variables. You can achieve dragging the window using the following code:
root.setOnMousePressed(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
xOffset = event.getSceneX();
yOffset = event.getSceneY();
}
});
root.setOnMouseDragged(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
primaryStage.setX(event.getScreenX() - xOffset);
primaryStage.setY(event.getScreenY() - yOffset);
}
});
i understand
import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class Main extends Application
{
private double xOffset = 0;
private double yOffset = 0;
private static class Delta {
double x, y;
}
final Delta dragDelta = new Delta();
final BooleanProperty inDrag = new SimpleBooleanProperty(false);
#Override public void start(final Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("Login.fxml"));
primaryStage.initStyle(StageStyle.UNDECORATED);
root.setOnMousePressed(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
dragDelta.x = primaryStage.getX() - event.getScreenX();
dragDelta.y = primaryStage.getY() - event.getScreenY();
xOffset = event.getSceneX();
yOffset = event.getSceneY();
}
});
root.setOnMouseDragged(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
primaryStage.setX(event.getScreenX() + dragDelta.x);
primaryStage.setY(event.getScreenY() + dragDelta.y);
primaryStage.getWidth();
primaryStage.getHeight();
primaryStage.getX();
primaryStage.getY();
inDrag.set(true);
}
});
primaryStage.setTitle("Login");
primaryStage.setResizable(false);
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}

Categories