Java FX nested event handler I want to block the parent handler when child handler is called - javafx

I have a fxml Mouse event handler method where every time I click a Pane a pop up dialog box appears on the screen asking for information. When OK is clicked on the dialog, a circle with text is added to a stack pane and the stack pane is then added to the pane where the user clicked.
However I am trying to implement a event handler where I can move the stack pane around by dragging the stack pane with the mouse. My event handler works but every time I finish dragging the stack pane the pop up dialog pops up. I do not want the pop up dialog to pop up when moving the circle how would I change my code to do this is there a way of blocking the pop up handler?
Thank you.
My Handler method:
#FXML
private void handleAddVertex(MouseEvent event) {
boolean okClicked = main.showAddVertexPopUp(this);
if(okClicked) {
String vertexText = "";
if(getSelectedDataChoice().equals("Integer")) {
vertexText = dataModel.getListOfIntVertices().get(dataModel.getListOfIntVertices().size() - 1).toString();
}else if(getSelectedDataChoice().equals("Double")){
vertexText = dataModel.getListOfDoubleVertices().get(dataModel.getListOfDoubleVertices().size() - 1).toString();
}else {
vertexText = dataModel.getListOfStringVertices().get(dataModel.getListOfStringVertices().size() - 1).toString();
}
EventHandler<MouseEvent> circleOnMousePressedEventHandler =
new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent t) {
orgSceneX = t.getSceneX();
orgSceneY = t.getSceneY();
orgTranslateX = ((StackPane)(t.getSource())).getTranslateX();
orgTranslateY = ((StackPane)(t.getSource())).getTranslateY();
}
};
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;
((StackPane)(t.getSource())).setTranslateX(newTranslateX);
((StackPane)(t.getSource())).setTranslateY(newTranslateY);
}
};
double x = event.getX();
double y = event.getY();
Circle vertex = new Circle(x, y, 20, Color.WHITE);
vertex.setStroke(Color.BLACK);
Text text = new Text (vertexText);
StackPane stack = new StackPane();
stack.getChildren().addAll(vertex, text);
stack.setLayoutX(x);
stack.setLayoutY(y);
stack.setOnMousePressed(circleOnMousePressedEventHandler);
stack.setOnMouseDragged(circleOnMouseDraggedEventHandler);
centerPane.getChildren().add(stack);
}
}

To stop an Event from propagating you use Event.consume().
Marks this Event as consumed. This stops its further propagation.
From your description, it appears handleAddVertex is a MOUSE_CLICKED handler. You'll have to add another EventHandler to the newly created StackPane that consumes MOUSE_CLICKED events.
stack.setOnMouseClicked(Event::consume);
This will stop the MOUSE_CLICKED event from bubbling up to the Node which has the handleAddVertex handler.
For more information on event processing in JavaFX, see JavaFX: Handling Events.
Here's a small example where you can see the difference between consuming and not consuming the event:
import java.util.function.Predicate;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Point2D;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.ButtonType;
import javafx.scene.control.CheckBox;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Border;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.BorderStroke;
import javafx.scene.layout.BorderStrokeStyle;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class Main extends Application {
private CheckBox consumeClickEventsCheckBox;
#Override
public void start(Stage primaryStage) throws Exception {
consumeClickEventsCheckBox = new CheckBox("Consume click events");
consumeClickEventsCheckBox.setSelected(true);
HBox top = new HBox(consumeClickEventsCheckBox);
top.setPadding(new Insets(10));
top.setAlignment(Pos.CENTER);
Pane center = new Pane();
center.setBorder(new Border(new BorderStroke(Color.BLACK, BorderStrokeStyle.SOLID, null, null)));
center.setOnMouseClicked(this::handleAddCircle);
Rectangle clip = new Rectangle();
clip.widthProperty().bind(center.widthProperty());
clip.heightProperty().bind(center.heightProperty());
center.setClip(clip);
BorderPane root = new BorderPane(center);
root.setTop(top);
Scene scene = new Scene(root, 600, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
private void handleAddCircle(MouseEvent event) {
event.consume();
Alert confirm = new Alert(AlertType.CONFIRMATION);
confirm.initOwner(((Node) event.getSource()).getScene().getWindow());
confirm.setHeaderText(null);
confirm.setContentText("Do you want to add a circle here?");
if (confirm.showAndWait().filter(Predicate.isEqual(ButtonType.OK)).isPresent()) {
Circle circle = new Circle(event.getX(), event.getY(), 25);
circle.setOnMousePressed(this::handleCirclePressed);
circle.setOnMouseDragged(this::handleCircleDragged);
circle.setOnMouseClicked(this::handleCircleClicked);
((Pane) event.getSource()).getChildren().add(circle);
}
}
private Point2D origin;
private void handleCirclePressed(MouseEvent event) {
event.consume();
origin = new Point2D(event.getX(), event.getY());
}
private void handleCircleDragged(MouseEvent event) {
event.consume();
Circle circle = (Circle) event.getSource();
circle.setTranslateX(circle.getTranslateX() + event.getX() - origin.getX());
circle.setTranslateY(circle.getTranslateY() + event.getY() - origin.getY());
}
/*
* Will consume the MOUSE_CLICKED event only if the CheckBox is selected. You can test
* the behavior of consuming the event by toggling the CheckBox.
*/
private void handleCircleClicked(MouseEvent event) {
if (consumeClickEventsCheckBox.isSelected()) {
event.consume();
}
}
}

Related

Issues with JavaFX Translate

I have this sample:
package bit.fxtest2;
import javafx.application.Application;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.ObservableList;
import javafx.geometry.Point2D;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Line;
import javafx.scene.transform.Transform;
import javafx.scene.transform.Translate;
import javafx.stage.Stage;
public class TransformTest2 extends Application {
#Override
public void start(Stage stage) {
stage.setTitle("TransformTest2");
var bp = new BorderPane();
bp.setCenter(new DragPane());
var scene = new Scene(bp, 640, 480);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
private static class DragPane extends Pane {
ObjectProperty<Transform> xform = new SimpleObjectProperty<>(new Translate(0, 0));
public DragPane() {
ObjectProperty<Point2D> mouseDown = new SimpleObjectProperty<>();
setOnMousePressed(e -> {
var mousePress = new Point2D(e.getX(), e.getY());
mouseDown.set(mousePress);
});
setOnMouseDragged(e -> {
var dragPoint = new Point2D(e.getX(), e.getY());
var delta = dragPoint.subtract(mouseDown.get());
var t = new Translate(delta.getX(), delta.getY());
xform.set(xform.get().createConcatenation(t));
mouseDown.set(dragPoint);
System.out.println("mp = " + mouseDown);
updateTransform();
});
populate();
updateTransform();
}
private void populate() {
ObservableList<Node> children = getChildren();
children.clear();
children.add(new Line(0, 0, 200, 0));
children.add(new Line(200, 0, 200, 200));
children.add(new Line(200, 200, 0, 200));
children.add(new Line(0, 200, 0, 0));
}
private void updateTransform() {
ObservableList<Transform> transforms = getTransforms();
transforms.clear();
transforms.add(xform.get());
}
}
}
If you run the code, two things happen.
First, as you start dragging, the box drags, but it starts getting very jerky, and bounces back and forth. If you print out the mouse motions they move back and forth.
Second, after you've dragged the box, say, down and to the right, you'll notice that you can no longer drag it in the upper left area of the window.
This is because the Translate is affecting the Pane itself, not necessarily the contents of the Pane. Since the OnMouse handlers are on the Pane itself, and the Pane is no longer in the upper left area, no handlers are called.
So, two questions.
First, why the jerky behavior?
Second, how can I apply Transforms (not just translate) to the children of a pane, and not the pane itself?
The answer to the first question (the jerkiness) is that it's because your calculations for the transform are incorrect.
When the dragging is processed, the pane is translated by the amount that was dragged. This leaves the coordinates of the mouse relative to the pane as being the same as they were when the mouse was first pressed.
For example, suppose you click on the pane at (100,100), so mouseDown contains the value (100,100). You then drag it, so suppose when the drag event is processed the mouse has moved to (102,101) in the pane's coordinate system. Then delta will be (2,1), so the pane will be translated by (an additional) (2,1), after which the mouse will again be over the point (100,100) in the pane's coordinate system.
Therefore, the correct thing to do here is not to change the value of mouseDown.
Simply removing the line
mouseDown.set(dragPoint);
fixes that issue.
For the second issue: As long as the user starts the drag inside the actual pane, then it all works fine; this seems to be the natural thing to do.
But if you really want to be able to drag from anywhere in the window, you can place the nodes to be dragged in a Group and apply the translation to the group. Note that this time, because the Pane is not moving, you do need to update the mouseDown value:
import javafx.application.Application;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.ObservableList;
import javafx.geometry.Point2D;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Line;
import javafx.scene.transform.Transform;
import javafx.scene.transform.Translate;
import javafx.stage.Stage;
public class TransformTest2 extends Application {
#Override
public void start(Stage stage) {
stage.setTitle("TransformTest2");
var bp = new BorderPane();
bp.setCenter(new DragPane());
var scene = new Scene(bp, 640, 480);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
private static class DragPane extends Pane {
ObjectProperty<Transform> xform = new SimpleObjectProperty<>(new Translate(0, 0));
Group group ;
public DragPane() {
ObjectProperty<Point2D> mouseDown = new SimpleObjectProperty<>();
group = new Group();
getChildren().add(group);
setOnMousePressed(e -> {
var mousePress = new Point2D(e.getX(), e.getY());
mouseDown.set(mousePress);
});
setOnMouseDragged(e -> {
var dragPoint = new Point2D(e.getX(), e.getY());
var delta = dragPoint.subtract(mouseDown.get());
var t = new Translate(delta.getX(), delta.getY());
xform.set(xform.get().createConcatenation(t));
mouseDown.set(dragPoint);
System.out.println("mp = " + mouseDown);
updateTransform();
});
populate();
updateTransform();
}
private void populate() {
ObservableList<Node> children = group.getChildren();
children.clear();
children.add(new Line(0, 0, 200, 0));
children.add(new Line(200, 0, 200, 200));
children.add(new Line(200, 200, 0, 200));
children.add(new Line(0, 200, 0, 0));
}
private void updateTransform() {
ObservableList<Transform> transforms = group.getTransforms();
transforms.clear();
transforms.add(xform.get());
}
}
}
If you don't want the additional node, you can achieve the same effect by handling the mouse events on the scene, and update the transforms for the pane.

JavaFX bounds issue?

So, using JAVAfx, which I painfully downloaded, I need to be able to move this ball, but not let it leave the bounds. Right now, I have it all set up, it just leaves the area. What am i doing wrong? Any tutors don't know anything about JavaFX, so I'm having trouble getting past this. Right now I tried to work it out, but keep getting this error Cannot Make a Static Reference to Bound
'''
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
import javafx.geometry.Bounds;
public class MoveBall extends Application {
// create buttons
Button left = new Button();
Button right = new Button();
Button up = new Button();
Button down = new Button();
Circle ball = new Circle(30, 30, 30);
// action event class
EventHandler<ActionEvent> event = new EventHandler<ActionEvent>() {
// handle them
#Override
public void handle(ActionEvent event) {
// movement of ball
if (event.getSource().equals(left) && ball.getLayoutX() >= (Bounds.getMaxX() + ball.getRadius())) {
ball.setCenterX(ball.getCenterX() - 5);
}
if (event.getSource().equals(right)) {
ball.setCenterX(ball.getCenterX() + 5);
}
if (event.getSource().equals(up)) {
ball.setCenterY(ball.getCenterY() - 5);
}
if (event.getSource().equals(down) && ball.getCenterY() < 400)) {
ball.setCenterY(ball.getCenterY() + 5);
}
}
};
// main method
public static void main(String[] args) {
Application.launch(args);
}
#Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Ball Movement");
ball.setStroke(Color.BLACK);
ball.setFill(null);
// button location
left.setLayoutX(100);
left.setLayoutY(210);
left.setText("Left");
// button event
left.setOnAction(event);
// similar for all button
right.setLayoutX(150);
right.setLayoutY(210);
right.setText("Right");
right.setOnAction(event);
// button location
up.setLayoutX(200);
up.setLayoutY(210);
up.setText("Up");
// button event
up.setOnAction(event);
// similar for all button
down.setLayoutX(250);
down.setLayoutY(210);
down.setText("Down");
down.setOnAction(event);
Group root = new Group();
// add to a group
root.getChildren().add(left);
root.getChildren().add(right);
root.getChildren().add(up);
root.getChildren().add(down);
root.getChildren().add(ball);
primaryStage.setScene(new Scene(root, 400, 250, Color.WHITE));
// show the scene
primaryStage.show();
}
}
'''

Highlighting rectangle when more than half overlaps

I have a JavaFX application with a pane that contains rectangles. These rectangles can be moved by dragging the mouse.
When I drag a rectangle over another rectangle, I would like the second (background) rectangle to be highlighted. This works, see code below
private boolean moveInProgress;
private Point2D prevPos;
public void onMousePressed(MouseEvent event) {
setMouseTransparent(true);
Point2D point = new Point2D(event.getSceneX(), event.getSceneY());
if (!moveInProgress) {
moveInProgress = true;
prevPos = point;
LOG.debug("Mouse move started on location " + prevPos);
}
event.consume();
}
public void onMouseDragged(MouseEvent event) {
if (moveInProgress) {
Point2D point = new Point2D(event.getSceneX(), event.getSceneY());
this.toFront();
double[] translationVector = new double[2];
translationVector[0] = point.getX() - prevPos.getX();
translationVector[1] = point.getY() - prevPos.getY();
setTranslateX(getTranslateX() + translationVector[0]);
setTranslateY(getTranslateY() + translationVector[1]);
prevPos = point;
}
event.consume();
}
public void onMouseReleased(MouseEvent event) {
setMouseTransparent(false);
if (moveInProgress) {
moveInProgress = false;
}
event.consume();
}
public void onDragDetected(MouseEvent event) {
startFullDrag();
event.consume();
}
public void onMouseDragEntered(MouseDragEvent event) {
getStyleClass().add("drag-target");
event.consume();
}
public void onMouseDragExited(MouseDragEvent event) {
if (getStyleClass().contains("drag-target")) {
getStyleClass().remove("drag-target");
}
event.consume();
}
I would like to highlight the underlying rectangle when more than half of my dragging rectangle overlaps. In this picture, I would like to highlight the red rectangle, since the grey rectangle overlaps more than half of it.
The problem is that the MouseDragEntered and MouseDragExited events are fired based on my mouse position. When my mouse position is for example the black dot in the picture, my mouse events will only be fired when my mouse enters the red rectangle.
Can anyone give me some pointers how to highlight the red rectangle when during a drag action of the grey rectangle, more than half of it overlaps?
One approach is to have each rectangle observe the bounds of the rectangle that is being dragged. Then it's reasonably easy to do a computation using Shape.intersect (or by other means) to see if the rectangle is 50% covered by the rectangle being dragged. The tricky part here is adding the listeners to the rectangle being dragged and removing them again when the rectangle stops being dragged.
Here's a quick example. I think I have things set up a little differently from the way you have them set up, but you should be able to adapt this to your use case easily enough.
import java.util.Random;
import javafx.application.Application;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ChangeListener;
import javafx.css.PseudoClass;
import javafx.geometry.Bounds;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.Shape;
import javafx.stage.Stage;
public class DraggingHighlightRectangles extends Application {
private final Random rng = new Random();
private final ObjectProperty<Rectangle> draggingRectangle = new SimpleObjectProperty<>();
#Override
public void start(Stage primaryStage) {
Pane pane = new Pane();
pane.setMinSize(600, 600);
Button newRectButton = new Button("New Rectangle");
newRectButton.setOnAction(e -> pane.getChildren().add(createRectangle()));
BorderPane.setAlignment(newRectButton, Pos.CENTER);
BorderPane.setMargin(newRectButton, new Insets(5));
BorderPane root = new BorderPane(pane);
root.setBottom(newRectButton);
Scene scene = new Scene(root);
scene.getStylesheets().add("style.css");
primaryStage.setScene(scene);
primaryStage.show();
}
private Rectangle createRectangle() {
Rectangle rect = new Rectangle(rng.nextInt(400)+100, rng.nextInt(500)+50, 100, 50);
rect.setFill(randomColor());
rect.getStyleClass().add("rect");
ChangeListener<Bounds> boundsListener = (obs, oldBounds, newBounds) -> {
double myArea = rect.getWidth() * rect.getHeight() ;
Shape intersection = Shape.intersect(draggingRectangle.get(), rect);
Bounds intersectionBounds = intersection.getBoundsInLocal();
double intersectionArea = intersectionBounds.getWidth() * intersectionBounds.getHeight() ;
rect.pseudoClassStateChanged(PseudoClass.getPseudoClass("highlight"), intersectionArea >= 0.5 * myArea);
};
draggingRectangle.addListener((obs, oldRect, newRect) -> {
if (oldRect != null) {
oldRect.boundsInLocalProperty().removeListener(boundsListener);
}
if (newRect != null && newRect != rect) {
newRect.boundsInLocalProperty().addListener(boundsListener);
}
rect.pseudoClassStateChanged(PseudoClass.getPseudoClass("highlight"), false);
});
class MouseLocation { double x, y ; }
MouseLocation mouseLocation = new MouseLocation();
rect.setOnMousePressed(e -> {
draggingRectangle.set(rect);
rect.toFront();
mouseLocation.x = e.getX() ;
mouseLocation.y = e.getY() ;
});
rect.setOnMouseDragged(e -> {
rect.setX(rect.getX() + e.getX() - mouseLocation.x);
rect.setY(rect.getY() + e.getY() - mouseLocation.y);
mouseLocation.x = e.getX() ;
mouseLocation.y = e.getY() ;
});
rect.setOnMouseReleased(e -> draggingRectangle.set(null));
return rect ;
}
private Color randomColor() {
return Color.rgb(rng.nextInt(256), rng.nextInt(256), rng.nextInt(256));
}
public static void main(String[] args) {
launch(args);
}
}
My stylesheet, style.css, just contains
.rect:highlight {
-fx-fill: yellow ;
}

Tooltip isn't being displayed on ScrollPane

Following the tutorial here I tried to create a Tooltip on a ScrollPane using the following code:
final ScrollPane scroll = new ScrollPane();
scroll.addEventHandler(MouseEvent.MOUSE_MOVED, new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent t) {
pointer = MouseInfo.getPointerInfo();
point = pointer.getLocation();
color = robot.getPixelColor((int) point.getX(), (int) point.getY());
Tooltip tooltip = new Tooltip();
tooltip.setText(" " + color);
tooltip.activatedProperty();
scroll.setTooltip(tooltip);
System.out.println("Color at: " + point.getX() + "," + point.getY() + " is: " + color);
}
});
The tooltip however refuses to show itself on the ScrollPane but the output of "Color at: ..." is being printed so I am sure that handle is being called.
EDIT : On the suggestion of jewelsea , I tried putting the eventHandler on the content ,rather than the pane, but to no effect.
If I understand what you're trying to do, you really only need to install the tooltip once, and then just modify its text as the mouse moves.
This works for me:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.Tooltip;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.PixelReader;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class ImageTooltipTest extends Application {
#Override
public void start(Stage primaryStage) {
BorderPane root = new BorderPane();
Image image = new Image("http://www.publicdomainpictures.net/pictures/30000/velka/tropical-paradise.jpg");
final ImageView imageView = new ImageView();
imageView.setImage(image);
final ScrollPane scroller = new ScrollPane();
scroller.setContent(imageView);
final Tooltip tooltip = new Tooltip();
scroller.setTooltip(tooltip);
scroller.getContent().addEventHandler(MouseEvent.MOUSE_MOVED, event -> {
Image snapshot = scroller.getContent().snapshot(null, null);
int x = (int) event.getX();
int y = (int) event.getY();
PixelReader pixelReader = snapshot.getPixelReader();
Color color = pixelReader.getColor(x, y);
String text = String.format("Red: %.2f%nGreen: %.2f%nBlue: %.2f",
color.getRed(),
color.getGreen(),
color.getBlue());
tooltip.setText(text);
});
root.setCenter(scroller);
Scene scene = new Scene(root, 800, 600);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}

Transparent Stage should not minimized when clicked inside in Javafx

I am learning to create Screen Recording application in JavaFx. I want user to resize the rectangle to decide the screen capture area. I have made stage and scene Transparent by primaryStage.initStyle(StageStyle.TRANSPARENT); and scene.setFill(null); .
I am able to resize the rectangular section but the problem is When I click inside the stage, It gets minimized as it is transparent. How to solve this issue ?
I have seen this application screencast-o-matics and following the same. Please guide me on this.
Edit::
Code:
import java.awt.Toolkit;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class ScreenCaptureDemo extends Application {
Rectangle rectangle ;
double x0,y0;
public static void main(String[] args) {
launch(ScreenCaptureDemo.class);
}
#Override
public void start(final Stage primaryStage) throws Exception {
BorderPane borderPane = new BorderPane();
GridPane gridPane = new GridPane();
HBox box = new HBox();
Button button1 = new Button("button2");
Button button2 = new Button("Button3");
Button button = new Button("button");
box.getChildren().add(button);
box.getChildren().add(button1);
box.getChildren().add(button2);
rectangle = new Rectangle(500.0, 500.0);
rectangle.setStrokeWidth(2);
rectangle.setArcHeight(15.0);
rectangle.setArcWidth(15.0);
rectangle.setFill(Color.TRANSPARENT);
rectangle.setStroke(Color.RED);
rectangle.setStrokeWidth(5);
rectangle.getStrokeDashArray().addAll(3.0,13.0,3.0,7.0);
gridPane.add(rectangle, 0, 0);
gridPane.add(box, 0, 1);
borderPane.setCenter(gridPane);
Scene scene = new Scene(borderPane,Toolkit.getDefaultToolkit().getScreenSize().getWidth()-100,Toolkit.getDefaultToolkit().getScreenSize().getHeight()-100);
scene.setOnMouseDragged(mouseHandler);
scene.setOnMousePressed(mouseHandler);
primaryStage.setScene(scene);
primaryStage.initStyle(StageStyle.TRANSPARENT);
scene.setFill(null);
rectangle.setMouseTransparent(true);
rectangle.setPickOnBounds(true);
primaryStage.show();
}
void setScaleRect(double sX, double sY){
rectangle.setHeight(sY);
rectangle.setWidth(sX);
}
EventHandler<MouseEvent> mouseHandler = new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent mouseEvent) {
if (mouseEvent.getEventType() == MouseEvent.MOUSE_DRAGGED) {
double heightLowerLimit = rectangle.getHeight()-500;
double heightUpperLimit = rectangle.getHeight()+500;
double widthLowerLimit = rectangle.getWidth()-500;
double widthUpperLimit = rectangle.getWidth()+500;
if ((mouseEvent.getY() >heightLowerLimit && mouseEvent.getY() < heightUpperLimit) &&
(mouseEvent.getX() >widthLowerLimit && mouseEvent.getX() < widthUpperLimit)
) {
double scaleX = mouseEvent.getX();
double scaleY = mouseEvent.getY();
setScaleRect(scaleX, scaleY);
} else if ((mouseEvent.getY() >heightLowerLimit && mouseEvent.getY() < heightUpperLimit)
&& (mouseEvent.getX() <widthLowerLimit && mouseEvent.getX() > widthUpperLimit)) {
double scaleY = mouseEvent.getY();
double scaleX=rectangle.getWidth();
setScaleRect(scaleX, scaleY);
} else if (mouseEvent.getY() != rectangle.getHeight()
&& mouseEvent.getX() == rectangle.getWidth()) {
double scaleX = mouseEvent.getX();
double scaleY=rectangle.getHeight();
setScaleRect(scaleX, scaleY);
}
}
}
};
}
Thank you in advance
Fill the rectangle as
rectangle.setFill(Color.web("blue", 0.1));
// or more transparent
rectangle.setFill(Color.web("gray", 0.01));

Resources