Die Anwendung der Lösung für JavaFx Bildgrößenänderung an Ihrem Beispielcode und die Änderung der Fenstergröße führen bei mir zu unterschiedlichen Bildgrößen.
import javafx.application.Application;
import javafx.beans.property.*;
import javafx.beans.value.*;
import javafx.event.*;
import javafx.geometry.HPos;
import javafx.geometry.VPos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
public class ImageResizer extends Application {
@Override
public void start(Stage primaryStage) {
MenuBar menuBar=new MenuBar();
Menu menuGame = new Menu("Spiel");
MenuItem newGame = new MenuItem("Neues Spiel F1");
MenuItem exit = new MenuItem("Beenden F2");
exit.setOnAction(new EventHandler() {
@Override
public void handle(ActionEvent event) {
primaryStage.close();
}
});
menuGame.getItems().addAll(newGame,new SeparatorMenuItem(),exit);
menuBar.getMenus().addAll(menuGame);
Image image = new Image("http://docs.oracle.com/javafx/"
+ "javafx/images/javafx-documentation.png");
ImageView imageView = new ImageView();
imageView.setImage(image);
ImageViewPane viewPane = new ImageViewPane(imageView);
VBox vbox=new VBox();
StackPane root=new StackPane();
root.getChildren().addAll(viewPane);
vbox.getChildren().addAll(menuBar,root);
VBox.setVgrow(root, Priority.ALWAYS);
Scene scene= new Scene(vbox,200,200);
primaryStage.setScene(scene);
primaryStage.setMaxHeight(400);
primaryStage.setMinHeight(200);
primaryStage.setMaxWidth(500);
primaryStage.setMinWidth(400);
primaryStage.setTitle("Minesweeper");
primaryStage.show();
}
public static void main(String[] args) { launch(); }
}
/*
* Urheberrecht (c) 2012, Oracle und/oder seine verbundenen Unternehmen. Alle Rechte vorbehalten.
* ÄNDERN ODER ENTFERNEN SIE KEINE URHEBERRECHTSVERMERKE ODER DIESER DATEIKOPF.
*/
/**
*
* @autor akouznet
*/
class ImageViewPane extends Region {
private ObjectProperty imageViewProperty = new SimpleObjectProperty();
public ObjectProperty imageViewProperty() {
return imageViewProperty;
}
public ImageView getImageView() {
return imageViewProperty.get();
}
public void setImageView(ImageView imageView) {
this.imageViewProperty.set(imageView);
}
public ImageViewPane() {
this(new ImageView());
}
@Override
protected void layoutChildren() {
ImageView imageView = imageViewProperty.get();
if (imageView != null) {
imageView.setFitWidth(getWidth());
imageView.setFitHeight(getHeight());
layoutInArea(imageView, 0, 0, getWidth(), getHeight(), 0, HPos.CENTER, VPos.CENTER);
}
super.layoutChildren();
}
public ImageViewPane(ImageView imageView) {
imageViewProperty.addListener(new ChangeListener() {
@Override
public void changed(ObservableValue arg0, ImageView oldIV, ImageView newIV) {
if (oldIV != null) {
getChildren().remove(oldIV);
}
if (newIV != null) {
getChildren().add(newIV);
}
}
});
this.imageViewProperty.set(imageView);
}
}
Alternative Ansätze und zusätzliche Informationen basierend auf Kommentaren
Wenn Sie das alles tun müssen, dann ist das eine Schwäche der JavaFX-Plattform. Idealerweise würde ich erwarten, dass es eine Skalierungseigenschaft des Bildes gäbe, die man setzen könnte, so dass es seine Größe mithilfe des Szenengraphen bestimmt.
Die oben gezeigte Lösung ist nur eine Antwort, es gibt auch andere Möglichkeiten. Der Szenengraph kann verwendet werden, indem verschiedene Eigenschaften an die Breite und Höhe des übergeordneten Knotens gebunden werden oder indem layoutChildren im übergeordneten Knoten überschrieben wird.
Zugehörige Eigenschaften:
Ich bevorzuge den Ansatz mit der Region-Unterklasse gegenüber einer Skalierungseigenschaft oder einem transformationsbasierten Ansatz, weil das Bild dann automatisch auf Grund des Layout-Managers dimensioniert wird. Die obige ImageViewPane ist nur eine einmalige Definitionsklasse, die beliebig oft wiederverwendet werden kann, der tatsächliche Anwendungscode zur Verwendung eines ImageView oder ImageViewPane ist weitgehend äquivalent.
Ein weiterer möglicher Ansatz besteht darin, eine Region-Unterklasse (wie z. B. ein Pane) zu verwenden, die eine definierte CSS-Stilklasse oder ID hat, und dann das Bild in CSS als Hintergrund zu definieren. Das Schöne an einem per CSS definierten Bild ist, dass Sie dann zusätzliche CSS-basierte Attribute verwenden können, um Dinge wie Größenänderung, Skalierung, Positionierung und Wiederholungen für das Bild festzulegen. Dieser Hintergrund kann auch programmgesteuert festgelegt werden, wenn gewünscht, anstatt über CSS.
Zugehörige Frage:
Um das Verhältnis von Höhe und Breite des Bildes beizubehalten
Der folgende Code kann in der ImageViewPane-Klasse verwendet werden, die oben bereitgestellt wurde:
if (imageView.isPreserveRatio()) {
if (getHeight() > getWidth()) {
imageView.setFitWidth(getWidth());
imageView.setFitHeight(0);
} else {
imageView.setFitWidth(0);
imageView.setFitHeight(getHeight());
}
} else {
imageView.setFitWidth(getWidth());
imageView.setFitHeight(getHeight());
}