JavaFX - PriorityQueue和Threads

时间:2016-05-19 18:03:27

标签: java multithreading javafx-2 priority-queue

我有一个没有阶段的JavaFx应用程序。它仅在系统托盘上运行。基本上它会收听服务并根据它显示通知。

应用和服务之间的连接是使用Socket完成的。 但是,服务可以发送优先级消息,该消息将首先显示在其他消息上。

问题:我在PriorityQueue中收到了所有邮件,但我不知道如何处理通知等待其他完成显示。这是最好的方法吗?架构是否正确?另外,由于TrayNotification类会显示Scene,因此我害怕出现UI线程问题。

这是消息类:

public class Message implements Comparable<Message> {

    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());
    }
}

在配置托盘后,我的应用程序类 SystemtrayLauncher start方法上有此代码:

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

ServiceConnector (我认为需要对其进行改进以处理PriorityQueue):

public class ServiceConnector extends Task<Void> {

    private ServerSocket socket;
    private int port;
    public static PriorityQueue<Message> messageQueue = new PriorityQueue<>();

    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(() -> 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;
    }
}

消息监听

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();
    }
}

0 个答案:

没有答案