javafxjavafx-8javafx-11

How to set a transparent png as a stage's background in javafx?


I am trying to set a transparent png as a stage's background. The problem is that the transparent part of the png is not not transparent in javafx. This is the code I am using:

    Pane root = new Pane();
    root.setStyle("-fx-background-color: transparent");
    ImageView img = new ImageView();
    img.setStyle("-fx-background-color: transparent");
    img.setImage(new Image(getClass().getClassLoader().getResource("transparent_png.png").toExternalForm()));
    root.getChildren().add(img);
    Scene scene = new Scene(root, 500, 500);
    scene.setFill(Color.TRANSPARENT);
    stage.initStyle(StageStyle.TRANSPARENT);
    stage.setScene(scene);
    stage.show();

Am I doing something wrong or is it not possible? Regards,


Solution

  • Am I doing something wrong or is it not possible?

    It is certainly possible. It is likely your image is not actually transparent. Here is a complete example which creates an image in code with transparent pixels, saves it to a file, then reads the file into an image object and displays it. The only other difference from your code are to make it easy to exit the application by clicking on it.

    import javafx.application.Application;
    import javafx.application.Platform;
    import javafx.embed.swing.SwingFXUtils;
    import javafx.scene.Scene;
    import javafx.scene.image.Image;
    import javafx.scene.image.ImageView;
    import javafx.scene.image.PixelWriter;
    import javafx.scene.image.WritableImage;
    import javafx.scene.layout.Pane;
    import javafx.scene.paint.Color;
    import javafx.stage.Stage;
    import javafx.stage.StageStyle;
    
    import javax.imageio.ImageIO;
    import java.io.File;
    import java.io.IOException;
    import java.nio.file.Files;
    import java.nio.file.Paths;
    
    public class HelloApplication extends Application {
        @Override
        public void start(Stage stage) throws IOException {
            Pane root = new Pane();
            root.setStyle("-fx-background-color: transparent");
            ImageView img = new ImageView();
    //        img.setStyle("-fx-background-color: transparent");
            img.setImage(createImage());
            img.setOnMouseClicked(e -> Platform.exit());
            img.setPickOnBounds(true);
            root.getChildren().add(img);
            Scene scene = new Scene(root, 512, 512);
            scene.setFill(Color.TRANSPARENT);
            stage.initStyle(StageStyle.TRANSPARENT);
            stage.setScene(scene);
            stage.show();
        }
    
        private Image createImage() throws IOException {
    
            WritableImage image = new WritableImage(512, 512);
            PixelWriter pw = image.getPixelWriter();
            for (int x = 0 ; x < 512 ; x++) {
                for (int y = 0 ; y < 512 ; y++) {
                    Color color = ((x/32) + (y/32)) % 2 == 0 ? Color.TRANSPARENT : Color.BLUE;
                    pw.setColor(x, y, color);
                }
            }
    
            // This code just writes the image to a file
            // and reads it back in, just to demonstrate this
            // can be done from an image on file.
    
            // You can just return image;
            // instead of all this, which is equivalent and saves
            // all the javafx.swing and java.desktop dependencies
            File tempFile = new File("temp.png");
            ImageIO.write(SwingFXUtils.fromFXImage(image, null), "png", tempFile);
            Image readImage = new Image(tempFile.toURI().toString());
            tempFile.delete();
            return readImage;
        }
    
        public static void main(String[] args) {
            launch();
        }
    }
    

    enter image description here