Une note d'essais et d'erreurs lors de la tentative de création d'une application JavaFX qui n'apparaît pas dans la barre des tâches, comme des accessoires de bureau, et qui n'a pas de bordure et n'est pas carrée.
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();
}
}
** Résultat d'exécution **
La description
--Si vous spécifiez StageStyle.UTILITY
avec ʻinitStyle () of
Stage`, vous pouvez créer une fenêtre qui ne s'affiche pas dans la barre des tâches.
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();
}
}
** Résultat d'exécution **
La description
StageStyle.TRANSPARENT
avec ʻinitStyle ()de
Stage. --Si cela est spécifié, le cadre de la fenêtre disparaît et l'arrière-plan de
Stagedevient transparent. --Cependant, dans ce cas ** la barre des tâches s'affiche ** --Spécifiez
Color.TRANSPARENT avec
setFill () ʻof Scene
à placer sur Stage
pour rendre le fond de Scene
transparent.Scene
déterminera la forme de la fenêtre, donc si vous changez la forme du cadre avec -fx-background-radius
etc., vous pouvez changer la forme de la fenêtre. Sera capable de changer enUTILITY |
TRANSPARENT |
|
---|---|---|
Masquer la barre des tâches | OK | NG |
Fenêtre non rectangulaire | NG | OK |
Comme ça, chacun a les fonctions que vous voulez et les fonctions dont vous n'avez pas besoin, donc si vous vous tenez là, vous ne pouvez pas vous lever. En avril 2018, il ne semble y avoir aucun moyen de combiner ces deux proprement.
Le problème d'OpenJDK mentionne ce problème, mais il a été mis à jour pour la dernière fois en mai 2017 et il ne semble y avoir aucun progrès depuis.
[JDK-8091566] Taskbar-less Undecorated Transparent Window - Java Bug System
Comme mentionné dans le problème ci-dessus, vous pouvez combiner les deux de force.
Plus précisément, c'est comme suit.
--Définissez la scène principale sur StageStyle.UTILITY
et déplacez-la vers un endroit invisible en dehors de l'écran.
――Créez une autre étape
et
--Définissez StageStyle.TRANSPARENT
--Définissez la scène principale au propriétaire
En d'autres termes, l'étape principale est utilisée uniquement pour utiliser la fonction de ʻUTILITYqui n'affiche pas la barre des tâches, et elle n'est pas affichée à l'écran, et la fenêtre visible réelle est faite par une autre
étape avec
TRANSPARENT`. La méthode.
Les préoccupations de cette méthode sont expliquées dans le problème ci-dessus comme suit:
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.
(Traduction) C'est un piratage dangereux. Cela est dû au fait que la fenêtre UTILITY peut revenir à la fenêtre principale si l'écran de l'ordinateur est redimensionné, par exemple en connectant une session de bureau à distance, et le système d'exploitation décide de renvoyer toutes les positions de la fenêtre dans la zone visible. Les tests disent que cela ne se produit pas, mais je pense que cela se produira probablement dans certains cas.
Il semble que cela ne se produit pas dans le test, mais il semble que ce ne soit pas une solution propre. Il est facile d'imaginer que si quelque chose ne va pas et que la scène principale est visible, ce sera assez moche.
Pour contourner le problème, j'ai également défini l''opacité 'de l'étape principale sur' 0 '. Si ʻopacity` est pris en charge, l'étage principal ne sera pas visible s'il entre accidentellement dans la zone visible. Cependant, cela n'a pas de sens dans un environnement où «opacity» n'est pas supporté, donc je pense qu'il sera nécessaire de le déplacer hors de l'écran.
En plus de la combinaison forcée mentionnée ci-dessus, si l'implémentation telle que la barre d'état système est incluse, le résultat final sera le suivant.
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);
}
}
** Résultat d'exécution **
On dirait que tu traînes
On dirait qu'il est dans la barre d'état système
La description
Platform.setImplicitExit (false);
Main.java
@Override
public void start(Stage primaryStage) throws Exception {
Platform.setImplicitExit(false);
false
** Comment utiliser la barre d'état système avec JavaFX **
Recommended Posts