-
-
Save andytill/4369729 to your computer and use it in GitHub Desktop.
import javafx.event.EventHandler; | |
import javafx.scene.Cursor; | |
import javafx.scene.input.MouseEvent; | |
import javafx.scene.layout.Region; | |
/** | |
* {@link DragResizer} can be used to add mouse listeners to a {@link Region} | |
* and make it resizable by the user by clicking and dragging the border in the | |
* same way as a window. | |
* <p> | |
* Only height resizing is currently implemented. Usage: <pre>DragResizer.makeResizable(myAnchorPane);</pre> | |
* | |
* @author atill | |
* | |
*/ | |
public class DragResizer { | |
/** | |
* The margin around the control that a user can click in to start resizing | |
* the region. | |
*/ | |
private static final int RESIZE_MARGIN = 5; | |
private final Region region; | |
private double y; | |
private boolean initMinHeight; | |
private boolean dragging; | |
private DragResizer(Region aRegion) { | |
region = aRegion; | |
} | |
public static void makeResizable(Region region) { | |
final DragResizer resizer = new DragResizer(region); | |
region.setOnMousePressed(new EventHandler<MouseEvent>() { | |
@Override | |
public void handle(MouseEvent event) { | |
resizer.mousePressed(event); | |
}}); | |
region.setOnMouseDragged(new EventHandler<MouseEvent>() { | |
@Override | |
public void handle(MouseEvent event) { | |
resizer.mouseDragged(event); | |
}}); | |
region.setOnMouseMoved(new EventHandler<MouseEvent>() { | |
@Override | |
public void handle(MouseEvent event) { | |
resizer.mouseOver(event); | |
}}); | |
region.setOnMouseReleased(new EventHandler<MouseEvent>() { | |
@Override | |
public void handle(MouseEvent event) { | |
resizer.mouseReleased(event); | |
}}); | |
} | |
protected void mouseReleased(MouseEvent event) { | |
dragging = false; | |
region.setCursor(Cursor.DEFAULT); | |
} | |
protected void mouseOver(MouseEvent event) { | |
if(isInDraggableZone(event) || dragging) { | |
region.setCursor(Cursor.S_RESIZE); | |
} | |
else { | |
region.setCursor(Cursor.DEFAULT); | |
} | |
} | |
protected boolean isInDraggableZone(MouseEvent event) { | |
return event.getY() > (region.getHeight() - RESIZE_MARGIN); | |
} | |
protected void mouseDragged(MouseEvent event) { | |
if(!dragging) { | |
return; | |
} | |
double mousey = event.getY(); | |
double newHeight = region.getMinHeight() + (mousey - y); | |
region.setMinHeight(newHeight); | |
y = mousey; | |
} | |
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 anyone is interested, I made a little modification to the code in order to obtain both height and width resizing.
You can finde the code here: https://gist.github.com/cannibalsticky/a3057d6e9c1f029d99e6bc95f9b3340e
Happy coding!
is there any way to resize a decorated stage proportionally in square form ?
Cool! This is what I am looking for.
I found that transition will give better performance, so instead of
region.setMinHeight(newHeight);
one can use something like:
Timeline timeline = new Timeline(
new KeyFrame(Duration.millis(1),
new KeyValue(region.minHeightProperty(), newHeight, Interpolator.EASE_BOTH))
);
timeline.play()
Here is a version that allows diagonal (as well as horizontal and vertical) resizing. I use it with my PopWindow class which, when using an AnchorPane as a container, results in a window can be dragged to move as well as to resize. It also has a title bar with a maximize/unmaximize button and a close button. It is also compatible with JPro.
Super nice DragResizer! I just make my stackpane FX node (, and all of its children FX nodes) perfectly resizable by add just one line: DragResizer.makeResizable(myStackpane);
Nice!