当包含形状的组的比例不是默认值时,如何在JavaFX中绘制形状



我正在学习如何在JavaFX中拖动鼠标时创建形状,并且我可以在拖动鼠标时生成形状,但当我更改包含该形状的GroupscaleXscaleY时会出现问题。问题是,当我试图在比例不为1的情况下创建一个形状时,当我在代码中编写根据鼠标位置设置其转换值时,形状的位置会发生变化。我已经尝试过很多次解决这个问题,但我不知道为什么会发生这种情况,也不知道如何解决这个问题。

这是我的代码:

当拖动鼠标时,我正在使用代码修改Rectangle,称为object,但当我拖动鼠标时它的位置正在移动,保持比例不是1。再次澄清,我试图在拖动鼠标时创建矩形。但它的位置不是鼠标所在的位置,即当组的比例不为1时位置发生了移动。

import javafx.application.Application;
import javafx.geometry.Bounds;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.ScrollEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class Example extends Application{

private Group  group;
private double mousePointX;
private double mousePointY;

public static void main(String... arguments){ launch(arguments); }

@Override public void start(Stage primaryStage){

group = new Group();

Pane pane = new Pane(group);
pane.setOnMousePressed(this::recordPosition);
pane.setOnMouseDragged(this::makeShape);
pane.setOnScroll(this::handleScroll);

primaryStage.setScene(new Scene(new BorderPane(pane)));
primaryStage.show();
}

//record mouse position
private void recordPosition(MouseEvent event){
mousePointX = event.getX();
mousePointY = event.getY();
}

//method to make shape
private void makeShape(MouseEvent event){
Rectangle object;
object = new Rectangle(200, 200, Color.BLUE);
object.setStroke(Color.BLACK);

group.getChildren().addAll(object);

object.setTranslateX(mousePointX - group.getTranslateX());
object.setTranslateY(mousePointY - group.getTranslateY());
object.setHeight(event.getY() - mousePointY);
object.setWidth(event.getX() - mousePointX);
}

//method to control scroll
private void handleScroll(ScrollEvent event){
if(event.isControlDown()){
zoom(Math.pow(1.01, event.getDeltaY()), event.getSceneX(), event.getSceneY());
}else{
group.setTranslateX(this.group.getTranslateX() + event.getDeltaX());
group.setTranslateY(this.group.getTranslateY() + event.getDeltaY());
}
event.consume();
}

//method to control zoom
private void zoom(double factor, double x, double y){
double oldScale = group.getScaleX();
double scale    = oldScale * factor;

if(scale < 0.05) scale = 0.05;
if(scale > 50) scale = 50;

group.setScaleX(scale);
group.setScaleY(scale);

double f      = (scale / oldScale) - 1;
Bounds bounds = this.group.localToScene(this.group.getBoundsInLocal());
double dx     = (x - (bounds.getWidth() / 2 + bounds.getMinX()));
double dy     = (y - (bounds.getHeight() / 2 + bounds.getMinY()));

group.setTranslateX(this.group.getTranslateX() - f * dx);
group.setTranslateY(this.group.getTranslateY() - f * dy);
}

}

那么,当包含形状的组的比例不为1时,绘制形状的正确方法是什么??

请给我推荐。

不是最干净的方法,但仍然是一种方法,问题是很难计算Scale对您的团队的影响(如果有人知道如何做到这一点,那就太棒了),所以我绕过了它:

import javafx.application.Application;
import javafx.geometry.Bounds;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.ScrollEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import java.util.ArrayList;
import java.util.List;
public class MySolution extends Application{
List<Group> groups = new ArrayList<>();
private Group  group;
private Rectangle object ;
private Pane pane;
private double mousePointX;
private double mousePointY;
public static void main(String... arguments){ launch(arguments); }
@Override public void start(Stage primaryStage){
group = new Group();
pane = new Pane(group);
pane.setOnMousePressed(this::recordPosition);
pane.setOnMouseDragged(this::makeShape);
pane.setOnScroll(this::handleScroll);
primaryStage.setScene(new Scene(new BorderPane(pane)));
primaryStage.show();
}
//record mouse position
private void recordPosition(MouseEvent event){
mousePointX = event.getX();
mousePointY = event.getY();
object = new Rectangle(0, 0, Color.BLUE);
object.setStroke(Color.BLACK);
group.getChildren().addAll(object);
}
//method to make shape
private void makeShape(MouseEvent event){
if(object!=null){
object.setTranslateX(mousePointX - group.getTranslateX());
object.setTranslateY(mousePointY - group.getTranslateY());
object.setHeight(event.getY() - mousePointY);
object.setWidth(event.getX() - mousePointX);
}
}
//method to control scroll
private void handleScroll(ScrollEvent event){
if(event.isControlDown()){
zoom(Math.pow(1.01, event.getDeltaY()), event.getSceneX(), event.getSceneY());
}else{
group.setTranslateX(this.group.getTranslateX() + event.getDeltaX());
group.setTranslateY(this.group.getTranslateY() + event.getDeltaY());
for (Group g:groups) {
g.setTranslateX(g.getTranslateX() + event.getDeltaX());
g.setTranslateY(g.getTranslateY() + event.getDeltaY());
}
}
event.consume();
}
//method to control zoom
private void zoom(double factor, double x, double y){
groups.add(group);
for (Group g:groups) {
double oldScale = g.getScaleX();
double scale    = oldScale * factor;
if(scale < 0.05) scale = 0.05;
if(scale > 50) scale = 50;
g.setScaleX(scale);
g.setScaleY(scale);
double f      = (scale / oldScale) - 1;
Bounds bounds = g.localToScene(g.getBoundsInLocal());
double dx     = (x - (bounds.getWidth() / 2 + bounds.getMinX()));
double dy     = (y - (bounds.getHeight() / 2 + bounds.getMinY()));
g.setTranslateX(g.getTranslateX() - f * dx);
g.setTranslateY(g.getTranslateY() - f * dy);
}
group = new Group();
pane.getChildren().add(group);
}
}

最新更新