是否可以在javafx中使用透明的实用程序阶段?

我知道你可以设置一个阶段来实现一个实用程序样式“Stage.InitStyle(StageStyle.UTILITY);” 并且您可以将其设置为具有透明样式“Stage.InitStyle(StageStyle.TRANSPARENT);” 但你能同时在同一个舞台吗? 我很累,因为舞台在开始菜单中没有显示为窗口,我希望舞台不可见,这样你才能看到场景。

您始终可以使用Swing以旧方式执行该function。 Swing允许您嵌入JavaFX。 当然,最好有一个没有Swing的干净机制,但是afaik它还不存在(还)。

例:

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(); } } 

这是未在任务栏中显示的小部件的屏幕截图。 用鼠标左键拖动它。 鼠标右键提供带关闭按钮的上下文菜单。

窗口小部件

上面的代码使用了swing框架的形状。 下面的代码使用javafx控件的形状。

这是一个只有控件可见的版本。 我使用reflection标签控件。

如果要将控件直接发送到桌面,则需要激活toBack()调用。 您可以使用鼠标滚轮缩放控件。 最大缩放大小限制为jframe的大小。

您需要为自定义控件执行的所有操作都是在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() { @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(); } } 

或者,如果您手头有https://github.com/HanSolo/Enzo的强大的Enzo库,您可以使用以下代码:

 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; } 

创建这个:

在此处输入图像描述

找到了一种简单的方法:创建一个实用程序窗口并使其完全透明,这样您就无法查看或与之交互。 然后创建所需窗口并将所有者初始化到实用程序窗口 – 这将导致它不会出现在任务栏中。