所以,我的橡皮筋课上有一个错误,我似乎无法修复。
我基本上要做的是:我有一个borderpane,它是
我要调整大小的节点的外部窗格。我为该borderpane分配了一个宽度为1
像素的边框(查看CSS)。我还为该边框窗格分配了四个矩形,每个矩形位于一个
角(NE,SE,SW,NW)。在此边框中,我具有所谓的
“ contentPane”。该窗格包含所有内容(矩形,
图像视图等)。
它工作得很好,但是我似乎无法修复错误。
错误:
如果我调整一个像素的大小,则宽度,高度/ x和y会使用
未知值进行调整。之后,调整大小就可以了。在此处输入图片说明
RubberBand2.java
package org.displee.javafx.mod;
import javafx.scene.Cursor;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
/**
* A class representing a rubberband that can be used to resize panes.
* @author Displee
*/
public class RubberBand2 {
/**
* The parent of this rectangle.
*/
private final Pane parent;
/**
* The rectangle.
*/
private final Pane node;
/**
* The corner rectangles.
*/
private final Rectangle[] rectangles = new Rectangle[4];
/**
* The last known node width.
*/
private double nodeWidth;
/**
* The last known node height.
*/
private double nodeHeight;
/**
* The last known node x-coordinate.
*/
private double nodeX;
/**
* The last known node y-coordinate.
*/
private double nodeY;
/**
* The current selected component.
*/
public static RubberBand2 SELECTED;
/**
* The size of the corners of a rectangle.
*/
public static final double RECTANGLE_CORNER_SIZE = 5.0;
/**
* The minimum width of the {@code node}.
*/
private static final double MIN_WIDTH = 10.0;
/**
* The minimum height of the {@code node}
*/
private static final double MIN_HEIGHT = 10.0;
public RubberBand2(Pane node) {
this.node = node;
this.parent = (Pane) node.getParent();
parent.getStyleClass().add("transparent_border");
createCorners();
bind();
}
/**
* Create the corners.
*/
public void createCorners() {
final Pane inheritPane = node;
for (int i = 0; i < rectangles.length; i++) {
final Rectangle rectangle = rectangles[i] = new Rectangle();
rectangle.setWidth(RECTANGLE_CORNER_SIZE);
rectangle.setHeight(RECTANGLE_CORNER_SIZE);
rectangle.setFill(Color.BLACK);
rectangle.getStyleClass().add("rectangle_corner");
rectangle.setArcHeight(4);
rectangle.setArcWidth(4);
if (i == 0) {
rectangle.xProperty().bind(inheritPane.layoutXProperty().subtract(RECTANGLE_CORNER_SIZE));
rectangle.yProperty().bind(inheritPane.layoutYProperty().subtract(RECTANGLE_CORNER_SIZE));
rectangle.setOnMouseEntered((e) -> {
rectangle.setCursor(Cursor.NW_RESIZE);
});
rectangle.setOnMouseDragged((event) -> {
resize(event, 0);
});
} else if (i == 1) {
rectangle.xProperty().bind(inheritPane.layoutXProperty().add(inheritPane.widthProperty()));
rectangle.yProperty().bind(inheritPane.layoutYProperty().subtract(RECTANGLE_CORNER_SIZE));
rectangle.setOnMouseEntered((e) -> {
rectangle.setCursor(Cursor.NE_RESIZE);
});
rectangle.setOnMouseDragged((event) -> {
resize(event, 1);
});
} else if (i == 2) {
rectangle.xProperty().bind(inheritPane.layoutXProperty().add(inheritPane.widthProperty()));
rectangle.yProperty().bind(inheritPane.layoutYProperty().add(inheritPane.heightProperty()));
rectangle.setOnMouseEntered((e) -> {
rectangle.setCursor(Cursor.SE_RESIZE);
});
rectangle.setOnMouseDragged((event) -> {
resize(event, 2);
});
} else {
rectangle.xProperty().bind(inheritPane.layoutXProperty().subtract(RECTANGLE_CORNER_SIZE));
rectangle.yProperty().bind(inheritPane.layoutYProperty().add(inheritPane.heightProperty()));
rectangle.setOnMouseEntered((e) -> {
rectangle.setCursor(Cursor.SW_RESIZE);
});
rectangle.setOnMouseDragged((event) -> {
resize(event, 3);
});
}
rectangle.setOnMousePressed((e) -> {
setDefaults();
e.consume();
});
rectangle.setVisible(false);
parent.getChildren().add(rectangle);
}
}
/**
* Bind the mouse events.
*/
public void bind() {
node.setOnMouseEntered((e) -> {
node.setCursor(Cursor.MOVE);
});
parent.setOnMouseClicked((e) -> {
if (SELECTED != null) {
SELECTED.setRubberBandSelection(false);
}
SELECTED = this;
setRubberBandSelection(true);
e.consume();
});
node.setOnMouseClicked((e) -> {
if (SELECTED != null) {
SELECTED.setRubberBandSelection(false);
}
SELECTED = this;
setRubberBandSelection(true);
e.consume();
});
node.setOnMousePressed((e) -> {
setDefaults();
e.consume();
});
node.setOnMouseMoved((e) -> {
});
node.setOnMouseReleased((e) -> {
});
}
/**
* Resize the argued resize type.
* @param event The mouse event
* @param type The type (0 = NW, 1 = NE, 2 = SE, 3 = SW);
*/
public void resize(MouseEvent event, int type) {
final double mouseX = parent.getBoundsInParent().getMinX() + event.getX();
final double mouseY = parent.getBoundsInParent().getMinY() + event.getY();
double newX = nodeX;
double newY = nodeY;
double newW = nodeWidth;
double newH = nodeHeight;
switch (type) {
case 0:
newX = mouseX;
newY = mouseY;
newW = nodeWidth + nodeX - newX;
newH = nodeHeight + nodeY - newY;
break;
case 1:
newY = mouseY;
newW = mouseX - nodeX;
newH = nodeHeight + nodeY - newY;
break;
case 2:
newW = mouseX - nodeX;
newH = mouseY - nodeY;
break;
case 3:
newX = mouseX;
newW = nodeWidth + nodeX - newX;
newH = mouseY - nodeY;
break;
}
parent.setLayoutX(newX);
parent.setLayoutY(newY);
node.setPrefSize(newW, newH);
}
/**
* Set the defaults before we resize anything.
*/
public void setDefaults() {
nodeX = node.getBoundsInParent().getMinX();
nodeY = node.getBoundsInParent().getMinY();
nodeHeight = node.getBoundsInParent().getHeight();
nodeWidth = node.getBoundsInParent().getWidth();
}
/**
* Set the rubber band selection for the rectangle.
* @param show If we have to show the corner rectangles.
*/
public void setRubberBandSelection(boolean show) {
if (show) {
parent.getStyleClass().remove("transparent_border");
parent.getStyleClass().add("dotted_pane");
} else {
parent.getStyleClass().remove("dotted_pane");
parent.getStyleClass().add("transparent_border");
}
for (Rectangle rectangle : rectangles) {
rectangle.setVisible(show);
}
}
}
style.css
.dotted_pane {
-fx-background-insets: 0;
-fx-border-color: white;
-fx-border-width: 1;
-fx-border-style: dashed;
}
.transparent_border {
-fx-background-insets: 0;
-fx-border-color: transparent;
-fx-border-width: 1;
-fx-border-style: solid;
}
Test2.java
package org.test;
import org.displee.javafx.mod.RubberBand2;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.Border;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.BorderStroke;
import javafx.scene.layout.BorderStrokeStyle;
import javafx.scene.layout.BorderWidths;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class Test2 extends Application {
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
Group root = new Group();
Scene scene = new Scene(root, 900, 600);
Pane inner = new Pane();
inner.setBackground(new Background(new BackgroundFill(Color.web("red"), CornerRadii.EMPTY, Insets.EMPTY)));
BorderPane border = new BorderPane(inner);
inner.setPrefSize(100, 100);
border.setBorder(new Border(new BorderStroke(Color.BLUE, BorderStrokeStyle.SOLID, CornerRadii.EMPTY, BorderWidths.DEFAULT)));
Pane outer = new Pane(border);
outer.layoutXProperty().bind(scene.widthProperty().divide(4));
outer.layoutYProperty().bind(scene.heightProperty().divide(4));
root.getChildren().addAll(outer);
primaryStage.setScene(scene);
primaryStage.show();
new RubberBand2(inner);
}
}
Any suggestions and improvements are of course much appreciated.
Edit: Sorry, my documentation is pretty outdated xD.
Thanks.