0
사용자가 javafx에서 사각형을 끌거나 크기를 조정할 수 있도록 노력하고 있습니다. javafx의 직사각형은 TopLeft-X, Y, 높이 및 너비로 그립니다.JavaFx - 사각형 크기 조정
내가하려는 것은 사용자가 핸들을 끌 수 있도록 사각형의 각 구석에 4 개의 핸들을 갖는 것입니다. 사각형의 크기가 변경됩니다.
내 응용 프로그램은 리스너의 재귀 호출로 인해 발생하는 것으로 알고있는 stackoverflow 예외를 throw합니다.
내가 뭔가를 잊었습니까? 아니면 불필요한 청취자가 있습니까?
public class Handler extends Circle
{
private double deltaX;
private double deltaY;
private static final double DEFAULT_RADIUS = 10;
private static final Color DEFAULT_COLOR = Color.GOLD;
private DoubleProperty xProperty;
private DoubleProperty yProperty;
public Handler(DoubleProperty xProperty, DoubleProperty yProperty)
{
super(DEFAULT_RADIUS, DEFAULT_COLOR);
this.xProperty = xProperty;
this.yProperty = yProperty;
init();
}
private void init()
{
setFill(DEFAULT_COLOR.deriveColor(1, 1, 1, 0.5));
setStroke(DEFAULT_COLOR);
setStrokeWidth(2);
setStrokeType(StrokeType.OUTSIDE);
centerXProperty().bind(xProperty);
centerYProperty().bind(yProperty);
setOnMousePressed(new EventHandler<MouseEvent>()
{
@Override
public void handle(MouseEvent mouseEvent)
{
mouseEvent.consume();
deltaX = getCenterX() - mouseEvent.getX();
deltaY = getCenterY() - mouseEvent.getY();
getScene().setCursor(javafx.scene.Cursor.MOVE);
}
});
setOnMouseReleased(new EventHandler<MouseEvent>()
{
@Override
public void handle(MouseEvent mouseEvent)
{
getScene().setCursor(javafx.scene.Cursor.HAND);
}
});
setOnMouseEntered(new EventHandler<MouseEvent>()
{
@Override
public void handle(MouseEvent mouseEvent)
{
if (!mouseEvent.isPrimaryButtonDown())
{
getScene().setCursor(javafx.scene.Cursor.HAND);
}
}
});
setOnMouseExited(new EventHandler<MouseEvent>()
{
@Override
public void handle(MouseEvent mouseEvent)
{
if (!mouseEvent.isPrimaryButtonDown())
{
getScene().setCursor(javafx.scene.Cursor.DEFAULT);
}
}
});
setOnMouseDragged(new EventHandler<MouseEvent>()
{
@Override
public void handle(MouseEvent mouseEvent)
{
double newX = mouseEvent.getX() + deltaX;
double newY = mouseEvent.getY() + deltaY;
if (newX > 0 && newX < getScene().getWidth())
{
xProperty.set(newX);
}
if (newY > 0 && newY < getScene().getHeight())
{
yProperty.set(newY);
}
}
});
}
//JavaFx Accessor and mutator
}
public class CustomRectangle extends Rectangle
{
private DoubleProperty topRightX;
private DoubleProperty topRightY;
private DoubleProperty btmLeftX;
private DoubleProperty btmLeftY;
private DoubleProperty btmRightX;
private DoubleProperty btmRightY;
private DoubleProperty customeWidth;
private DoubleProperty customHeight;
public CustomRectangle()
{
super();
init();
}
public CustomRectangle(double x, double y, double width, double height)
{
super(x, y, width, height);
init();
}
public CustomRectangle(double width, double height, Paint fill)
{
super(width, height, fill);
init();
}
public CustomRectangle(double width, double height)
{
super(width, height);
init();
}
private void init()
{
topRightX = new SimpleDoubleProperty();
topRightY = new SimpleDoubleProperty();
btmLeftX = new SimpleDoubleProperty();
btmLeftY = new SimpleDoubleProperty();
btmRightX = new SimpleDoubleProperty();
btmRightY = new SimpleDoubleProperty();
topRightX.addListener((observable, oldValue, newValue) ->
{
this.setWidth(this.getWidth() + (newValue.doubleValue() - oldValue.doubleValue()));
});
topRightY.addListener((observable, oldValue, newValue) ->
{
this.setY(newValue.doubleValue());
this.setHeight(this.getHeight() - (newValue.doubleValue() - oldValue.doubleValue()));
});
btmLeftX.addListener((observable, oldValue, newValue) ->
{
this.setX(newValue.doubleValue());
this.setWidth(this.getWidth() - (newValue.doubleValue() - oldValue.doubleValue()));
});
btmLeftY.addListener((observable, oldValue, newValue) ->
{
this.setY(newValue.doubleValue());
this.setHeight(this.getHeight() + (newValue.doubleValue() - oldValue.doubleValue()));
});
btmRightX.addListener((observable, oldValue, newValue) ->
{
this.setWidth(this.getWidth() + (newValue.doubleValue() - oldValue.doubleValue()));
});
btmRightY.addListener((observable, oldValue, newValue) ->
{
this.setHeight(this.getHeight() + (newValue.doubleValue() - oldValue.doubleValue()));
});
this.xProperty().addListener((observable, oldValue, newValue) ->
{
btmLeftX.set(newValue.doubleValue());
topRightX.set(newValue.doubleValue() + this.getWidth());
btmRightX.set(newValue.doubleValue() + this.getWidth());
});
this.yProperty().addListener((observable, oldValue, newValue) ->
{
btmLeftY.set(newValue.doubleValue() + this.getHeight());
topRightY.set(newValue.doubleValue());
btmRightY.set(newValue.doubleValue() + this.getHeight());
});
this.widthProperty().addListener((observable, oldValue, newValue) ->
{
topRightX.set(this.getX() + (newValue.doubleValue() - oldValue.doubleValue()));
btmRightX.set(this.getX() + (newValue.doubleValue() - oldValue.doubleValue()));
});
this.heightProperty().addListener((observable, oldValue, newValue) ->
{
btmLeftY.set(this.getY() + (newValue.doubleValue() - oldValue.doubleValue()));
btmRightY.set(this.getY() + (newValue.doubleValue() - oldValue.doubleValue()));
});
}
//JavaFx Accessor and Mutator
}
public class FeatureHelper
{
private static double orgSceneX;
private static double orgSceneY;
private static double orgTranslateX;
private static double orgTranslateY;
public static CustomRectangle createDraggableRectangle(double x, double y, double width, double height,
boolean resizeImage)
{
CustomRectangle rect = new CustomRectangle(x, y, width, height);
// top left resize handle:
Handler topLeftHandle = new Handler(rect.topLeftXProperty(), rect.topLeftYProperty());
// top right resize handle:
Handler topRightHandle = new Handler(rect.topRightXProperty(), rect.topRightYProperty());
// bottom left resize handle:
Handler btmLeftHandle = new Handler(rect.btmLeftXProperty(), rect.btmLeftYProperty());
// bottom right resize handle:
Handler btmRightHandle = new Handler(rect.btmRightXProperty(), rect.btmRightYProperty());
// force circles to live in same parent as rectangle:
rect.parentProperty().addListener((obs, oldParent, newParent) ->
{
for (Circle c : Arrays.asList(topLeftHandle, topRightHandle, btmLeftHandle, btmRightHandle))
{
if (newParent != null)
{
((Pane) newParent).getChildren().add(c);
}
}
});
rect.setOnMousePressed(event ->
{
event.consume();
orgSceneX = event.getSceneX();
orgSceneY = event.getSceneY();
Node p = ((Node) (event.getSource()));
orgTranslateX = p.getTranslateX();
orgTranslateY = p.getTranslateY();
});
rect.setOnMouseDragged(event ->
{
double offsetX = event.getSceneX() - orgSceneX;
double offsetY = event.getSceneY() - orgSceneY;
double newTranslateX = orgTranslateX + offsetX;
double newTranslateY = orgTranslateY + offsetY;
Node p = ((Node) (event.getSource()));
p.setTranslateX(newTranslateX);
p.setTranslateY(newTranslateY);
for(Circle circle : Arrays.asList(topLeftHandle, topRightHandle, btmLeftHandle, btmRightHandle))
{
circle.setTranslateX(newTranslateX);
circle.setTranslateY(newTranslateY);
}
});
return rect;
}
}