Ein Hinweis auf Versuch und Irrtum beim Versuch, eine JavaFX-Anwendung zu erstellen, die nicht in der Taskleiste angezeigt wird, z. B. Desktop-Zubehör, ohne Rand und nicht quadratisch.
OS Windows 10
Java 1.8.0_162
package sample.javafx;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class Main extends Application {
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.initStyle(StageStyle.UTILITY);
Parent root = FXMLLoader.load(this.getClass().getResource("/main.fxml"));
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
}
** Ausführungsergebnis **
Erläuterung
main.fxml
package sample.javafx;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class Main extends Application {
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.initStyle(StageStyle.TRANSPARENT);
Parent root = FXMLLoader.load(this.getClass().getResource("/main.fxml"));
Scene scene = new Scene(root);
scene.setFill(Color.TRANSPARENT);
primaryStage.setScene(scene);
primaryStage.show();
}
}
** Ausführungsergebnis **
Erläuterung
StageStyle.TRANSPARENT
mit initStyle ()
of Stage
an.UTILITY |
TRANSPARENT |
|
---|---|---|
Taskleiste ausblenden | OK | NG |
Nicht rechteckiges Fenster | NG | OK |
Auf diese Weise verfügt jeder über die gewünschten Funktionen und die Funktionen, die Sie nicht benötigen. Wenn Sie also dort oben stehen, können Sie nicht aufstehen. Ab April 2018 scheint es keine Möglichkeit zu geben, diese beiden ordentlich zu kombinieren.
In der OpenJDK-Ausgabe wird dieses Problem erwähnt, es wurde jedoch zuletzt im Mai 2017 aktualisiert, und seitdem scheint es keine Fortschritte zu geben.
[JDK-8091566] Taskbar-less Undecorated Transparent Window - Java Bug System
Wie in der obigen Ausgabe erwähnt, können Sie beide zwangsweise kombinieren.
Insbesondere ist es wie folgt.
Bühne
und
--Stellen Sie StageStyle.TRANSPARENT
einDas heißt, die primäre Stufe wird nur verwendet, um die Funktion "UTILITY" zu verwenden, die die Taskleiste verbirgt und vom Bildschirm ausgeblendet wird, und das tatsächlich sichtbare Fenster wird von einer anderen "Stufe" mit der Einstellung "TRANSPARENT" ausgeführt. Die Methode.
Die Bedenken dieser Methode werden in der obigen Ausgabe wie folgt erläutert:
This is a dangerous hack because that UTILITY window could get placed back on the main screen if the computer screen resizes like from a remote desktop session connect and the OS decides to place all windows back on the visible bounds. Tests have shown this doesn't happen, but it feels like it could in certain cases.
(Übersetzung) Dies ist ein gefährlicher Hack. Dies liegt daran, dass das UTILITY-Fenster möglicherweise zum Hauptfenster zurückkehrt, wenn die Größe des Computerbildschirms geändert wird, z. B. durch Verbinden einer Remotedesktopsitzung, und das Betriebssystem beschließt, alle Fensterpositionen in den sichtbaren Bereich zurückzusetzen. Tests sagen, dass dies nicht passiert, aber ich denke, dass es in bestimmten Fällen wahrscheinlich ist.
Es scheint, dass es im Test nicht passiert, aber es scheint, dass es keine saubere Lösung ist. Es ist leicht vorstellbar, dass wenn etwas schief geht und die Primärstufe sichtbar ist, es ziemlich hässlich wird.
Um dieses Problem zu umgehen, habe ich auch die Primärstufe "Deckkraft" auf "0" gesetzt. Wenn die Umgebung "Deckkraft" unterstützt, ist die Primärstufe nicht sichtbar, wenn sie versehentlich in den sichtbaren Bereich eintritt. In einer Umgebung, in der "Deckkraft" nicht unterstützt wird, ist dies jedoch nicht sinnvoll. Ich denke, es wird notwendig sein, sie vom Bildschirm zu entfernen.
Zusätzlich zu der oben erwähnten erzwungenen Kombination ist das Endergebnis wie folgt, wenn die Implementierung wie die Taskleiste enthalten ist.
main.fxml
Main.java
package sample.javafx;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javax.imageio.ImageIO;
import java.awt.TrayIcon;
import java.awt.SystemTray;
import java.awt.AWTException;
import java.awt.image.BufferedImage;
import java.io.IOException;
public class Main extends Application {
private TrayIcon trayIcon;
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
Platform.setImplicitExit(false);
this.initPrimaryStage(primaryStage);
Stage mainStage = this.initMainStage(primaryStage);
this.initSystemTray(mainStage);
primaryStage.show();
mainStage.show();
}
private void initPrimaryStage(Stage primaryStage) {
primaryStage.initStyle(StageStyle.UTILITY);
primaryStage.setOpacity(0.0);
primaryStage.setX(-1000);
primaryStage.setY(-1000);
}
private Stage initMainStage(Stage primaryStage) throws IOException {
Stage mainStage = new Stage();
mainStage.initOwner(primaryStage);
mainStage.initStyle(StageStyle.TRANSPARENT);
FXMLLoader fxmlLoader = new FXMLLoader(this.getClass().getResource("/main.fxml"));
Parent root = fxmlLoader.load();
Scene scene = new Scene(root);
scene.setFill(Color.TRANSPARENT);
mainStage.setScene(scene);
MainController controller = fxmlLoader.getController();
controller.setStage(mainStage);
return mainStage;
}
private void initSystemTray(Stage mainStage) throws IOException, AWTException {
if (!SystemTray.isSupported()) {
return;
}
BufferedImage img = ImageIO.read(this.getClass().getResource("/img/open.png "));
this.trayIcon = new TrayIcon(img);
this.trayIcon.setImageAutoSize(true);
this.trayIcon.addActionListener(e -> {
Platform.runLater(() -> {
if (mainStage.isShowing()) {
mainStage.hide();
} else {
mainStage.show();
}
});
});
this.trayIcon.setToolTip("show/hide");
SystemTray systemTray = SystemTray.getSystemTray();
systemTray.add(trayIcon);
}
@Override
public void stop() {
if (SystemTray.isSupported() && this.trayIcon != null) {
SystemTray.getSystemTray().remove(this.trayIcon);
}
}
}
MainController.java
package sample.javafx;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.scene.input.MouseEvent;
import javafx.stage.Stage;
public class MainController {
private Stage stage;
private double mouseOffsetX;
private double mouseOffsetY;
public void setStage(Stage stage) {
this.stage = stage;
}
@FXML
public void close() {
Platform.exit();
}
@FXML
public void onMousePressed(MouseEvent event) {
this.mouseOffsetX = this.stage.getX() - event.getScreenX();
this.mouseOffsetY = this.stage.getY() - event.getScreenY();
}
@FXML
public void onMouseDragged(MouseEvent event) {
this.stage.setX(event.getScreenX() + this.mouseOffsetX);
this.stage.setY(event.getScreenY() + this.mouseOffsetY);
}
}
** Ausführungsergebnis **
Es sieht so aus, als würden Sie ziehen
Es sieht so aus, als ob es sich in der Taskleiste befindet
Erläuterung
Platform.setImplicitExit (false);
Main.java
@Override
public void start(Stage primaryStage) throws Exception {
Platform.setImplicitExit(false);
** Verwendung der Taskleiste mit JavaFX **
Recommended Posts