JavaFX - PriorityQueue and Threads
<p>I have an JavaFx application that has no stage. It only runs at system tray. Basically it listen to a service and show notification according to it.</p>

<p>The connection between app and service is done using <code>Socket</code>.
However, service can send a priority message, which will be shown first than others.</p>

<p>The problem: I have all my messages in a PriorityQueue but I don't know how to handle a notification await for the other finish to show. Is that the best approach? Is the architecture correct? Also, since <code>TrayNotification</code> class will show a <code>Scene</code>, I'm afraid of having problems with UI Thread.</p>

<p>This is <strong>Message</strong> class:</p>

<pre><code>public class Message implements Comparable&lt;Message&gt; {

    private int priority;
    private String notificationType;
    private String title;
    private String message;

    public Message() {

    }

    public Message (int priority, String notificationType, String title, String message) {
        this.priority = priority;
        this.notificationType = notificationType;
        this.title = title;
        this.message = message;
    }

    public void setPriority(int priority) {
        this.priority = priority;
    }

    public int getPriority() {
        return this.priority;
    }

    public void setNotificationType(String notificationType) {
        this.notificationType = notificationType;
    }

    public NotificationType getNotificationType() {
        if (this.notificationType.equals(NotificationType.CUSTOM.toString())) {
            return NotificationType.CUSTOM;
        }
        else if (this.notificationType.equals(NotificationType.ERROR.toString())) {
            return NotificationType.ERROR;
        }
        else if (this.notificationType.equals(NotificationType.INFORMATION.toString())) {
            return NotificationType.INFORMATION;
        }
        else if (this.notificationType.equals(NotificationType.NOTICE.toString())) {
            return NotificationType.NOTICE;
        }
        else if (this.notificationType.equals(NotificationType.SUCCESS.toString())) {
            return NotificationType.SUCCESS;
        }
        else if (this.notificationType.equals(NotificationType.WARNING.toString())) {
            return NotificationType.WARNING;
        }
        else {
            throw new IllegalArgumentException("Invalid notification type.");
        }
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getTitle() {
        return this.title;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public String getMessage() {
        return this.message;
    }

    @Override
    public int compareTo(Message otherMessage) {
        return Integer.compare(this.priority, otherMessage.getPriority());
    }
}
</code></pre>

<p>My application class, <strong>SystemtrayLauncher</strong>, has this code on <code>start</code> method, after configuring tray:</p>

<pre><code>/** Start to listen to service **/
ServiceConnector connector = new ServiceConnector(8888);
new Thread(connector).start();
</code></pre>

<p><strong>ServiceConnector</strong> (which I think needs to be improved to handle <code>PriorityQueue</code>):</p>

<pre><code>public class ServiceConnector extends Task&lt;Void&gt; {

    private ServerSocket socket;
    private int port;
    public static PriorityQueue&lt;Message&gt; messageQueue = new PriorityQueue&lt;&gt;();

    public ServiceConnector(int port) {
        this.port = port;
    }

    public void connect() {

        try {
            System.out.println("Opening connection...");
            socket = new ServerSocket(this.port);
            socket.setSoTimeout(0);

            System.out.println("Connection opened at port " + this.port);

            while (true) {

                System.out.println("Awaiting service connection...");
                Socket service = socket.accept();
                System.out.println(
                    "Service at " + service.getInetAddress().getHostAddress() + " connected");

                Message message = MessageListener.getMessage(service);

                if (message != null) {
                    messageQueue.offer(message);

                    // get top priority message
                    Platform.runLater(() -&gt; MessageListener.notifyUser(messageQueue.peek()));
                }
                else {
                    CustomAlert dialog = new CustomAlert(Alert.AlertType.ERROR);
                    dialog.setContentText(SystemConfiguration.LOCALE.getString("MESSAGE_ERROR"));
                    dialog.showAndWait();
                }

                service.close();
            }

        } catch (IOException exc) {
            exc.printStackTrace();
        }
    }

    @Override
    protected Void call() throws Exception {
        this.connect();
        return null;
    }
}
</code></pre>

<p><strong>MessageListener</strong></p>

<pre><code>public class MessageListener {

    private static TrayNotification trayNotification;

    public static Message getMessage(Socket service) {
        System.out.println("Processing message...");

        try {
            BufferedReader inputReader =
                new BufferedReader(new InputStreamReader(service.getInputStream()));

            /**
             * JSON format:
             * {
             *     "priority": "1 for urgent and greater with less priority",
             *     "notificationType": "ERROR|INFORMATION|NOTICE|SUCCESS|WARNING",
             *     "title": "A string to be show as notification windows title",
             *     "message": "A string to be show as message"
             * }
             */

            JSONObject jsonMessage = new JSONObject(inputReader.readLine());

            Message message = new Message();
            message.setPriority(jsonMessage.getInt("priority"));
            message.setNotificationType(jsonMessage.getString("notificationType"));
            message.setTitle(jsonMessage.getString("title"));
            message.setMessage(jsonMessage.getString("message"));

            inputReader.close();
            service.close();

            System.out.println("Message with priority " + message.getPriority() + " processed.");

            return message;

        } catch (IOException exc) {
            exc.printStackTrace();
            return null;
        }
    }

    /**
     * Notify user with processed service message.
     * @param message
     *
     */
    public static void notifyUser(Message message) {

        System.out.println("Priority: " + message.getPriority());

        trayNotification = new TrayNotification();
        trayNotification.setAnimationType(AnimationType.POPUP);
        trayNotification.setRectangleFill(Paint.valueOf("#0277BD"));
        trayNotification.setImage(new Image(SystemConfiguration.ICON));

        trayNotification.setNotificationType(message.getNotificationType());
        trayNotification.setTitle(message.getTitle());
        trayNotification.setMessage(message.getMessage());

        trayNotification.showAndDismiss(Duration.seconds(3.5));

        ServiceConnector.messageQueue.poll();
    }
}
</code></pre>