透明 stage/scene 在加载另一个 FXML 文件后失去透明度
Transparent stage/scene loses its transparency after loading another FXML file
当我启动我的应用程序时,我的透明 javafx.stage.Stage
按预期显示半透明图像。但是在加载第二阶段后,第一阶段就失去了透明度。
奇怪的是,如果第二个 fxml 文件 ("MainScreen.fxml") 不包含任何组件,如按钮或文本字段,背景将保持透明。
我在 macOS Sierra 上的 eclipse neon.2 中使用 JavaFX 和 JavaSE-1.8。
主要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();
}
});
}
}
控制器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 文件("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 文件("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>
解决方案(由James_D解决)
我加了
.root {
-fx-background-color: transparent;
}
添加到外部样式 sheet 并添加 stylesheets="@application.css"
到 FXML 文件中的根节点。
JavaFX 的默认 CSS 样式 sheet,modena,将非透明颜色应用于根节点的背景。这就是您在显示主视图时看到的颜色。
您在第一个屏幕上看不到它的原因,或者如果您从主屏幕上删除按钮,是因为默认样式 sheet 仅在 Control
class(或其子class之一)被实例化。这样做是为了避免 CSS 处理不需要它的应用程序的开销。
要修复,请将 style="-fx-background-color: transparent;"
添加到 FXML 文件中的根节点,或添加规则
.root {
-fx-background-color: transparent ;
}
到外部样式 sheet。
当我启动我的应用程序时,我的透明 javafx.stage.Stage
按预期显示半透明图像。但是在加载第二阶段后,第一阶段就失去了透明度。
奇怪的是,如果第二个 fxml 文件 ("MainScreen.fxml") 不包含任何组件,如按钮或文本字段,背景将保持透明。
我在 macOS Sierra 上的 eclipse neon.2 中使用 JavaFX 和 JavaSE-1.8。
主要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();
}
});
}
}
控制器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 文件("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 文件("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>
解决方案(由James_D解决)
我加了
.root {
-fx-background-color: transparent;
}
添加到外部样式 sheet 并添加 stylesheets="@application.css"
到 FXML 文件中的根节点。
JavaFX 的默认 CSS 样式 sheet,modena,将非透明颜色应用于根节点的背景。这就是您在显示主视图时看到的颜色。
您在第一个屏幕上看不到它的原因,或者如果您从主屏幕上删除按钮,是因为默认样式 sheet 仅在 Control
class(或其子class之一)被实例化。这样做是为了避免 CSS 处理不需要它的应用程序的开销。
要修复,请将 style="-fx-background-color: transparent;"
添加到 FXML 文件中的根节点,或添加规则
.root {
-fx-background-color: transparent ;
}
到外部样式 sheet。