Чтобы скрыть приложение JavaFx fxml или JavaFx swing в системном трее

Я хочу разработать клиентское приложение для веб-сайта.

Я хочу, чтобы приложение находилось в панели задач в свернутом виде.

Я не знаю, как выполнить эту задачу.

Есть какой-нибудь их пример для этого типа операции.


person Mohammad Sadiq Shaikh    schedule 31.01.2013    source источник
comment
Правильный ответ находится здесь   -  person Aubin    schedule 25.03.2017


Ответы (2)


Ключевым моментом здесь является установка неявного выхода на false Platform.setImplicitExit(false); Также важно показать и скрыть этап в новом потоке.

 Platform.runLater(new Runnable() {
    @Override
    public void run() {
        stage.show();
    }
 });

 Platform.runLater(new Runnable() {
    @Override
    public void run() {
        stage.hide();
    }
 });

Далее весь код:

import java.awt.AWTException;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.TrayIcon;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.URL;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
import javax.imageio.ImageIO;

/**
 *
 * @author alvaro
 */
public class TrayTest extends Application {

    private boolean firstTime;
    private TrayIcon trayIcon;


    public static void main(String[] args)
    {
        launch(args);
    }

    @Override
    public void start(Stage stage) throws Exception {
        createTrayIcon(stage);
        firstTime = true;
        Platform.setImplicitExit(false);
        Scene scene = new Scene(new Group(), 800, 600);
        stage.setScene(scene);
        stage.show();

    }

    public void createTrayIcon(final Stage stage) {
        if (SystemTray.isSupported()) {
            // get the SystemTray instance
            SystemTray tray = SystemTray.getSystemTray();
            // load an image
            java.awt.Image image = null;
            try {
                URL url = new URL("http://www.digitalphotoartistry.com/rose1.jpg");
                image = ImageIO.read(url);
            } catch (IOException ex) {
                System.out.println(ex);
            }


            stage.setOnCloseRequest(new EventHandler<WindowEvent>() {
                @Override
                public void handle(WindowEvent t) {
                    hide(stage);
                }
            });
            // create a action listener to listen for default action executed on the tray icon
            final ActionListener closeListener = new ActionListener() {
                @Override
                public void actionPerformed(java.awt.event.ActionEvent e) {
                    System.exit(0);
                }
            };

            ActionListener showListener = new ActionListener() {
                @Override
                public void actionPerformed(java.awt.event.ActionEvent e) {
                    Platform.runLater(new Runnable() {
                        @Override
                        public void run() {
                            stage.show();
                        }
                    });
                }
            };
            // create a popup menu
            PopupMenu popup = new PopupMenu();

            MenuItem showItem = new MenuItem("Show");
            showItem.addActionListener(showListener);
            popup.add(showItem);

            MenuItem closeItem = new MenuItem("Close");
            closeItem.addActionListener(closeListener);
            popup.add(closeItem);
            /// ... add other items
            // construct a TrayIcon
            trayIcon = new TrayIcon(image, "Title", popup);
            // set the TrayIcon properties
            trayIcon.addActionListener(showListener);
            // ...
            // add the tray image
            try {
                tray.add(trayIcon);
            } catch (AWTException e) {
                System.err.println(e);
            }
            // ...
        }
    }

    public void showProgramIsMinimizedMsg() {
        if (firstTime) {
            trayIcon.displayMessage("Some message.",
                    "Some other message.",
                    TrayIcon.MessageType.INFO);
            firstTime = false;
        }
    }

    private void hide(final Stage stage) {
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                if (SystemTray.isSupported()) {
                    stage.hide();
                    showProgramIsMinimizedMsg();
                } else {
                    System.exit(0);
                }
            }
        });
    }
}
person alscu    schedule 31.01.2013
comment
JavaFx 8 уже вышел. Можно ли теперь использовать системный лоток без AWT? JavaFx выглядит намного лучше. - person qed; 03.08.2014
comment
У меня это не работает в OS X. Когда я нахожу на значок в трее, он зависает. - person Ascherer; 05.09.2015
comment
@Ascherer Вы нашли решение для OS X? - person thanili; 12.11.2015
comment
После того, как я закрываю приложение (скрываю), приложение Thread (графическое) закрывается, и после этого его невозможно восстановить из системного трея. Я использую java 8u66. Я думаю, что метод stage.hide () нарушает работу. - person Guerino Rodella; 26.11.2015
comment
Я нашел решение своей проблемы. Далее следует ссылка на stackoverflow. stackoverflow.com/questions/32355335/ - person Guerino Rodella; 26.11.2015
comment
Хороший ответ. Предлагаю модификацию в showListener if (!stage.isShowing()) stage.show(); else if (stage.isIconified()) stage.setIconified(false); else hide(stage); - person Solostaran14; 26.02.2016
comment
Ключевым моментом здесь является установка неявного выхода на false Platform.setImplicitExit(false); Также важно показать и скрыть этап в новом потоке. - person juliocb92; 01.02.2018
comment
@thanil, @Ascherer Для решения проблемы зависания OS X удалите вызов `trayIcon.displayMessage` - person Rafael Membrives; 20.03.2019

Насколько я знаю, это будет возможно в JFX 8. Сейчас лучшее решение - встроить ваше приложение в AWT и скрыть само окно AWT.

person Lakatos Gyula    schedule 31.01.2013
comment
Ответ @alscu был тем, что вы объяснили .. Спасибо - person Mohammad Sadiq Shaikh; 01.02.2013
comment
JavaFx 8 уже вышел. Можно ли теперь использовать системный лоток без AWT? JavaFx выглядит намного лучше. - person qed; 03.08.2014