MenuShortcut KeyEvent not working - java

The code below is a testable class that should print out some text when control+A has been pushed on the keyboard, and will also display an image in the system tray. This is all dependent on the system tray being supported by your operating system.
My issue is that the text is not being printed out when I push control+A, it is only printed when I press the item in the system tray.
/**
*
* #author Tyluur
* #since Aug 23, 2013
*/
public class Testable {
public static void main(String... args) {
registerTrayItems();
}
private static void registerTrayItems() {
if (SystemTray.isSupported()) {
SystemTray tray = SystemTray.getSystemTray();
TrayIcon icon = null;
MenuShortcut shortcut = new MenuShortcut(KeyEvent.VK_A);
MenuItem menuItem = new MenuItem("Toggle", shortcut);
menuItem.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.err.println("The action has been called!");
}
});
PopupMenu popup = new PopupMenu();
popup.add(menuItem);
try {
icon = new TrayIcon(new ImageIcon(new URL("http://i.imgur.com/xQoz2TN.png")).getImage(), "Typer", popup);
tray.add(icon);
} catch (MalformedURLException | AWTException e) {
e.printStackTrace();
}
}
}
}

The reason your code is not working is because Java is not 'globally' listening for your key event, but only when the menu has your focus and is shown.
This is also the reason why there is no possibility to write a pure Java keylogger. Java only allows you to capture window-directed messages.
A workaround would be to implement one of these options:
Use JNI/JNA/whatever native wrapper to access global key hooking
Use an invisible window, always being on top and not shown in the system tray that captures the events. I would not suggest using this one as it may either not work like a charm or annoys your user.
The top approach is not a hard one but will require you to use native access and therefor your application becomes platform-specific.
Good luck!

From the API, it looks like you should try this constructor for the MenuItem()
MenuShortcut shortcut = new MenuShortcut(KeyEvent.VK_A, false);
as the default is to require that the Shift key be pressed too.

Related

Netbeans Module: open JFrame on button click

I am coding a module for Netbeans where I have a button that when clicked will open a JFrame.
This is the action listener class of the button:
// ... (package and imports)
#ActionID(
category = "File",
id = "org.myorg.readabilitychecker.ReadabilityActionListener"
)
#ActionRegistration(
iconBase = "org/myorg/readabilitychecker/google.png",
displayName = "#CTL_ReadabilityActionListener"
)
#ActionReference(path = "Toolbars/File", position = 0)
#Messages("CTL_ReadabilityActionListener=Readability")
public final class ReadabilityActionListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
JFrame readabilityFrame = new ReadabilityFrame();
readabilityFrame.setVisible(true);
}
}
In the JFrame I basically have:
public static void main(String args[]) {
* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new ReadabilityFrame().setVisible(true);
}
});
}
It also has some other automatically generated code, but nothing important.
When I run the application, the button appears in the toolbar, but when I click it, the JFrame doesn't open.
I tried checking if a print inside the actionPerformed() method would show in the output terminal and it does, so I guess that I am missing something while calling the JFrame.
Can anyone give me a hint on where the problem is?
I think the issue is with the object creation of your frame. Try
ReadabilityFrame readabilityFrame = new ReadabilityFrame();
readabilityFrame.setVisible(true);
Hope it helps.
I found where was the problem.
The method initComponents() automatically generated had the line setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); and it was always throwing an exception.
I just changed EXIT_ON_CLOSE to DISPOSE_ON_CLOSE, defined the frame in a different way and now, the problem disappeared.

Disable non-SWT window while SWT dialog showing

I'm mixing SWT with a non-SWT window (formerly an AWT window but I'm now using a native GLFW window). When I call fileDialog.show(), I would like the file dialog to get the full application context, where it is drawn on top of the existing non-SWT window, and the non-SWT window cannot be clicked. i.e., the same behavior as when using AWT with an AWT FileDialog.
However, when I show the SWT FileDialog, it still allows me to click the other window and bring that window to front.
Here's how I set up my app. I'm using LWJGL 3 (via LibGDX), which in turn creates a native window through a GLFW binding. And this is part of the reason I'm using SWT...GLFW does not support AWT or Swing.
public static void main (String[] arg) {
//...
new Lwjgl3Application(app, config); //starts an OpenGL loop in a native GLFW window
prepareSWT();
}
static void prepareSWT (){
swtThread = new Thread(new Runnable (){
#Override
public void run() {
swtDisplay = new Display();
swtShell = new Shell(swtDisplay);
while (!swtDisplay.isDisposed()) {
if (!swtDisplay.readAndDispatch())
swtDisplay.sleep();
}
swtDisplay.dispose();
}
});
swtThread.start();
}
public static void showSWTFileChooserDialog (final FileChooserResult fileChooserResult){
swtDisplay.asyncExec(new Runnable() {
#Override
public void run() {
final org.eclipse.swt.widgets.FileDialog fileChooser =
new org.eclipse.swt.widgets.FileDialog(swtShell, SWT.OPEN);
fileChooser.open();
String filename = fileChooser.getFileName();
if (filename == null || filename.equals("")){
fileChooserResult.file = null;
} else {
fileChooserResult.file = new File(fileChooser.getFilterPath(), filename);
}
fileChooserResult.ready = true;
}
});
}
I'm at a loss for how to get the FileDialog to be forced on top of the non-SWT window.
Setting the SWT.SYSTEM_MODAL style on the Shell will block input to all applications' windows on the system.
http://help.eclipse.org/luna/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/SWT.html#SYSTEM_MODAL

Virtual keyboard conflicts with Nimbus

I was wondering why Nimbus would be conflicting somehow with Virtual keys. Check out the sample I made below:
public class buttontest implements ActionListener {
JMenuItem close =new JMenuItem("Close");
public static void main (String[] args){
try {
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (UnsupportedLookAndFeelException e) {
// handle exception
} catch (ClassNotFoundException e) {
// handle exception
} catch (InstantiationException e) {
// handle exception
} catch (IllegalAccessException e) {
// handle exception
}
}
public buttontest(){
JFrame test = new JFrame();
JMenuBar bar=new JMenuBar();
JMenu file=new JMenu("File");
close.setMnemonic(KeyEvent.VK_C);
file.setMnemonic(KeyEvent.VK_F);
test.setExtendedState(test.getExtendedState() | test.MAXIMIZED_BOTH); // Maximized Window or setSize(getMaximumSize())
test.setDefaultCloseOperation(1);
bar.add(file);
file.add(close);
test.setJMenuBar(bar);
test.setVisible(true);
}
public void actionPerformed(ActionEvent e){
if(e.getSource()==close){
System.exit(0);
}
}
}
The way its wrote, you can try to use the Virtual keys. You will see that Alt F works to open the File menu but Alt C doesnt close the application. In other way, if you comment the Nimbus code both virtual Keys will work.
I made one research regarding to this "bug" (or maybe something wrong Im doing that Im not aware) but until now I found nothing. Has someone ever passed through this?
You have to use setAccelerator() method for JMenuItem:
close.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.ALT_MASK ));
From Javadoc:
JMenuItem#setAccelerator(KeyStroke)
Sets the key combination which
invokes the menu item's action listeners without navigating the menu
hierarchy. It is the UI's responsibility to install the correct
action. Note that when the keyboard accelerator is typed, it will work
whether or not the menu is currently displayed.
Additional note:
Replace LookAndFeelInfo to UIManager.LookAndFeelInfo as it's an inner class inside UIManager.
Call the constructor in the main method.
Change the parameter of setDefaultCloseOperation(1) to 3 as 3 = JFrame.EXIT_ON_CLOSE, but 1=JFrame.HIDE_ON_CLOSE which hides the frame, personally, I hate it, because close button created for closing frame, not hiding it, like Skype.
Add actionListener to close button :close.addActionListener(this);

Java swt treeview popup menu

Hiho,
currently I have a working popup menu which appears when I click on a treeview item.
But I want to show different popups for different tree view entries. I don't get a idea how to do so...
Here is my code for creating the menu:
MenuManager menuMgr = new MenuManager("#PopupMenu");
menuMgr.setRemoveAllWhenShown(true);
menuMgr.addMenuListener(new IMenuListener() {
#Override
public void menuAboutToShow(IMenuManager manager) {
Action action = new Action() {
public void run() {
// So something
}
};
action.setText("Set as working file");
manager.add(action);
}
});
Menu menu = menuMgr.createContextMenu(getTree());
getTree().setMenu(menu);
You should propably use a MouseListener on the tree:
final Tree tree = new Tree(parent, ...);
tree.addMouseListener(new MouseAdapter() {
#override
public void mouseDown(MouseEvent me) {
if(tree.getSelection() instanceof MySpecificTreeNode) {
// create menu...
}
}
});
Two ideas. For both you need to listen to selections on the TreeView, because that's the only way to determine which Menu (or special content) you want to show.
Then you could either set the correct menu to the the tree right after you know which one to use or contribute the needed items to the existing menu (that's how it's done in the eclipse framework).

How would i program a dynamic menubar in Swing?

Basically i want to be able to allow the user to save bookmarks which are then put into a list on a submenu on a menubar. How would i go about programming a general function for any number of bookmarks that may be added, i basically want the items to put the URL into a textbox when clicked. Would i need to create a new class for this, or is there an inbuilt function?
My program is a simple RSS reader written in Java using Swing.
You need to add a MenuListener to the menu item that you want to be dynamic.
In the void menuSelected(MenuEvent e) method, implement the construction of the submenus.
In a first implementation, you can first reset the content of your menu and then rebuid it from scratch instead of updating it :
JMenu menu = new JMenu("Bookmarks");
menu.addMenuListener(new MyMenuListener());
private class MyMenuListener implements MenuListener {
public void menuCanceled(MenuEvent e) { }
public void menuDeselected(MenuEvent e) { }
public void menuSelected(MenuEvent e) {
JMenu menu = (JMenu) e.getSource();
populateWindowMenu(menu);
}
}
void populateWindowMenu(JMenu windowMenu) {
windowMenu.removeAll();
// Populate the menu here
}

Categories