Java/JavaFX AWT (MenuItem) to JavaFX (event)

51 views Asked by At

I have one suspended state of my application that I can't get around in any way. I was able to successfully create an application that has absolutely all the functionality. I decided to practice a little and add the ability of the application to work in the tray, for this I created a tray icon with a menu (Open and Close the application window).

private TrayIcon trayIcon;
private PopupMenu popup;
private MenuItem openItem;
private MenuItem closeItem;
private System Tray tray; 

there are only two options in my menu, close Item - "Close", which works wonderfully, and open Item - "Open", which broke my head. The main idea is that I have a primaryStage that hides in the tray when you click the "cross" button on the main window (anyway, I guess it should be like this), I implemented it like this:

primaryStage.setOnCloseRequest(event -> {
            event.consumer();
            primaryStage.hide();
        });

Next, when I click the tray icon, the menu is displayed, I press the "Open" button. And visually nothing happens. Next, I went into debug mode, added messages for debugging and saw this behavior that on the line: Platform.runLater(new Runnable() { the compiler passes to:

public static void runLater(Runnable runnable) {
        PlatformImpl.runLater(runnable);
    }

some object, then returns back to my method and ignoring the run method exits the method, you can get there again by initiating an event by clicking on the "Open" button. The implementation was written through lambda expressions, but I expanded everything for a better understanding of the process.

What should I change in the code so that the window of my JavaFX application finally opens at the click of the menu button?

openItem.addActionListener(new ActionListener() {
   @Override
      public void actionPerformed(ActionEvent event) {
      System.out.println("Preparing to call Platform.runLater");
      System.out.println(Platform.isFxApplicationThread()); // here is FALSE
   
      Platform.runLater(new Runnable() {

          @Override
          public void run() { // leave from here to ...
             System.out.println("Executing in Platform.runLater");
             System.out.println(Platform.isFxApplicationThread());
             primaryStage.setIconified(false);
             primaryStage.show();
             primaryStage.toFront();
          }
      }); // to here ... and again, after pressing "OPEN"
    }
});

    closeItem = new MenuItem("Close");
    closeItem.addActionListener(event -> {
       Platform.exit();
       tray.remove(trayIcon);
       System.exit(0);
    });

Here is my Start method:

    @Override
    public void start(Stage primaryStage) throws IOException {
        primaryStage.setTitle("Meal Ordering App");
        FXMLLoader startLoader = new FXMLLoader(getClass().getResource("/Start.fxml"));
        Parent root = startLoader.load();
        Scene scene = new Scene(root);
        primaryStage.setScene(scene);

        prepareTrayIcon(primaryStage);
        primaryStage.show();

        primaryStage.setOnCloseRequest(event -> {
            System.out.println("Closing window requested");
            event.consume();
            System.out.println("event is consumed? " + event.isConsumed());
            primaryStage.hide();
        });

        scheduleNotifications();
    }

I rewrote it in different ways, it didn’t help

0

There are 0 answers