When I start my application my transparent javafx.stage.Stage
shows a half transparent image as expected. But after a second stage is loaded the first stage loses its transparency.
The weird thing is that if the second fxml file ("MainScreen.fxml") doesn't contains any components like buttons or text fields, the background stays transparent.
I'm using JavaFX with JavaSE-1.8 in eclipse neon.2 on macOS Sierra.
Main class
package customPackage.main;
import javafx.animation.FadeTransition;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.stage.Screen;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.util.Duration;
public class Main extends Application implements Runnable {
private Stage primaryStage;
private Stage stage;
private Controller launchController;
@Override
public void start(Stage primaryStage) {
this.primaryStage = primaryStage;
launchController = new Controller("LaunchScreen.fxml");
Scene launchScene = new Scene(launchController);
launchScene.setFill(Color.TRANSPARENT);
primaryStage.initStyle(StageStyle.TRANSPARENT);
primaryStage.setAlwaysOnTop(true);
primaryStage.setResizable(false);
primaryStage.setScene(launchScene);
primaryStage.show();
Thread thread = new Thread(this);
thread.start();
}
@Override
public void run() {
try {
Thread.sleep(3000);
// simulate work
} catch (InterruptedException e) {
e.printStackTrace();
}
Controller controller = new Controller("MainScreen.fxml");
Scene scene = new Scene(controller);
Platform.runLater(new Runnable() {
@Override
public void run() {
stage = new Stage();
stage.initStyle(StageStyle.UNDECORATED);
stage.setResizable(false);
stage.setScene(scene);
stage.show();
}
});
}
}
Controller class
package customPackage.main;
import java.io.IOException;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.AnchorPane;
public class LaunchController extends AnchorPane {
@FXML
private ProgressBar bar;
public LaunchController(String filename) {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource(filename));
fxmlLoader.setRoot(this);
fxmlLoader.setController(this);
try {
fxmlLoader.load();
} catch (IOException e) {
e.printStackTrace();
}
}
}
FXML File ("LaunchScreen.fxml")
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.effect.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.image.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<fx:root fx:id="pane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="326.0" prefWidth="883.0" type="AnchorPane" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
<ImageView fitHeight="326.0" fitWidth="883.0" layoutX="7.0" layoutY="134.0" pickOnBounds="true" preserveRatio="true" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<image>
<Image url="@http://www.lunapic.com/editor/premade/transparent.gif" />
</image>
</ImageView>
</children>
<cursor>
<Cursor fx:constant="DEFAULT" />
</cursor>
</fx:root>
FXML File ("MainScreen.fxml")
<?xml version="1.0" encoding="UTF-8"?>
<?import java.net.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<fx:root fx:id="pane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="720.0" prefWidth="1280.0" type="AnchorPane" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
<ImageView fitHeight="720.0" fitWidth="1280.0" pickOnBounds="true" preserveRatio="true" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<image>
<Image url="@http://i.telegraph.co.uk/multimedia/archive/03589/Wellcome_Image_Awa_3589699k.jpg" />
</image>
</ImageView>
<HBox spacing="100.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0">
<children>
<Button fx:id="button1" mnemonicParsing="false" onAction="#button1Press" prefHeight="45.0" prefWidth="1000.0" text="Singleplayer" />
<Button fx:id="button2" mnemonicParsing="false" onAction="#button2Press" prefHeight="45.0" prefWidth="1000.0" text="Multiplayer" />
<Button fx:id="button3" mnemonicParsing="false" onAction="#button3Press" prefHeight="45.0" prefWidth="1000.0" text="Settings" />
<Button fx:id="button4" mnemonicParsing="false" onAction="#button4Press" prefHeight="45.0" prefWidth="1000.0" text="Quit" />
</children>
<padding>
<Insets bottom="30.0" left="100.0" right="100.0" top="20.0" />
</padding>
</HBox>
<Region fx:id="region" prefHeight="15.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children>
</fx:root>
Solution (solved by James_D)
I added
.root {
-fx-background-color: transparent;
}
to the external style sheet and added stylesheets="@application.css"
to the root node in the FXML file.
The default CSS style sheet for JavaFX, modena, applies a non-transparent color to the background of the root node. That's the color you're seeing when you display your main view.
The reason you don't see this in your first screen, or if you remove the buttons from the main screen, is that the default style sheet is only loaded the first time the
Control
class (or one of its subclasses) is instantiated. This is done to avoid the overhead of CSS processing for applications not needing it.To fix, either add
style="-fx-background-color: transparent;"
to the root node in the FXML file, or add the ruleto the external style sheet.