Reputation: 1678
I'm interested how I can resize this component with mouse drag:
VBox stackedTitledPanes = createStackedTitledPanes();
ScrollPane scroll = makeScrollable(stackedTitledPanes);
TabPane tabPane = new TabPane();
BorderPane mainPane = new BorderPane();
tabPane.setStyle("-fx-font-size: 12pt;"); // Set global size for the font
// Create Tabs
Tab tabA = new Tab();
tabA.setText("Main Component");
tabA.setStyle("-fx-font-size: 12pt;"); // Set size of the tab name
// Add something in Tab
StackPane tabA_stack = new StackPane();
tabA_stack.setAlignment(Pos.CENTER);
tabA_stack.getChildren().add(scroll);
tabA.setContent(tabA_stack);
tabPane.getTabs().add(tabA);
Tab tabB = new Tab();
tabB.setText("Second Component");
tabB.setStyle("-fx-font-size: 12pt;"); // Set size of the tab name
// Add something in Tab
StackPane tabB_stack = new StackPane();
tabB_stack.setAlignment(Pos.CENTER);
tabB_stack.getChildren().add(new Label("Label@Tab B"));
tabB.setContent(tabB_stack);
tabPane.getTabs().add(tabB);
Tab tabC = new Tab();
tabC.setText("Last Component");
tabC.setStyle("-fx-font-size: 12pt;"); // Set size of the tab name
// Add something in Tab
StackPane tabC_vBox = new StackPane();
tabC_vBox.setAlignment(Pos.CENTER);
tabC_vBox.getChildren().add(new Label("Label@Tab C"));
tabC.setContent(tabC_vBox);
tabPane.getTabs().add(tabC);
mainPane.setCenter(tabPane);
mainPane.setPrefSize(395, 580);
mainPane.setLayoutX(850);
mainPane.setLayoutY(32);
scroll.setPrefSize(395, 580);
scroll.setLayoutX(850);
scroll.setLayoutY(32);
root.getChildren().add(mainPane);
The problem is that I have several components placed on the main stage. When I resize one component for example increase the height of the component I have to reduce the size of the next component without stepping over the component. How I can do this?
Upvotes: 4
Views: 11179
Reputation: 1349
to make a Node resizable by mouse drag (my thoughts)
node_textArea_or_canvas
that you want to resize by mouse dragpanel_Wrapper
that wraps node_textArea_or_canvas
(not strictly required)handler_Resize
that is also wrapped inside panel_Wrapper
& is made make_Draggable()
handler_Resize
& drag it
handler_Resize.layoutXProperty().addListener((ChangeListener<Number>) (observable, oldValue, newValue) -> {
node_textArea_or_canvas.setPrefWidth((double) newValue);
});
package com.redfrog.note;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
import com.google.common.util.concurrent.AtomicDouble;
import com.redfrog.note.TestAppJavafxBoot.StageReadyEvent;
import javafx.beans.value.ChangeListener;
import javafx.geometry.Orientation;
import javafx.scene.Cursor;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
@Component
public class T1 implements ApplicationListener<StageReadyEvent> {
@Override
public void onApplicationEvent(StageReadyEvent stageReadyEvent) {
Stage primaryStage = stageReadyEvent.getStage();
FlowPane root = new FlowPane(Orientation.VERTICAL);
root.setMinSize(800, 800);
root.setStyle(""
+ "-fx-border-style: solid;"
+ "-fx-border-width: 1;"
+ "-fx-border-color: teal;");
AnchorPane panel_Wrapper = new AnchorPane();
panel_Wrapper.setStyle(""
+ "-fx-border-style: solid;"
+ "-fx-border-width: 1;"
+ "-fx-border-color: grey;");
TextArea node_textArea_or_canvas = new TextArea();
node_textArea_or_canvas.setPrefSize(300, 80);
node_textArea_or_canvas.appendText("(- After one button is clicked, then dont touch/click on any button anymore.)");
node_textArea_or_canvas.setWrapText(true);
// Canvas node_textArea_or_canvas = new Canvas();
// node_textArea_or_canvas.setWidth(300);
// node_textArea_or_canvas.setHeight(80);
//
// GraphicsContext graphicsContext = node_textArea_or_canvas.getGraphicsContext2D();
// graphicsContext.beginPath();
// graphicsContext.moveTo(20, 30);
// graphicsContext.lineTo(180, 260);
// graphicsContext.stroke();
panel_Wrapper.getChildren().add(node_textArea_or_canvas);
setup_Resizable(node_textArea_or_canvas, panel_Wrapper);
root.getChildren().add(panel_Wrapper);
primaryStage.setTitle("DrawAndChatApp - Session init Page");
primaryStage.setScene(new Scene(root, 650, 450));
primaryStage.show();
}
public void setup_Resizable(final /*Node*/ TextArea node_textArea_or_canvas, Pane panel_Wrapper) {
AnchorPane handler_Resize = new AnchorPane();
handler_Resize.setStyle(""
+ "-fx-border-style: solid;"
+ "-fx-border-width: 1;"
+ "-fx-border-color: grey;"); // let transparent ...
handler_Resize.setPrefSize(10, 10);
make_Draggable(handler_Resize, true);
// handler_Resize.setLayoutX(panel_Wrapper.getWidth());
// handler_Resize.setLayoutY(panel_Wrapper.getHeight()); // wont work cuz 0 // thought layer adding no, just 0
panel_Wrapper.getChildren().add(handler_Resize); // @note: layer pb ..?
handler_Resize.layoutXProperty().addListener((ChangeListener<Number>) (observable, oldValue, newValue) -> {
node_textArea_or_canvas.setPrefWidth((double) newValue);
// node_textArea_or_canvas.setWidth((double) newValue);
});
handler_Resize.layoutYProperty().addListener((ChangeListener<Number>) (observable, oldValue, newValue) -> {
node_textArea_or_canvas.setPrefHeight((double) newValue);
// node_textArea_or_canvas.setHeight((double) newValue);
});
// // can do sth like: listen to key event confirm then execute ... nah too much trouble // even undo is a thing ...
// // saying the conflict of event.comuse() too ... @pb ..
// Class<? extends Node> clazz = node_textArea_or_canvas.getClass();
// if (Region.class.isAssignableFrom(clazz)) {
// Region textArea = (Region) node_textArea_or_canvas;
// handler_Resize.addEventHandler(MouseEvent.MOUSE_PRESSED, event -> {
// if (!event.isConsumed()) {
// if (event.isControlDown() && event.isAltDown() && !event.isShiftDown() && event.isSecondaryButtonDown()) {
// event.consume();
// textArea.setPrefWidth(handler_Resize.getLayoutX());
// textArea.setPrefHeight(handler_Resize.getLayoutY());
// }
// }
// });
// }
// else if (Canvas.class.isAssignableFrom(clazz)) {
// Canvas canvas = (Canvas) node_textArea_or_canvas;
// handler_Resize.addEventHandler(MouseEvent.MOUSE_PRESSED, event -> {
// if (!event.isConsumed()) {
// if (event.isControlDown() && event.isAltDown() && !event.isShiftDown() && event.isSecondaryButtonDown()) {
// event.consume();
// canvas.setWidth(handler_Resize.getLayoutX());
// canvas.setHeight(handler_Resize.getLayoutY());
// }
// }
// });
// }
// else {
// throw new Error();
// }
}
public static void make_Draggable(final Node node, boolean det_PreventMovePassLeft) {
final AtomicDouble posX_offset = new AtomicDouble();
final AtomicDouble posY_offset = new AtomicDouble();
final AtomicDouble posX_ori = new AtomicDouble();
final AtomicDouble posY_ori = new AtomicDouble();
node.addEventHandler(MouseEvent.MOUSE_PRESSED, event -> {
if (!event.isConsumed()) {
if (event.isControlDown() && event.isAltDown() && !event.isShiftDown() && event.isPrimaryButtonDown()) {
event.consume();
double x = event.getSceneX();
double y = event.getSceneY();
posX_offset.set(node.getLayoutX() - x);
posY_offset.set(node.getLayoutY() - y);
node.setCursor(Cursor.HAND);
posX_ori.set(node.getLayoutX());
posY_ori.set(node.getLayoutY());
}
}
});
node.addEventHandler(MouseEvent.MOUSE_DRAGGED, event -> {
if (!event.isConsumed()) {
if (event.isControlDown() && event.isAltDown() && !event.isShiftDown() && event.isPrimaryButtonDown()) {
event.consume();
double x = event.getSceneX() + posX_offset.get();
double y = event.getSceneY() + posY_offset.get();
if (det_PreventMovePassLeft) {
if (x < 0) { x = 0; }
if (y < 0) { y = 0; }
}
node.setLayoutX(x);
node.setLayoutY(y);
node.setCursor(Cursor.MOVE);
}
}
});
}
}
resize a Canvas, may lost some Paint if you reduces its window size.
resize a TextArea, you can try Resizable Text Area demo/ResizableTextAreaApp.java in https://github.com/dlsc-software-consulting-gmbh/GemsFX
(btw, hotkey for drag in sample code is ctrl+alt+drag
...)
Upvotes: 0
Reputation: 1
Here is a modified version for the case of an upper and lower Region. If one Region grows the other one gets smaller.
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 top, bottom;
private double y;
private boolean initMinHeight;
private boolean dragging;
private double ySum;
private DragResizer(Region top, Region bottom) {
this.top = top;
this.bottom = bottom;
ySum = top.getPrefHeight() + bottom.getPrefHeight();
}
public static void makeResizable(Region top, Region bottom) {
final DragResizer resizer = new DragResizer(top, bottom);
top.setOnMousePressed(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
resizer.mousePressed(event);
}});
top.setOnMouseDragged(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
resizer.mouseDragged(event);
}});
top.setOnMouseMoved(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
resizer.mouseOver(event);
}});
top.setOnMouseReleased(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
resizer.mouseReleased(event);
}});
}
protected void mouseReleased(MouseEvent event) {
dragging = false;
top.setCursor(Cursor.DEFAULT);
}
protected void mouseOver(MouseEvent event) {
if(isInDraggableZone(event) || dragging) {
top.setCursor(Cursor.S_RESIZE);
}
else {
top.setCursor(Cursor.DEFAULT);
}
}
protected boolean isInDraggableZone(MouseEvent event) {
return event.getY() > (top.getHeight() - RESIZE_MARGIN);
}
protected void mouseDragged(MouseEvent event) {
if(!dragging) {
return;
}
double mousey = event.getY();
double dy = (mousey - y);
if(top.getMinHeight() + dy >= ySum || bottom.getPrefHeight() - dy >= ySum)
return;
top.setMinHeight(top.getMinHeight() + dy);
top.setPrefHeight(top.getPrefHeight() + dy);
bottom.setMinHeight(bottom.getMinHeight() - dy);
bottom.setPrefHeight(bottom.getPrefHeight() - dy);
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) {
top.setMinHeight(top.getHeight());
initMinHeight = true;
}
y = event.getY();
}
}
Upvotes: 0
Reputation: 3511
I think it is stack pane that is causing the problem, it does not support resize behaviour like VBox or HBox does. I am dragging in my own program to resize TextArea or List components to make them larger if necessary. Check out the code here:
and usage:
EDIT I have pulled EstiMate but the drag resizer is still open source in this gist.
https://gist.github.com/andytill/4369729
Or the full code.
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();
}
}
Upvotes: 5