问题描述
我正尝试在 http:/上将JavaFX 1.3放大镜示例迁移到JavaFX 2.0. /docs.oracle.com/javafx/1.3/tutorials/FXImage/,但我遇到了一个问题.
Im trying to migrate the JavaFX 1.3 Magnifying Glass example to JavaFX 2.0 at http://docs.oracle.com/javafx/1.3/tutorials/FXImage/ , but i've come across a problem.
我可能已经变得盲目了,但我真的不明白为什么眼镜组不跟随鼠标.
I might have become blind, but i really cant figure out, why the glassgroup doesn't follow the mouse.
代码如下:
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));
}
}
任何帮助将不胜感激:-)
any help will be appreciated :-)
推荐答案
1..您可能想升级到JavaFX 2.1(开发人员预览).
1. You may want to upgrade to JavaFX 2.1 (developers preview).
您只需将impl_setOnMouseWheel
处理程序更改为
You would have to change only impl_setOnMouseWheel
handler to
bgImageView.setOnScroll(new EventHandler<ScrollEvent>() {
@Override
public void handle(ScrollEvent me) {
adjustMagnification(me.getDeltaY()/40);
}
});
2..要固定玻璃的居中位置,您需要固定布局. StackPane
将所有与数学无关的孩子放在中间.使用Pane
代替:
2. To fix centering of the glass you need to fix your layout. StackPane
put all chidren in the center which doesn't correlate with your math. Use Pane
instead:
Pane root = new Pane();
scene = new Scene(root, 900, 700);
3..然后,将glassGroup
放置在鼠标下方,鼠标事件将被消耗.因此,您还应该将下一个通话添加到setupGlassGroup
:
3. Then you do that your glassGroup
will be positioned under the mouse, and mouse events will be consumed by it. So you should also add next call to setupGlassGroup
:
glassGroup.setMouseTransparent(true);
4..此外,您可以简化绑定.不必每次都覆盖computeValue
,而是可以使用以下便捷方法:viewportCenterX.bind(centerX.multiply(factor));
.查看下面的更新代码:
4. Also, you can simplify your bindings. Instead of overriding computeValue
each time you can use convenience methods like here: viewportCenterX.bind(centerX.multiply(factor));
. See updated code below:
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));
}
}
这篇关于为什么我的放大镜不跟随鼠标?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!