Reputation: 57
I have the main window (mainWindow.fxml) on top of which I want to display a transparent popup window (errorDialog.fxml) with 50% opacity so that the main window's content can still be seen underneath. However, my attempts at making the background colour of overlay inside errorDialog.fxml transparent only results in the background colour being displayed as a solid 50% grey that hides the main window completely.
I tried to set the transparency both in the style attribute of "overlay" as well as in in the initialize method of controllerErrorDialog.java.
Any help is appreciated!
controllerMainWindow.java
package myPackage;
import [...];
public class controllerMainWindow extends AbstractController
{
@FXML
private Button btnOpenPopup;
@FXML
private BorderPane paneMainWindow;
//---------------------------------------------------------------------------------------------------
public void initialize()
{
}
//---------------------------------------------------------------------------------------------------
@FXML
public void handleButtonAction(ActionEvent event)
{
try {
if (event.getSource().equals(btnOpenPopup)) {
FXMLLoader errorLoader = new FXMLLoader();
errorLoader.setLocation(getClass().getResource("errorDialog.fxml"));
controllerErrorDialog errorController = new controllerErrorDialog();
errorLoader.setController(errorController);
Parent layout;
layout = errorLoader.load();
Scene errorScene = new Scene(layout);
Stage errorStage = new Stage();
errorStage.initStyle(StageStyle.UNDECORATED);
errorStage.setMaximized(true);
errorController.setStage(errorStage);
if(this.main!=null) {
errorStage.initOwner(main.getPrimaryStage());
}
errorStage.initModality(Modality.APPLICATION_MODAL);
errorStage.setScene(errorScene);
errorStage.showAndWait();
}
}catch (IOException exceptionCockpitSettings) {
System.out.println("Error when switching to cockpitSettings.");
exceptionCockpitSettings.printStackTrace();
return;
}
}
//---------------------------------------------------------------------------------------------------
}
controllerErrorDialog.java
package myPackage;
import [...];
public class controllerErrorDialog extends AbstractController implements Initializable
{
@FXML
private BorderPane overlay;
private Stage stage = null;
//-------------------------------------------------------------------------------------------------------
@Override
public void initialize(URL url, ResourceBundle rb)
{
overlay.setStyle("fx-background-color: transparent");
}
//---------------------------------------------------------------------------------------------------
public void setStage(Stage stage) {
this.stage = stage;
}
//---------------------------------------------------------------------------------------------------
}
errorDialog.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import [...]?>
<BorderPane fx:id="overlay" prefWidth="1920" prefHeight="1080" style="-fx-background-color: rgba(0,0,0,0.5)" xmlns:fx="http://javafx.com/fxml">
<top></top>
<left></left>
<center></center>
<right></right>
<bottom></bottom>
</BorderPane>
Upvotes: 0
Views: 939
Reputation: 209553
You need to make sure:
errorScene.setFill(Color.TRANSPARENT);
errorStage.initStyle(StageStyle.TRANSPARENT);
Here's a complete (albeit not very user-friendly) example:
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Random;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
/**
* JavaFX App
*/
public class App extends Application {
private Random rng = new Random();
@Override
public void start(Stage stage) {
Button createError = new Button("Try something dangerous");
createError.setOnAction(e -> {
try {
throw new Exception("Boom!");
} catch (Exception exc) {
BorderPane root = new BorderPane();
root.setTop(new Label("Error"));
Label stackTrace = new Label();
StringWriter sw = new StringWriter();
exc.printStackTrace(new PrintWriter(sw));
ScrollPane scroller = new ScrollPane(stackTrace);
stackTrace.setText(sw.toString());
root.setCenter(scroller);
Button close = new Button("Close");
HBox buttons = createHBox(close);
root.setBottom(buttons);
Scene errorScene = new Scene(root, 400, 400);
errorScene.setFill(Color.TRANSPARENT);
errorScene.getStylesheets().add(getClass().getResource("transparent.css").toExternalForm());
Stage errorStage = new Stage();
close.setOnAction(evt -> errorStage.close());
errorStage.setScene(errorScene);
errorStage.initStyle(StageStyle.TRANSPARENT);
errorStage.initModality(Modality.APPLICATION_MODAL);
errorStage.initOwner(stage);
errorStage.show();
}
});
HBox buttons = createHBox(createError);
BorderPane root = new BorderPane(createContent());
root.setBottom(buttons);
Scene scene = new Scene(root, 600, 600);
stage.setScene(scene);
stage.show();
}
private HBox createHBox(Node... content) {
HBox buttons = new HBox(content);
buttons.setAlignment(Pos.CENTER);
buttons.setPadding(new Insets(2));
return buttons;
}
private Node createContent() {
Pane pane = new Pane();
for (int i = 0 ; i < 15 ; i++) {
Circle circle = new Circle(
50 + rng.nextDouble() * 500,
50 + rng.nextDouble() * 500,
50 + rng.nextDouble() * 50,
randomColor());
pane.getChildren().add(circle);
}
return pane ;
}
private Color randomColor() {
return Color.color(rng.nextDouble(), rng.nextDouble(), rng.nextDouble(), 0.5 + 0.25 * rng.nextDouble());
}
public static void main(String[] args) {
launch();
}
}
with transparent.css
being:
.root {
-fx-background-color: #ffffff7f ;
}
.root HBox, .root .scroll-pane, .root .scroll-pane .viewport {
-fx-background-color: transparent ;
}
Upvotes: 4