I am trying to set the background image of a JavaFX program same as the user background.
The background image in windows is found in : "%AppData%\Microsoft\Windows\Themes\CachedFiles"
and using JavaFX i added the style using:
style="-fx-background-image: url('%AppData%\Microsoft\Windows\Themes\CachedFiles\*.jpg');"
what should I replace the '*.jpg' with (knowing that there is 1 photo there only)? or how can I come around this issue?
You can't do it with FXML alone. You will need to set the background from the controller after the FXML is loaded.
FXML:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.PasswordField?>
<?import javafx.scene.control.Button?>
<AnchorPane fx:controller="stackoverflow.answers.demo.Main$Controller" fx:id="mainPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">
<children>
<TextField fx:id="username" layoutX="30.0" layoutY="125.0" />
<Label layoutX="30.0" layoutY="99.0" text="Username" />
<Label layoutX="30.0" layoutY="174.0" text="Password" />
<PasswordField fx:id="password" layoutX="30.0" layoutY="200.0" />
<Button fx:id="login" layoutX="61.0" layoutY="338.0" mnemonicParsing="false" text="Login" />
</children>
</AnchorPane>
Code:
public class Main extends Application {
public static class Controller {
@FXML
AnchorPane mainPane;
@FXML
TextField username;
@FXML
PasswordField password;
@FXML
Button login;
}
public static void main(String[] args) {
launch(args);
}
private Optional<String> pickRandomImage() {
File[] imgs = Paths.get(System.getenv("APPDATA"), "Microsoft", "Windows", "Themes", "CachedFiles")
.toFile().listFiles((File f) -> f.getName().endsWith(".jpg"));
if (imgs != null && imgs.length > 0) {
Collections.shuffle(Arrays.asList(imgs));
return Optional.of(imgs[0].toURI().toString());
}
return Optional.empty();
}
@Override
public void start(Stage stage) {
stage.setTitle("Random Background");
FXMLLoader loader = new FXMLLoader(getClass().getResource("/layout.xml"));
try {
Parent root = loader.load();
Controller ctrl = loader.getController();
pickRandomImage().ifPresent(imgurl -> {
Image image = new Image(imgurl);
ctrl.mainPane.setBackground(new Background(new BackgroundImage(image, BackgroundRepeat.REPEAT, BackgroundRepeat.REPEAT, BackgroundPosition.CENTER, BackgroundSize.DEFAULT)));
});
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Note that my example will pick a random image from the folder if multiple images are present. You can get rid of that part or leave it as it won't effect the result if only one image is present.