代码之家  ›  专栏  ›  技术社区  ›  Pooran

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

  •  -1
  • Pooran  · 技术社区  · 6 年前

    我正在学习如何在JavaFX中拖动鼠标时创建形状,我可以在拖动鼠标时创建形状,但当我更改鼠标时会出现问题 scaleX scaleY Group 包含该形状的。问题是,当我尝试在比例不是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时,绘制形状的正确方法是什么??

    1 回复  |  直到 3 年前
        1
  •  0
  •   Sarel Foyerlicht James_D    6 年前

    这不是最干净的方式,但仍然是一种方式,问题是很难计算规模对您的团队的影响(如果有人知道如何做到这一点,那将是非常好的),所以我绕过了它:

    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);
        }
    
    }
    
    推荐文章