forked from Qortal/qortal
Convert SysTray to use JPopupMenu for Unicode support
Correct Systray_zh.properties to ISO 8859-1 instead of UTF-8. Added SysTray test to GuiTests
This commit is contained in:
parent
6942c02700
commit
f8b496ff3c
@ -1,15 +1,22 @@
|
||||
package org.qora.gui;
|
||||
|
||||
import java.awt.AWTException;
|
||||
import java.awt.MenuItem;
|
||||
import java.awt.PopupMenu;
|
||||
import java.awt.SystemTray;
|
||||
import java.awt.TrayIcon;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.event.WindowFocusListener;
|
||||
import java.net.URL;
|
||||
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.SwingWorker;
|
||||
import javax.swing.event.PopupMenuEvent;
|
||||
import javax.swing.event.PopupMenuListener;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
@ -24,15 +31,47 @@ public class SysTray {
|
||||
|
||||
private static SysTray instance;
|
||||
private TrayIcon trayIcon = null;
|
||||
private PopupMenu popupMenu = null;
|
||||
private JPopupMenu popupMenu = null;
|
||||
/** The hidden dialog has 'focus' when menu displayed so closes the menu when user clicks elsewhere. */
|
||||
private JDialog hiddenDialog = null;
|
||||
|
||||
private SysTray() {
|
||||
if (!SystemTray.isSupported())
|
||||
return;
|
||||
|
||||
this.popupMenu = createPopupMenu();
|
||||
this.popupMenu = createJPopupMenu();
|
||||
|
||||
this.trayIcon = new TrayIcon(Gui.loadImage("icons/icon32.png"), "qora-core", popupMenu);
|
||||
// Build TrayIcon without AWT PopupMenu (which doesn't support Unicode)...
|
||||
this.trayIcon = new TrayIcon(Gui.loadImage("icons/icon32.png"), "qora-core", null);
|
||||
// ...and attach mouse listener instead so we can use JPopupMenu (which does support Unicode)
|
||||
this.trayIcon.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mousePressed (MouseEvent me) {
|
||||
this.maybePopupMenu(me);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased (MouseEvent me) {
|
||||
this.maybePopupMenu(me);
|
||||
}
|
||||
|
||||
private void maybePopupMenu(MouseEvent me) {
|
||||
if (me.isPopupTrigger()) {
|
||||
// We destroy, then recreate, the hidden dialog to prevent taskbar entries on X11
|
||||
if (!popupMenu.isVisible())
|
||||
destroyHiddenDialog();
|
||||
|
||||
createHiddenDialog();
|
||||
hiddenDialog.setLocation(me.getX() + 1, me.getY() - 1);
|
||||
popupMenu.setLocation(me.getX() + 1, me.getY() - 1);
|
||||
|
||||
popupMenu.setInvoker(hiddenDialog);
|
||||
|
||||
hiddenDialog.setVisible(true);
|
||||
popupMenu.setVisible(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.trayIcon.setImageAutoSize(true);
|
||||
|
||||
@ -43,6 +82,81 @@ public class SysTray {
|
||||
}
|
||||
}
|
||||
|
||||
private void createHiddenDialog() {
|
||||
if (hiddenDialog != null)
|
||||
return;
|
||||
|
||||
hiddenDialog = new JDialog();
|
||||
hiddenDialog.setUndecorated(true);
|
||||
hiddenDialog.setSize(10, 10);
|
||||
hiddenDialog.addWindowFocusListener(new WindowFocusListener () {
|
||||
@Override
|
||||
public void windowLostFocus (WindowEvent we ) {
|
||||
destroyHiddenDialog();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowGainedFocus (WindowEvent we) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void destroyHiddenDialog() {
|
||||
if (hiddenDialog == null)
|
||||
return;
|
||||
|
||||
hiddenDialog.setVisible(false);
|
||||
hiddenDialog.dispose();
|
||||
hiddenDialog = null;
|
||||
}
|
||||
|
||||
private JPopupMenu createJPopupMenu() {
|
||||
JPopupMenu menu = new JPopupMenu();
|
||||
|
||||
menu.addPopupMenuListener(new PopupMenuListener() {
|
||||
@Override
|
||||
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
|
||||
destroyHiddenDialog();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void popupMenuCanceled(PopupMenuEvent e) {
|
||||
}
|
||||
});
|
||||
|
||||
JMenuItem openUi = new JMenuItem(Translator.INSTANCE.translate("SysTray", "OPEN_NODE_UI"));
|
||||
openUi.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
destroyHiddenDialog();
|
||||
|
||||
try {
|
||||
URLViewer.openWebpage(new URL("http://localhost:" + Settings.getInstance().getUiPort()));
|
||||
} catch (Exception e1) {
|
||||
LOGGER.error("Unable to open node UI in browser");
|
||||
}
|
||||
}
|
||||
});
|
||||
menu.add(openUi);
|
||||
|
||||
JMenuItem exit = new JMenuItem(Translator.INSTANCE.translate("SysTray", "EXIT"));
|
||||
exit.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
destroyHiddenDialog();
|
||||
|
||||
new ClosingWorker().execute();
|
||||
}
|
||||
});
|
||||
menu.add(exit);
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
class ClosingWorker extends SwingWorker<Void, Void> {
|
||||
@Override
|
||||
protected Void doInBackground() {
|
||||
@ -56,32 +170,6 @@ public class SysTray {
|
||||
}
|
||||
}
|
||||
|
||||
private PopupMenu createPopupMenu() {
|
||||
PopupMenu menu = new PopupMenu();
|
||||
|
||||
MenuItem openUi = new MenuItem(Translator.INSTANCE.translate("SysTray", "OPEN_NODE_UI"));
|
||||
openUi.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
try {
|
||||
URLViewer.openWebpage(new URL("http://localhost:" + Settings.getInstance().getUiPort()));
|
||||
} catch (Exception e1) {
|
||||
LOGGER.error("Unable to open node UI in browser");
|
||||
}
|
||||
}
|
||||
});
|
||||
menu.add(openUi);
|
||||
|
||||
MenuItem exit = new MenuItem(Translator.INSTANCE.translate("SysTray", "EXIT"));
|
||||
exit.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
new ClosingWorker().execute();
|
||||
}
|
||||
});
|
||||
menu.add(exit);
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
public static SysTray getInstance() {
|
||||
if (instance == null)
|
||||
instance = new SysTray();
|
||||
|
@ -1,7 +1,7 @@
|
||||
# SysTray pop-up menu
|
||||
OPEN_NODE_UI=开启界面
|
||||
EXIT=退出软件
|
||||
OPEN_NODE_UI=\u5F00\u542F\u754C\u9762
|
||||
EXIT=\u9000\u51FA\u8F6F\u4EF6
|
||||
|
||||
# Nagging about lack of NTP time sync
|
||||
NTP_NAG_CAPTION=没有连接上节点?
|
||||
NTP_NAG_TEXT=请启用Windows自动时间同步。
|
||||
NTP_NAG_CAPTION=\u6CA1\u6709\u8FDE\u63A5\u4E0A\u8282\u70B9\uFF1F
|
||||
NTP_NAG_TEXT=\u8BF7\u542F\u7528Windows\u81EA\u52A8\u65F6\u95F4\u540C\u6B65\u3002
|
||||
|
@ -2,6 +2,7 @@ package org.qora.test;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.qora.gui.SplashFrame;
|
||||
import org.qora.gui.SysTray;
|
||||
|
||||
public class GuiTests {
|
||||
|
||||
@ -14,4 +15,13 @@ public class GuiTests {
|
||||
splashFrame.dispose();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSysTray() throws InterruptedException {
|
||||
SysTray.getInstance();
|
||||
|
||||
while(true) {
|
||||
Thread.sleep(2000L);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user