加载另一个FXML文件后,透明舞台/场景失去透明度 [英] Transparent stage/scene loses its transparency after loading another FXML file

查看:222
本文介绍了加载另一个FXML文件后,透明舞台/场景失去透明度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我启动我的应用程序时,我的透明 javafx.stage.Stage 按预期显示半透明图像。但是在第二阶段加载后,第一阶段失去了透明度。



奇怪的是,如果第二个fxml文件(MainScreen.fxml)不包含任何组件,如按钮或文本字段,则背景保持透明。 / p>

我在macOS Sierra上的eclipse neon.2中使用JavaFX和JavaSE-1.8。





主要类



  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;

公共类Main扩展Application实现Runnable {

private Stage primaryStage;
私人舞台舞台;

private Controller launchController;

@Override
public void start(Stage primaryStage){
this.primaryStage = primaryStage;

launchController = new Controller(LaunchScreen.fxml);
场景launchScene =新场景(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);
//模拟工作
} catch(InterruptedException e){
e.printStackTrace();
}

控制器控制器=新控制器(MainScreen.fxml);
场景场景=新场景(控制器);

Platform.runLater(new Runnable(){
@Override
public void run(){
stage = new Stage();
stage。 initStyle(StageStyle.UNDECORATED);
stage.setResizable(false);
stage.setScene(scene);
stage.show();
}
}) ;
}
}



控制器类



  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;

公共类LaunchController扩展了AnchorPane {

@FXML
私有ProgressBar栏;

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文件(LaunchScreen。 fxml)



 <?xml version =1.0encoding =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 =panemaxHeight = - InfinitymaxWidth = - InfinityminHeight = - InfinityminWidth = - InfinityprefHeight =326.0prefWidth =883.0type =AnchorPanexmlns =http://javafx.com/javafx/8xmlns:fx =http://javafx.com/fxml/1>
< children>
< ImageView fitHeight =326.0fitWidth =883.0layoutX =7.0layoutY =134.0pickOnBounds =truepreserveRatio =trueAnchorPane.bottomAnchor =0.0AnchorPane.leftAnchor =0.0 AnchorPane.rightAnchor =0.0AnchorPane.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文件(MainScreen.fxml)



 <?xml version =1.0encoding =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 =panemaxHeight = - InfinitymaxWidth = - InfinityminHeight = - InfinityminWidth = - InfinityprefHeight =720.0prefWidth =1280.0type =AnchorPanexmlns =http://javafx.com/javafx/8xmlns:fx =http://javafx.com/fxml/1>
< children>
< ImageView fitHeight =720.0fitWidth =1280.0pickOnBounds =truepreserveRatio =trueAnchorPane.bottomAnchor =0.0AnchorPane.leftAnchor =0.0AnchorPane.rightAnchor =0.0AnchorPane。 topAnchor = 0.0 >
< image>
< Image url =@http://i.telegraph.co.uk/multimedia/archive/03589/Wellcome_Image_Awa_3589699k.jpg/>
< / image>
< / ImageView>
< HBox spacing =100.0AnchorPane.bottomAnchor =0.0AnchorPane.leftAnchor =0.0AnchorPane.rightAnchor =0.0>
< children>
< Button fx:id =button1mnemonicParsing =falseonAction =#button1PressprefHeight =45.0prefWidth =1000.0text =Singleplayer/>
< Button fx:id =button2mnemonicParsing =falseonAction =#button2PressprefHeight =45.0prefWidth =1000.0text =multiplayer/>
< Button fx:id =button3mnemonicParsing =falseonAction =#button3PressprefHeight =45.0prefWidth =1000.0text =Settings/>
< Button fx:id =button4mnemonicParsing =falseonAction =#button4PressprefHeight =45.0prefWidth =1000.0text =Quit/>
< / children>
< padding>
< Insets bottom =30.0left =100.0right =100.0top =20.0/>
< / padding>
< / HBox>
< Region fx:id =regionprefHeight =15.0AnchorPane.leftAnchor =0.0AnchorPane.rightAnchor =0.0AnchorPane.topAnchor =0.0/>
< / children>
< / fx:root>



解决方案(由James_D解决)



我添加了

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

到外部样式表并添加 stylesheets = @ application.css到FXML文件中的根节点。

解决方案

默认的CSS样式用于JavaFX的工作表,modena,将非透明颜色应用于根节点的背景。这是您在显示主视图时看到的颜色。



您在第一个屏幕中没有看到此内容的原因,或者如果您从主屏幕中删除按钮,原因是默认样式表仅在第一个屏幕上加载时间 Control 类(或其子类之一)被实例化。这样做是为了避免不需要它的应用程序的CSS处理开销。



要修复,请将 style = - fx-background-color:transparent;添加到根节点在FXML文件中,或添加规则

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

到外部样式表。


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 rule

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

to the external style sheet.

这篇关于加载另一个FXML文件后,透明舞台/场景失去透明度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆