I'm creating UI editor and for that I need to draw UI components on mouse events. I'm stuck on drawing button with caption inside of it. As a result of my searches over stackoverflow I tried to use StackPane for creating Rectangle with caption. For layout I'm using Group element. The problem is, when I add StackPane to the Group it's being displayed on the top left corner of the Group. However, if I draw just Rectangle itself, it's being displayed on that place, where I'm releasing the mouse. How to achieve the same effect for StackPane?
Here is my code:
public class Main extends Application {
double startingPointX, startingPointY;
Group rectanglesGroup = new Group();
Rectangle newRectangle = null;
boolean newRectangleIsBeingDrawn = false;
// the following method adjusts coordinates so that the rectangle
// is shown "in a correct way" in relation to the mouse event
void adjustRectanglePRoperties(double startingPointX,
double startingPointY, double endingPointX, double endingPointY,
Rectangle givenRectangle) {
givenRectangle.setX(startingPointX);
givenRectangle.setY(startingPointY);
givenRectangle.setWidth(endingPointX - startingPointX);
givenRectangle.setHeight(endingPointY - startingPointY);
if (givenRectangle.getWidth() < 0) {
givenRectangle.setWidth(-givenRectangle.getWidth());
givenRectangle.setX(givenRectangle.getX()
- givenRectangle.getWidth());
}
if (givenRectangle.getHeight() < 0) {
givenRectangle.setHeight(-givenRectangle.getHeight());
givenRectangle.setY(givenRectangle.getY()
- givenRectangle.getHeight());
}
}
@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Drawing rectangles");
Scene scene = new Scene(rectanglesGroup, 800, 600);
scene.setFill(Color.BEIGE);
scene.setOnMousePressed(e -> {
if (newRectangleIsBeingDrawn == false) {
startingPointX = e.getSceneX();
startingPointY = e.getSceneY();
newRectangle = new Rectangle();
// a non finished rectangle has always the same color
newRectangle.setFill(Color.SNOW); // almost white color
//Line line = new Line(20,120,270,120);
newRectangle.setStroke(Color.BLACK);
newRectangle.setStrokeWidth(1);
newRectangle.getStrokeDashArray().addAll(3.0, 7.0, 3.0, 7.0);
rectanglesGroup.getChildren().add(newRectangle);
newRectangleIsBeingDrawn = true;
}
});
scene.setOnMouseDragged(e -> {
if (newRectangleIsBeingDrawn == true) {
double currentEndingPointX = e.getSceneX();
double currentEndingPointY = e.getSceneY();
adjustRectanglePRoperties(startingPointX, startingPointY,
currentEndingPointX, currentEndingPointY, newRectangle);
}
});
scene.setOnMouseReleased(e->{
if(newRectangleIsBeingDrawn == true){
//now the drawing of the new rectangle is finished
//let's set the final color for the rectangle
/******************Drawing textbox*******************************/
//newRectangle.setFill(Color.WHITE);
//newRectangle.getStrokeDashArray().removeAll(3.0, 7.0, 3.0, 7.0);
/****************************************************************/
/*****************Drawing button*********************************/
Image image = new Image("file:button.png");
ImagePattern buttonImagePattern = new ImagePattern(image);
newRectangle.setFill(buttonImagePattern);
newRectangle.setStroke(Color.WHITE);
newRectangle.getStrokeDashArray().removeAll(3.0,7.0,3.0,7.0);
Text text = new Text("Button");
rectanglesGroup.getChildren().remove(newRectangle);
StackPane stack = new StackPane();
stack.getChildren().addAll(newRectangle, text);
rectanglesGroup.getChildren().add(stack);
/****************************************************************/
colorIndex++; //index for the next color to use
//if all colors have been used we'll start re-using colors
//from the beginning of the array
if(colorIndex>=rectangleColors.length){
colorIndex=0;
}
newRectangle=null;
newRectangleIsBeingDrawn=false;
}
});
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
I'm using OnMouseReleased event to create components.
I looked for the setX, setPosition or something like this methods, but couldn't find them in StackPane's methods. And I don't know how translate methods work. So I didn't try them to achieve my goal.