Transparent stage/scene loses its transparency after loading another FXML file

亡梦爱人 提交于 2020-02-07 15:45:12

问题


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.


回答1:


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 rule

.root {
    -fx-background-color: transparent ;
}

to the external style sheet.



来源:https://stackoverflow.com/questions/41314300/transparent-stage-scene-loses-its-transparency-after-loading-another-fxml-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!