Is it possible to have transparent disposal in javafx?

I know that you can set the stage to have the style utility "Stage.InitStyle (StageStyle.UTILITY)"; and you can set it to the transparent style "Stage.InitStyle (StageStyle.TRANSPARENT)"; but can you at the same stage? I’m tired of doing this so that the scene does not show like a window down in the Start menu, and I would like the scene to be invisible so that you can only see the scene.

+1
java javafx transparency stage utility
source share
2 answers

You can always do it the old way using Swing, where this feature is available. And Swing allows you to embed JavaFX. Of course, it would be desirable to have a clean mechanism without Swing, but afaik does not exist yet.

Example:

import javafx.application.Platform; import javafx.embed.swing.JFXPanel; import javafx.scene.Scene; import javafx.scene.control.ContextMenu; import javafx.scene.control.Label; import javafx.scene.control.MenuItem; import javafx.scene.layout.Background; import javafx.scene.layout.StackPane; import javafx.scene.paint.Color; import javafx.scene.paint.CycleMethod; import javafx.scene.paint.RadialGradient; import javafx.scene.paint.Stop; import javax.swing.JFrame; import javax.swing.SwingUtilities; import java.awt.geom.GeneralPath; public class Widget extends JFrame { class DragContext { double x; double y; } public Widget() { // decoration setType(Type.UTILITY); setUndecorated(true); setSize(200, 200); toBack(); // position // setLocation(100, 100); setLocationRelativeTo(null); // centers on screen // frame operations setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // frame shape (a star) double points[][] = { { 0, 85 }, { 75, 75 }, { 100, 10 }, { 125, 75 }, { 200, 85 }, { 150, 125 }, { 160, 190 }, { 100, 150 }, { 40, 190 }, { 50, 125 }, { 0, 85 } }; GeneralPath star = new GeneralPath(); star.moveTo(points[0][0], points[0][1]); for (int k = 1; k < points.length; k++) star.lineTo(points[k][0], points[k][2]); star.closePath(); setShape(star); // embed fx into swing JFXPanel fxPanel = new JFXPanel(); Widget.this.getContentPane().add(fxPanel); Platform.runLater(new Runnable() { @Override public void run() { // set scene in JFXPanel fxPanel.setScene( createFxScene()); // show frame SwingUtilities.invokeLater(new Runnable() { @Override public void run() { Widget.this.setVisible(true); // send it to the desktop, behind all other existing windows // Widget.this.toBack(); // Widget.this.repaint(); } }); } }); } private Scene createFxScene() { StackPane rootPane = new StackPane(); rootPane.setBackground(Background.EMPTY); // add some node Label label = new Label("Bright & Shiny"); label.setTextFill(Color.RED); rootPane.getChildren().add(label); // create scene Scene scene = new Scene(rootPane); // gradient fill RadialGradient radialGradient = new RadialGradient( 270, 0.8, 0.5, 0.5, 0.7, true, CycleMethod.NO_CYCLE, new Stop( .5f, Color.YELLOW), new Stop( .7f, Color.ORANGE), new Stop( .9f, Color.ORANGERED)); scene.setFill(radialGradient); // context menu with close button ContextMenu contextMenu = new ContextMenu(); MenuItem closeMenuItem = new MenuItem("Close"); closeMenuItem.setOnAction(actionEvent -> System.exit(0)); contextMenu.getItems().add(closeMenuItem); // set context menu for scene scene.setOnMousePressed(mouseEvent -> { if (mouseEvent.isSecondaryButtonDown()) { contextMenu.show(rootPane, mouseEvent.getScreenX(), mouseEvent.getScreenY()); } }); // allow the frame to be dragged around final DragContext dragDelta = new DragContext(); rootPane.setOnMousePressed(mouseEvent -> { dragDelta.x = Widget.this.getLocation().getX() - mouseEvent.getScreenX(); dragDelta.y = Widget.this.getLocation().getY() - mouseEvent.getScreenY(); }); rootPane.setOnMouseDragged(mouseEvent -> Widget.this.setLocation((int) (mouseEvent.getScreenX() + dragDelta.x), (int) (mouseEvent.getScreenY() + dragDelta.y))); return scene; } public static void main(String[] args) { new Widget(); } } 

Here is a screenshot of the widget that does not appear in the taskbar. Drag it with the left mouse button. The right mouse button offers a context menu with a close button.

Widget

The above code uses the shape of a swinging frame. The code below uses the javafx control form.

Here is the version in which only the control is visible. I am using a reflective label control.

If you want to send the control directly to the desktop, you need to activate the toBack () call. You can scale the controls with the mouse wheel. The maximum zoom size is limited by the jframe size.

All you have to do for your custom control is to implement the code in createFxControl ()

 import javafx.application.Platform; import javafx.embed.swing.JFXPanel; import javafx.event.EventHandler; import javafx.scene.Scene; import javafx.scene.control.ContextMenu; import javafx.scene.control.Control; import javafx.scene.control.Label; import javafx.scene.control.MenuItem; import javafx.scene.effect.Reflection; import javafx.scene.input.ScrollEvent; import javafx.scene.layout.Background; import javafx.scene.layout.StackPane; import javafx.scene.paint.Color; import javafx.scene.text.Font; import javax.swing.JFrame; import javax.swing.SwingUtilities; public class LabelWidget extends JFrame { class DragContext { double x; double y; } public LabelWidget() { // decoration setType(Type.UTILITY); setUndecorated(true); // make frame transparent, we only want the control to be visible setBackground(new java.awt.Color(0,0,0,0)); setSize(400, 400); // position // setLocation(100, 100); setLocationRelativeTo(null); // centers on screen // frame operations setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // embed fx into swing JFXPanel fxPanel = new JFXPanel(); LabelWidget.this.getContentPane().add(fxPanel); Platform.runLater(new Runnable() { @Override public void run() { // set scene in JFXPanel fxPanel.setScene( createFxScene()); // show frame SwingUtilities.invokeLater(new Runnable() { @Override public void run() { LabelWidget.this.setVisible(true); // send it to the desktop, behind all other existing windows // ClockWidget.this.toBack(); // ClockWidget.this.repaint(); } }); } }); } private Scene createFxScene() { StackPane rootPane = new StackPane(); // make pane transparent, we only want the control to be visible rootPane.setBackground(Background.EMPTY); // add control Control control = createFxControl(); rootPane.getChildren().add( control); // create scene Scene scene = new Scene(rootPane); // make scene transparent, we only want the control to be visible scene.setFill( Color.TRANSPARENT); // context menu with close button ContextMenu contextMenu = new ContextMenu(); MenuItem closeMenuItem = new MenuItem("Close"); closeMenuItem.setOnAction(actionEvent -> System.exit(0)); contextMenu.getItems().add(closeMenuItem); control.setContextMenu(contextMenu); // allow the frame to be dragged around makeDraggable( control); // allow zooming makeZoomable( control); return scene; } /** * Create the JavaFX control of which we use the shape. * @return */ private Control createFxControl() { Label label = new Label( "I'm a Label"); label.setFont(new Font("Tahoma", 24)); label.setEffect(new Reflection()); return label; } /** * Allow dragging of the stage / control on the desktop * @param control * @param stage */ public void makeDraggable( Control control) { final DragContext dragDelta = new DragContext(); control.setOnMousePressed(mouseEvent -> { dragDelta.x = LabelWidget.this.getLocation().getX() - mouseEvent.getScreenX(); dragDelta.y = LabelWidget.this.getLocation().getY() - mouseEvent.getScreenY(); }); control.setOnMouseDragged(mouseEvent -> LabelWidget.this.setLocation((int) (mouseEvent.getScreenX() + dragDelta.x), (int) (mouseEvent.getScreenY() + dragDelta.y))); } /** * Allow zooming * @param control */ public void makeZoomable( Control control) { // note: in order to make it larger, we'd have to resize the stage/frame => we limit the size to 1.0 for now and allow only making the control smaller final double MAX_SCALE = 1.0; final double MIN_SCALE = 0.1; control.addEventFilter(ScrollEvent.ANY, new EventHandler<ScrollEvent>() { @Override public void handle(ScrollEvent event) { double delta = 1.2; double scale = control.getScaleX(); if (event.getDeltaY() < 0) { scale /= delta; } else { scale *= delta; } scale = clamp(scale, MIN_SCALE, MAX_SCALE); control.setScaleX(scale); control.setScaleY(scale); event.consume(); } }); } /** * Limit bounds of value * @param value * @param min * @param max * @return */ public static double clamp( double value, double min, double max) { if( Double.compare(value, min) < 0) return min; if( Double.compare(value, max) > 0) return max; return value; } public static void main(String[] args) { new LabelWidget(); } } 

Or, if you have the awesome Enzo library from https://github.com/HanSolo/Enzo at hand, you can use this code:

 private Control createFxControl() { // create a clock using the enzo library from https://github.com/HanSolo/Enzo Clock clock = ClockBuilder.create() // .prefSize(400, 400) .design(Clock.Design.DB) .running(true) .text("Berlin") .autoNightMode(true) .build(); return clock; } 

to create this:

enter image description here

+3
source share

Found an easy way to do this: Create a utility window and make it completely transparent so that you cannot see or interact with it. Then create the desired window and run the owner in the utility window - this will lead to the fact that it does not appear on the taskbar.

+2
source share

All Articles