Skip to content

Instantly share code, notes, and snippets.

@rlf89
Forked from andytill/DragResizer.java
Last active August 10, 2019 05:26
Show Gist options
  • Save rlf89/d82fdf3dd3a1a186f1f75cd75834cd45 to your computer and use it in GitHub Desktop.
Save rlf89/d82fdf3dd3a1a186f1f75cd75834cd45 to your computer and use it in GitHub Desktop.
DragResizerXY can be used to add mouse listeners to a Container and make it resizable by the user by clicking and dragging the border in the same way as a window.
import javafx.event.EventHandler;
import javafx.scene.Cursor;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.VBox;
/**
* {@link DragResizerXY} can be used to add mouse listeners to a container
* and make it resizable by the user by clicking and dragging the border in the
* same way as a window.
*
* This version uses EventFilter for mouse event registration, so these events
* are taken by DragResizerXY first before being consumed by other elements.
*
* Usage:
* <pre>
* DragResizer.makeResizable(myVBox);
* </pre>
* Builds on the modifications of Cannibalsticky to the original version by
* AndyTill.
*
* @author RamusisTrenksmas
*/
public class DragResizerXY {
/**
* The margin around the control that a user can click in to start resizing
* the region.
*/
private static final int RESIZE_MARGIN = 10;
private final VBox region;
private double y;
private double x;
private boolean initMinHeight;
private boolean initMinWidth;
private boolean draggableZoneX, draggableZoneY;
private boolean dragging;
DragResizerXY(VBox aRegion) {
region = aRegion;
}
public static void makeResizable(VBox region) {
final DragResizerXY resizer = new DragResizerXY(region);
region.addEventFilter(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
resizer.mousePressed(mouseEvent);
}
});
region.addEventFilter(MouseEvent.MOUSE_DRAGGED, new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
resizer.mouseDragged(mouseEvent);
}
});
region.addEventFilter(MouseEvent.MOUSE_MOVED, new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
resizer.mouseOver(mouseEvent);
}
});
region.addEventFilter(MouseEvent.MOUSE_RELEASED, new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
resizer.mouseReleased(mouseEvent);
}
});
}
protected void mouseReleased(MouseEvent event) {
dragging = false;
region.setCursor(Cursor.DEFAULT);
}
protected void mouseOver(MouseEvent event) {
if (isInDraggableZone(event) || dragging) {
if (draggableZoneY) {
region.setCursor(Cursor.S_RESIZE);
}
if (draggableZoneX) {
region.setCursor(Cursor.E_RESIZE);
}
} else {
region.setCursor(Cursor.DEFAULT);
}
}
//had to use 2 variables for the controll, tried without, had unexpected behaviour (going big was ok, going small nope.)
protected boolean isInDraggableZone(MouseEvent event) {
draggableZoneY = (boolean)(event.getY() > (region.getHeight() - RESIZE_MARGIN));
draggableZoneX = (boolean)(event.getX() > (region.getWidth() - RESIZE_MARGIN));
return (draggableZoneY || draggableZoneX);
}
protected void mouseDragged(MouseEvent event) {
if (!dragging) {
return;
}
if (draggableZoneY) {
double mousey = event.getY();
double newHeight = region.getMinHeight() + (mousey - y);
region.setMinHeight(newHeight);
y = mousey;
}
if (draggableZoneX) {
double mousex = event.getX();
double newWidth = region.getMinWidth() + (mousex - x);
region.setMinWidth(newWidth);
x = mousex;
}
}
protected void mousePressed(MouseEvent event) {
// ignore clicks outside of the draggable margin
if (!isInDraggableZone(event)) {
return;
}
dragging = true;
// make sure that the minimum height is set to the current height once,
// setting a min height that is smaller than the current height will
// have no effect
if (!initMinHeight) {
region.setMinHeight(region.getHeight());
initMinHeight = true;
}
y = event.getY();
if (!initMinWidth) {
region.setMinWidth(region.getWidth());
initMinWidth = true;
}
x = event.getX();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment