Javafx 2 为什么我的放大镜跟不上鼠标?

Javafx 2 为什么我的放大镜跟不上鼠标?,javafx-2,Javafx 2,我正在尝试将JavaFX1.3放大镜示例迁移到JavaFX2.0,但我遇到了一个问题 我可能已经失明了,但我真的不明白,为什么玻璃团体不跟着老鼠 代码如下: package javafxapplication18; import javafx.application.Application; import javafx.beans.binding.BooleanBinding; import javafx.beans.binding.DoubleBinding; import javafx.b

我正在尝试将JavaFX1.3放大镜示例迁移到JavaFX2.0,但我遇到了一个问题

我可能已经失明了,但我真的不明白,为什么玻璃团体不跟着老鼠

代码如下:

package javafxapplication18;

import javafx.application.Application;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.binding.DoubleBinding;
import javafx.beans.binding.ObjectBinding;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.event.EventHandler;
import javafx.geometry.Rectangle2D;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.effect.DropShadow;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class JavaFXApplication18 extends Application {

    private ImageView bgImageView = new ImageView();
    private Image image;
    private Scene scene;
    private DoubleProperty magnification = new SimpleDoubleProperty();
    private DoubleProperty GLASS_SIZE = new SimpleDoubleProperty();
    private DoubleProperty GLASS_CENTER = new SimpleDoubleProperty();
    private DoubleProperty centerX = new SimpleDoubleProperty();
    private DoubleProperty centerY = new SimpleDoubleProperty();
    private DoubleProperty factor = new SimpleDoubleProperty();
    private DoubleProperty viewportCenterX = new SimpleDoubleProperty();
    private DoubleProperty viewportCenterY = new SimpleDoubleProperty();
    private DoubleProperty viewportSize = new SimpleDoubleProperty();
    private ImageView magGlass = new ImageView();
    private Group glassGroup = new Group();
    private Text desc = new Text();

    /**
    * @param args the command line arguments
    */
    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        DoubleBinding db = new DoubleBinding() {

            {
                super.bind(centerX, factor);
            }

            @Override
            protected double computeValue() {
                return centerX.get() * factor.get();
            }
        };
        DoubleBinding db2 = new DoubleBinding() {

            {
                super.bind(centerY, factor);
            }

            @Override
            protected double computeValue() {
                return centerY.get() * factor.get();
            }
        };
        viewportCenterX.bind(db);
        viewportCenterY.bind(db2);
        image = new Image(this.getClass().getResourceAsStream("/SANY0194.jpg"));

        StackPane root = new StackPane();
        scene = new Scene(root, 900, 700);

        setupBgImageView();
        setupFactor();
        setupGLASS_SIZE();
        magnification.setValue(1.5);

        DoubleBinding db3 = new DoubleBinding() {

            {
                super.bind(GLASS_SIZE, factor, magnification);
            }

            @Override
            protected double computeValue() {
                return GLASS_SIZE.get() * factor.get() / magnification.get();
            }
        };
        viewportSize.bind(db3);
        setupMagGlass();
        setupGlassGroup();
        setupDesc();
        bgImageView.requestFocus();
        primaryStage.setTitle("Magnifying Glass");
        primaryStage.setWidth(image.getWidth() / 2);
        primaryStage.setHeight(image.getHeight() / 2);


        root.getChildren().addAll(bgImageView, glassGroup, desc);

        primaryStage.setScene(scene);
        primaryStage.show();

        //style: StageStyle.UNDECORATED


    }

    public void adjustMagnification(final double amount) {
        DoubleProperty newMagnification = new SimpleDoubleProperty();
        DoubleBinding db3 = new DoubleBinding() {

            {
                super.bind(magnification);
            }

            @Override
            protected double computeValue() {
                if (magnification.get() + amount / 4 < .5) {
                    return .5;
                } else if (magnification.get() + amount / 4 > 10) {
                    return 10;
                } else {
                    return magnification.get() + amount / 4;
                }
            }
        };
        newMagnification.bind(db3);
        magnification.setValue(newMagnification.getValue());
    }

    private void setupGLASS_SIZE() {
        DoubleBinding db = new DoubleBinding() {

            {
                super.bind(bgImageView.boundsInLocalProperty());
            }

            @Override
            protected double computeValue() {
                return bgImageView.boundsInLocalProperty().get().getWidth() / 4;
            }
        };
        GLASS_SIZE.bind(db);
        DoubleBinding db1 = new DoubleBinding() {

            {
                super.bind(GLASS_SIZE);
            }

            @Override
            protected double computeValue() {
                return GLASS_SIZE.get() / 2;
            }
        };
        GLASS_CENTER.bind(db1);
    }

    private void setupFactor() {
        DoubleBinding db = new DoubleBinding() {

            {
                super.bind(image.heightProperty(), bgImageView.boundsInLocalProperty());
            }

            @Override
            protected double computeValue() {
                return image.heightProperty().get() / bgImageView.boundsInLocalProperty().get().getHeight();
            }
        };

        factor.bind(db);

    }

    private void setupBgImageView() {
        bgImageView.setImage(image);
        bgImageView.fitWidthProperty().bind(scene.widthProperty());
        bgImageView.fitHeightProperty().bind(scene.heightProperty());

        BooleanBinding bb = new BooleanBinding() {

            {
                super.bind(factor);
            }

            @Override
            protected boolean computeValue() {
                if (factor.get() != 1.0) {
                    return true;
                } else {
                    return false;
                }
            }
        };
        bgImageView.cacheProperty().bind(bb);

        bgImageView.setSmooth(true);
        bgImageView.setPreserveRatio(true);
        bgImageView.setOnMouseMoved(new EventHandler<MouseEvent>() {

            @Override
            public void handle(MouseEvent me) {
                centerX.setValue(me.getX());
                centerY.setValue(me.getY());
            }
        });
        bgImageView.setOnKeyPressed(new EventHandler<KeyEvent>() {

            @Override
            public void handle(KeyEvent ke) {
                if (ke.getCode() == KeyCode.EQUALS || ke.getCode() == KeyCode.PLUS) {
                    adjustMagnification(1.0);
                } else if (ke.getCode() == KeyCode.MINUS) {
                    adjustMagnification(-1.0);
                }
            }
        });


        bgImageView.impl_setOnMouseWheelRotated(new EventHandler<MouseEvent>() {

            @Override
            public void handle(MouseEvent me) {
                adjustMagnification(me.impl_getWheelRotation());
            }
        });


        bgImageView.setOnMouseClicked(new EventHandler<MouseEvent>() {

            @Override
            public void handle(MouseEvent me) {
                if (me.getButton() != MouseButton.PRIMARY) {
                    magGlass.setSmooth(magGlass.isSmooth());
                }
                bgImageView.requestFocus();
            }
        });


    }

    private void setupMagGlass() {
        magGlass.setImage(image);
        magGlass.setPreserveRatio(true);
        magGlass.fitWidthProperty().bind(GLASS_SIZE);
        magGlass.fitHeightProperty().bind(GLASS_SIZE);
        magGlass.setSmooth(true);
        ObjectBinding ob = new ObjectBinding() {

            {
                super.bind(viewportCenterX, viewportSize, viewportCenterY);
            }

            @Override
            protected Object computeValue() {
                return new Rectangle2D(viewportCenterX.get() - viewportSize.get() / 2, (viewportCenterY.get() - viewportSize.get() / 2), viewportSize.get(), viewportSize.get());
            }
        };
        magGlass.viewportProperty().bind(ob);
        Circle clip = new Circle();
        clip.centerXProperty().bind(GLASS_CENTER);
        clip.centerYProperty().bind(GLASS_CENTER);
        DoubleBinding db1 = new DoubleBinding() {

            {
                super.bind(GLASS_CENTER);
            }

            @Override
            protected double computeValue() {
                return GLASS_CENTER.get() - 5;
            }
        };
        clip.radiusProperty().bind(db1);
        magGlass.setClip(clip);

    }

    private void setupGlassGroup() {

        DoubleBinding db = new DoubleBinding() {

            {
                super.bind(centerX, GLASS_CENTER);
            }

            @Override
            protected double computeValue() {
                return centerX.get() - GLASS_CENTER.get();
            }
        };
        DoubleBinding db2 = new DoubleBinding() {

            {
                super.bind(centerY, GLASS_CENTER);
            }

            @Override
            protected double computeValue() {
                return centerY.get() - GLASS_CENTER.get();
            }
        };

        System.out.println("glassGroup.getLayoutX() " + glassGroup.getLayoutX());
        System.out.println("glassGroup.getLayoutY() " + glassGroup.getLayoutY());
        glassGroup.translateXProperty().bind(db);
        glassGroup.translateYProperty().bind(db2);

        Text text = new Text();
        DoubleBinding db3 = new DoubleBinding() {

            {
                super.bind(GLASS_CENTER);
            }

            @Override
            protected double computeValue() {
                return GLASS_CENTER.get() + GLASS_CENTER.get() / 2;
            }
        };
        text.xProperty().bind(db3);
        text.yProperty().bind(GLASS_SIZE);
        text.setText("x{%2.2f magnification}");
        Circle circle = new Circle();
        circle.centerXProperty().bind(GLASS_CENTER);
        circle.centerYProperty().bind(GLASS_CENTER);
        DoubleBinding db4 = new DoubleBinding() {

            {
                super.bind(GLASS_CENTER);
            }

            @Override
            protected double computeValue() {
                return GLASS_CENTER.get() - 2;
            }
        };
        circle.radiusProperty().bind(db4);
        circle.setStroke(Color.GREEN);
        circle.setStrokeWidth(3);
        circle.setFill(null);
        glassGroup.getChildren().addAll(magGlass, text, circle);
        DropShadow dropShadow = new DropShadow();
        dropShadow.setOffsetY(4);
        glassGroup.setEffect(dropShadow);

    }

    private void setupDesc() {
        desc.setX(10);
        desc.setY(15);
        if (!bgImageView.isFocused()) {
            desc.setText("Click image to focus");
        } else {
            desc.setText("Use the +/- or mouse wheel to zoom. Right-click to make the magnification "
                    + "{if (magGlass.smooth)   less smooth. else more smooth.}");
        }
        desc.setFont(new Font(12));
    }
}
PackageJavaFXApplication18;
导入javafx.application.application;
导入javafx.beans.binding.BooleanBinding;
导入javafx.beans.binding.DoubleBinding;
导入javafx.beans.binding.ObjectBinding;
导入javafx.beans.property.DoubleProperty;
导入javafx.beans.property.SimpleDoubleProperty;
导入javafx.event.EventHandler;
导入javafx.geometry.Rectangle2D;
导入javafx.scene.Group;
导入javafx.scene.scene;
导入javafx.scene.effect.DropShadow;
导入javafx.scene.image.image;
导入javafx.scene.image.ImageView;
导入javafx.scene.input.KeyCode;
导入javafx.scene.input.KeyEvent;
导入javafx.scene.input.MouseButton;
导入javafx.scene.input.MouseEvent;
导入javafx.scene.layout.StackPane;
导入javafx.scene.paint.Color;
导入javafx.scene.shape.Circle;
导入javafx.scene.text.Font;
导入javafx.scene.text.text;
导入javafx.stage.stage;
公共类JavaFXApplication18扩展了应用程序{
私有ImageView bgImageView=新建ImageView();
私有图像;
私密场景;
私有DoubleProperty放大率=新的SimpleDoubleProperty();
私有DoubleProperty GLASS_SIZE=新的SimpleDoubleProperty();
private DoubleProperty GLASS_CENTER=新的SimpleDoubleProperty();
私有DoubleProperty centerX=新的SimpleDoubleProperty();
private DoubleProperty centerY=新的SimpleDoubleProperty();
私有DoubleProperty因子=新的SimpleDoubleProperty();
私有DoubleProperty viewportCenterX=新的SimpleDoubleProperty();
私有DoubleProperty viewportCenterY=新的SimpleDoubleProperty();
private DoubleProperty viewportSize=新的SimpleDoubleProperty();
私有ImageView magGlass=新ImageView();
私有组glassGroup=新组();
私有文本描述=新文本();
/**
*@param指定命令行参数
*/
公共静态void main(字符串[]args){
发射(args);
}
@凌驾
公共无效开始(阶段primaryStage){
DoubleBinding db=新的DoubleBinding(){
{
super.bind(centerX,factor);
}
@凌驾
受保护的双计算值(){
返回centerX.get()*factor.get();
}
};
DoubleBinding db2=新的DoubleBinding(){
{
超级绑定(中心,因子);
}
@凌驾
受保护的双计算值(){
return centerY.get()*factor.get();
}
};
viewportCenterX.bind(db);
bind(db2);
image=新图像(this.getClass().getResourceAsStream(“/SANY0194.jpg”);
StackPane root=新的StackPane();
场景=新场景(根,900700);
setupBgImageView();
设置因子();
设置玻璃_尺寸();
放大率。设定值(1.5);
DoubleBinding db3=新的DoubleBinding(){
{
超级绑定(玻璃尺寸、系数、放大倍数);
}
@凌驾
受保护的双计算值(){
返回玻璃大小.get()*因子.get()/放大率.get();
}
};
bind(db3);
(玻璃);
组();
setupDesc();
bgImageView.requestFocus();
初级阶段。设置标题(“放大镜”);
primaryStage.setWidth(image.getWidth()/2);
primaryStage.setHeight(image.getHeight()/2);
root.getChildren().addAll(bgImageView,glassGroup,desc);
初级阶段。场景(场景);
primaryStage.show();
//风格:舞台风格。未装饰
}
公共放大倍数(最终双倍金额){
DoubleProperty new放大=新的SimpleDoubleProperty();
DoubleBinding db3=新的DoubleBinding(){
{
超级绑定(放大);
}
@凌驾
受保护的双计算值(){
if(放大倍数get()+数量/4<.5){
回报5;
}else if(放大倍数get()+数量/4>10){
返回10;
}否则{
返回放大倍数。get()+金额/4;
}
}
};
新放大率绑定(db3);
放大率.setValue(new放大率.getValue());
}
专用空心玻璃(U尺寸)(){
DoubleBinding db=新的DoubleBinding(){
{
super.bind(bgImageView.boundsInLocalProperty());
}
@凌驾
受保护的双计算值(){
返回bgImageView.boundsInLocalProperty().get().getWidth()/4;
}
};
玻璃尺寸绑定(db);
DoubleBinding db1=新的DoubleBinding(){
{
超级绑定(玻璃尺寸);
}
@凌驾
受保护的双计算值(){
返回玻璃大小。get()/2;
}
};
玻璃纤维束(db1);
}
私人空隙系数(){
DoubleBinding db=新的DoubleBinding(){
{
super.bind(image.heightProperty(),bgImageView.boundsInLocalProperty());
}
@凌驾
受保护的双计算值(){
返回image.heightProperty().get()/bgImageView.boundsInLocalProperty().get().getHeight();
}
};
绑定因子(db);
}
私有void setupBgImageView(){
bgImageView.setImage(图像);
bgImageView.fitWidthProperty().bind(scene.widthProperty());
bgImageView.fitHeightProperty().bind(scene.h
    bgImageView.setOnScroll(new EventHandler<ScrollEvent>() {

        @Override
        public void handle(ScrollEvent me) {
            adjustMagnification(me.getDeltaY()/40);
        }
    });
    Pane root = new Pane();
    scene = new Scene(root, 900, 700);
    glassGroup.setMouseTransparent(true);
public class MagnifyingGlass extends Application {
    private ImageView bgImageView = new ImageView();
    private Image image;
    private Scene scene;
    private DoubleProperty magnification = new SimpleDoubleProperty();
    private DoubleProperty GLASS_SIZE = new SimpleDoubleProperty();
    private DoubleProperty GLASS_CENTER = new SimpleDoubleProperty();
    private DoubleProperty centerX = new SimpleDoubleProperty();
    private DoubleProperty centerY = new SimpleDoubleProperty();
    private DoubleProperty factor = new SimpleDoubleProperty();
    private DoubleProperty viewportCenterX = new SimpleDoubleProperty();
    private DoubleProperty viewportCenterY = new SimpleDoubleProperty();
    private DoubleProperty viewportSize = new SimpleDoubleProperty();
    private ImageView magGlass = new ImageView();
    private Group glassGroup = new Group();
    private Text desc = new Text();

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        viewportCenterX.bind(centerX.multiply(factor));
        viewportCenterY.bind(centerY.multiply(factor));
        viewportSize.bind(GLASS_SIZE.multiply(factor).multiply(magnification));


        image = new Image(this.getClass().getResourceAsStream("/sample.jpg"));

        Pane root = new Pane();
        scene = new Scene(root, 900, 700);

        setupBgImageView();
        setupFactor();
        setupGLASS_SIZE();
        magnification.setValue(1.5);

        setupMagGlass();
        setupGlassGroup();
        setupDesc();
        bgImageView.requestFocus();
        primaryStage.setTitle("Magnifying Glass");
        primaryStage.setWidth(image.getWidth() / 2);
        primaryStage.setHeight(image.getHeight() / 2);


        root.getChildren().addAll(bgImageView, glassGroup, desc);

        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public void adjustMagnification(final double amount) {
        // no bindings is needed here - it's one time operation
        double newValue = magnification.get() + amount / 4;
        if (newValue < .5) {
            newValue = .5;
        } else if (newValue > 10) {
            newValue = 10;
        }
        magnification.setValue(newValue);
    }

    private void setupGLASS_SIZE() {
        DoubleBinding db = new DoubleBinding() {
            {
                super.bind(bgImageView.boundsInLocalProperty());
            }

            @Override
            protected double computeValue() {
                return bgImageView.boundsInLocalProperty().get().getWidth() / 4;
            }
        };
        GLASS_SIZE.bind(db);
        GLASS_CENTER.bind(GLASS_SIZE.divide(2));
    }

    private void setupFactor() {
        DoubleBinding db = new DoubleBinding() {
            {
                super.bind(image.heightProperty(), bgImageView.boundsInLocalProperty());
            }

            @Override
            protected double computeValue() {
                return image.heightProperty().get() / bgImageView.boundsInLocalProperty().get().getHeight();
            }
        };

        factor.bind(db);

    }



    private void setupBgImageView() {
        bgImageView.setImage(image);
        bgImageView.fitWidthProperty().bind(scene.widthProperty());
        bgImageView.fitHeightProperty().bind(scene.heightProperty());

        // comparing double requires precision
        bgImageView.cacheProperty().bind(factor.isNotEqualTo(1.0, 0.05));

        bgImageView.setSmooth(true);
        bgImageView.setPreserveRatio(true);
        bgImageView.setOnMouseMoved(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent me) {
                centerX.setValue(me.getX());
                centerY.setValue(me.getY());
            }
        });
        bgImageView.setOnKeyPressed(new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent ke) {
                if (ke.getCode() == KeyCode.EQUALS || ke.getCode() == KeyCode.PLUS) {
                    adjustMagnification(1.0);
                } else if (ke.getCode() == KeyCode.MINUS) {
                    adjustMagnification(-1.0);
                }
            }
        });


        bgImageView.setOnScroll(new EventHandler<ScrollEvent>() {
            @Override
            public void handle(ScrollEvent me) {
                adjustMagnification(me.getDeltaY() / 40);
            }
        });


        bgImageView.setOnMouseClicked(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent me) {
                if (me.getButton() != MouseButton.PRIMARY) {
                    magGlass.setSmooth(magGlass.isSmooth());
                }
                bgImageView.requestFocus();
            }
        });


    }

    private void setupMagGlass() {
        magGlass.setImage(image);
        magGlass.setPreserveRatio(true);
        magGlass.fitWidthProperty().bind(GLASS_SIZE);
        magGlass.fitHeightProperty().bind(GLASS_SIZE);
        magGlass.setSmooth(true);
        ObjectBinding ob = new ObjectBinding() {
            {
                super.bind(viewportCenterX, viewportSize, viewportCenterY);
            }

            @Override
            protected Object computeValue() {
                return new Rectangle2D(viewportCenterX.get() - viewportSize.get() / 2, (viewportCenterY.get() - viewportSize.get() / 2), viewportSize.get(), viewportSize.get());
            }
        };
        magGlass.viewportProperty().bind(ob);
        Circle clip = new Circle();
        clip.centerXProperty().bind(GLASS_CENTER);
        clip.centerYProperty().bind(GLASS_CENTER);
        clip.radiusProperty().bind(GLASS_CENTER.subtract(5));
        magGlass.setClip(clip);

    }

    private void setupGlassGroup() {

        glassGroup.translateXProperty().bind(centerX.subtract(GLASS_CENTER));
        glassGroup.translateYProperty().bind(centerY.subtract(GLASS_CENTER));

        Text text = new Text();
        text.xProperty().bind(GLASS_CENTER.multiply(1.5));
        text.yProperty().bind(GLASS_SIZE);
        text.textProperty().bind(Bindings.concat("x", magnification, " magnification"));
        Circle circle = new Circle();
        circle.centerXProperty().bind(GLASS_CENTER);
        circle.centerYProperty().bind(GLASS_CENTER);

        circle.radiusProperty().bind(GLASS_CENTER.subtract(2));
        circle.setStroke(Color.GREEN);
        circle.setStrokeWidth(3);
        circle.setFill(null);
        glassGroup.getChildren().addAll(magGlass, text, circle);
        DropShadow dropShadow = new DropShadow();
        dropShadow.setOffsetY(4);
        glassGroup.setEffect(dropShadow);
        glassGroup.setMouseTransparent(true);
    }

    private void setupDesc() {
        desc.setX(10);
        desc.setY(15);
        if (!bgImageView.isFocused()) {
            desc.setText("Click image to focus");
        } else {
            desc.setText("Use the +/- or mouse wheel to zoom. Right-click to make the magnification "
                    + "{if (magGlass.smooth)   less smooth. else more smooth.}");
        }
        desc.setFont(new Font(12));
    }
}