我有一个没有阶段的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();
}
}