问题
I would like to embedd a video in my JavaFx 2.x scene and also resize it and relocate it to my needs. The problem I'm having is following. If I build a MediaView
component and then translate X or Y coordinate, then the whole view is being properly moved like so:
MediaView mv = (...)
mv.setTranslateX(200);
mv.setTranslateY(200);
I could do a similar transformation with scaling property:
MediaView mv = (...)
mv.setScaleX(2);
mv.setScaleY(2);
which will properly scale mv
instance two times in dimension.
However, the problem is when I combine those two translations. The mv
instance is being scaled but it always ends up in screen coordinates (0,0)
. This is of course incorrect behavior from my perspective.
I have also tried to wrap my MediaView
component within some wrapper node, like Group
and perform translations on this element. The behavior is the same.
How can I properly move and scale MediaView
component at the same time?
Edit:
Here is my code, although I'm using here ImageView
. This is irrelevant, however. After running this code, image will be placed at (0,0)
instead of (100,100)
.
@Override
public void start(Stage stage) throws Exception {
Group root = new Group();
// Img's dimension is 200x200
javafx.scene.image.Image img = new javafx.scene.image.Image("/home/bachman/projects/cs-player/src/main/resources/content.png");
ImageView iv = new ImageView(img);
root.getChildren().add(iv);
// Move Image View
iv.setTranslateX(100);
iv.setTranslateY(100);
// Scale Image View
iv.setScaleX(2.0);
iv.setScaleY(2.0);
Scene scene = new Scene(root);
stage.setWidth(600);
stage.setHeight(600);
stage.setScene(scene);
stage.show();
}
回答1:
When you use setScaleX, setScaleY, scaling occurs from the center of the node.
If you want to translate by an amount in addition to scaling, you need to take the scaling expansion into account when you set the required translation values. For example, if the node doubles in size (and you want to translate the node to a position relative to the upper left corner of the unscaled node), you need to translate by an additional half the node width and height.
import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.media.*;
import javafx.scene.transform.*;
import javafx.stage.Stage;
public class TransformedVideo extends Application {
public static void main(String[] args) throws Exception { launch(args); }
@Override public void start(final Stage stage) throws Exception {
final MediaPlayer oracleVid = new MediaPlayer(new Media("http://download.oracle.com/otndocs/products/javafx/oow2010-2.flv"));
final MediaView mediaView = new MediaView(oracleVid);
mediaView.setFitWidth(320); mediaView.setFitHeight(240); mediaView.setPreserveRatio(false);
mediaView.setTranslateX(mediaView.getFitWidth() / 2 + 200);
mediaView.setTranslateY(mediaView.getFitHeight() / 2 + 200);
mediaView.setScaleX(2); mediaView.setScaleY(2);
// alternative method of scaling and translating.
// mediaView.getTransforms().addAll(
// new Translate(200, 200),
// new Scale(2, 2)
// );
Group group = new Group(mediaView);
stage.setScene(new Scene(group, 1250, 800));
stage.show();
oracleVid.play();
System.out.println(group.getBoundsInParent());
}
}
When performing multiple transforms on a node, rather than using the setScale/setTransform/setRotate methods, it is often easier to just supply a list of transforms to the getTransforms() method.
来源:https://stackoverflow.com/questions/10161931/how-to-scale-and-set-coordinates-of-mediaview