I have an applicaton that implements a listener for smartcards reader.
When I run the application I send it to tray.
When the aplication detects a card I want it to restore the jFrame back to normal so the user can select the options available on the screen.
Problem is when I try to restore the window it creates a new one.
How is possible to restore the jFrame back to normal.
This code is what I have inside the jFrame constructor:
It creates the tray Icon and the options Close and Open. But I want it to open automatically. Is it possible to programatically click the Open option?
initComponents();
setResizable(false);
setLocationRelativeTo(null);
setTitle("App Title");
UFRInstance = (uFrFunctions) Native.loadLibrary(GetLibFullPath(false), uFrFunctions.class);
this.wsc = new WebSocketConnection();
System.out.println("creating instance");
try {
System.out.println("setting look and feel");
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
System.out.println("Unable to set LookAndFeel");
}
if (SystemTray.isSupported()) {
System.out.println("system tray supported");
tray = SystemTray.getSystemTray();
Image image = Toolkit.getDefaultToolkit().getImage("bulb.png");
ActionListener exitListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("Exiting....");
System.exit(0);
}
};
PopupMenu popup = new PopupMenu();
MenuItem defaultItem = new MenuItem("Close");
defaultItem.addActionListener(exitListener);
popup.add(defaultItem);
defaultItem = new MenuItem("Open");
defaultItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
setVisible(true);
setExtendedState(JFrame.NORMAL);
}
});
popup.add(defaultItem);
trayIcon = new TrayIcon(createIcon("bulb.png", "Icon"), "SystemTray Demo", popup);
trayIcon.setImageAutoSize(true);
} else {
System.out.println("system tray not supported");
}
addWindowStateListener(new WindowStateListener() {
public void windowStateChanged(WindowEvent e) {
if (e.getNewState() == ICONIFIED) {
try {
tray.add(trayIcon);
setVisible(false);
System.out.println("added to SystemTray");
} catch (AWTException ex) {
System.out.println("unable to add to tray");
}
}
if (e.getNewState() == 7) {
try {
tray.add(trayIcon);
setVisible(false);
System.out.println("added to SystemTray");
} catch (AWTException ex) {
System.out.println("unable to add to system tray");
}
}
if (e.getNewState() == MAXIMIZED_BOTH) {
tray.remove(trayIcon);
setVisible(true);
System.out.println("Tray icon removed");
}
if (e.getNewState() == NORMAL) {
tray.remove(trayIcon);
setVisible(true);
System.out.println("Tray icon removed1");
}
}
});
setIconImage(Toolkit.getDefaultToolkit().getImage("bulb.png"));
setIconImage(Toolkit.getDefaultToolkit().getImage(getClass().getResource("bulb.png")));
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
You code contains the "Open" option, adding an ActionListener:
defaultItem = new MenuItem("Open");
defaultItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
setVisible(true);
setExtendedState(JFrame.NORMAL);
}
So all you need to do is call setVisible(true); and maybe the second line as well.
You need to do visible. Like Below example :
int state = getExtendedState();
state = state & ~Frame.ICONIFIED;
setExtendedState(state);
setVisible(true);
The first line retrieves the current state, which is a bitmask. It then sets the ICONIFIED (minimized) part to false, then sets the same state again. This way, if the program was maximized before it will be maximimized again, etc. Of course a setVisible(true) must follow to show the window again.
This question is similar to this one. What I have is a JPopupMenu that pops up from an icon on the system tray. At this point, the system tray is the only manifestation of the program. That is, there are no other windows open, the icon in the system tray is the only way I can access the program. I used a JPopupMenu over the AWT PopupMenu because I wanted to get the system Look and Feel applied to the popup menu - when I used just a plain PopupMenu, I could not get the system's Look and Feel, I just kept getting Swing's Metal Look and Feel. I used this work-around to get this behavior (described here):
systemTrayPopupMenu = buildSystemTrayJPopupMenu();
trayIcon = new TrayIcon(iconImage, "Application Name", null /* Popup Menu */);
trayIcon.addMouseListener (new MouseAdapter () {
#Override
public void mouseReleased (MouseEvent me) {
if (me.isPopupTrigger()) {
systemTrayPopupMenu.setLocation(me.getX(), me.getY());
systemTrayPopupMenu.setInvoker(systemTrayPopupMenu);
systemTrayPopupMenu.setVisible(true);
}
}
};
When I right click on the tray icon, it shows the menu, and naturally, when I make a selection, the menu disappears. However, when I bring up the menu, then click out of it, it does not disappear. To make it disappear currently, I have to either make a selection, or select one of the menu items that are disabled.
I tried adding a FocusListener to it, however, there is no indication that the focusLost or focusGained methods ever get called. Additionally, I cannot make it disappear when another Window gains focus because there are no other windows present. Since this pop-up menu comes from a TrayIcon and not a typical button, I cannot use the solution mentioned here to get around the FocusListener not calling focusLost.
Ultimately, what I am wondering is either:
1) Is there a way to get the system's look and feel for a normal AWT PopupMenu?, or
2) Is there a way to make the JPopupMenu disappear when it loses focus?
EDIT: Per request, here is my SSCCE:
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;
public class SwingSystemTray {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run () {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
new SwingSystemTray ();
} catch (Exception e) {
System.out.println("Not using the System UI defeats the purpose...");
e.printStackTrace();
}
}
});
}
protected SystemTray systemTray;
protected TrayIcon trayIcon;
protected JPopupMenu systemTrayPopupMenu;
protected Image iconImage;
public SwingSystemTray () throws IOException {
iconImage = getIcon ();
if (SystemTray.isSupported()) {
systemTray = SystemTray.getSystemTray();
systemTrayPopupMenu = buildSystemTrayJPopupMenu();
trayIcon = new TrayIcon(iconImage, "Application Name", null /* Popup Menu */);
trayIcon.addMouseListener (new MouseAdapter () {
#Override
public void mouseReleased (MouseEvent me) {
if (me.isPopupTrigger()) {
systemTrayPopupMenu.setLocation(me.getX(), me.getY());
systemTrayPopupMenu.setInvoker(systemTrayPopupMenu);
systemTrayPopupMenu.setVisible(true);
}
}
});
try {
systemTray.add(trayIcon);
} catch (AWTException e) {
System.out.println("Could not place item at tray. Exiting.");
}
}
}
protected JPopupMenu buildSystemTrayJPopupMenu () {
final JPopupMenu menu = new JPopupMenu ();
final JMenuItem showMenuItem = new JMenuItem("Show");
final JMenuItem hideMenuItem = new JMenuItem("Hide");
final JMenuItem exitMenuItem = new JMenuItem("Exit");
hideMenuItem.setEnabled(false);
ActionListener listener = new ActionListener () {
#Override
public void actionPerformed (ActionEvent ae) {
Object source = ae.getSource();
if (source == showMenuItem) {
System.out.println("Shown");
showMenuItem.setEnabled(false);
hideMenuItem.setEnabled(true);
}
else if (source == hideMenuItem) {
System.out.println("Hidden");
hideMenuItem.setEnabled(false);
showMenuItem.setEnabled(true);
}
else if (source == exitMenuItem) {
System.exit(0);
}
}
};
for (JMenuItem item : new JMenuItem [] {showMenuItem, hideMenuItem, exitMenuItem}) {
if (item == exitMenuItem) menu.addSeparator();
menu.add(item);
item.addActionListener(listener);
}
return menu;
}
protected Image getIcon () throws IOException {
// Build the 16x16 image programmatically, start with BMP Header
byte [] iconData = new byte[822];
System.arraycopy(new byte [] {0x42,0x4d,0x36,0x03, 0,0,0,0, 0,0,0x36,0,
0,0,0x28,0, 0,0,16,0, 0,0,16,0, 0,0,16,0, 24,0,0,0, 0,0,0,3},
0, iconData, 0, 36);
for (int i = 36; i < 822; iconData[i++] = 0);
for (int i = 56; i < 822; i += 3) iconData[i] = -1;
return ImageIO.read(new java.io.ByteArrayInputStream(iconData));
}
}
I found a hack that I feel will work just nicely. I have yet to test it in Windows XP, but it works in Windows 7. This involves adding a "hidden dialog" that displays behind the popup menu, as if the popup menu originated from the hidden dialog in the first place. The only real trick is getting the hidden dialog to stay behind the popup menu. At least in Windows 7, it displays behind the system tray, so you never really see it in the first place. A WindowFocusListener can be added to this hidden dialog, and so when you click out of the popup menu, you are also clicking out of the hidden dialog. I have added this capability to the SSCCE that I posted previously to illustrate how adding this works:
package org.test;
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;
public class SwingSystemTray {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run () {
try {
/* We are going for the Windows Look and Feel here */
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
new SwingSystemTray ();
} catch (Exception e) {
System.out.println("Not using the System UI defeats the purpose...");
e.printStackTrace();
}
}
});
}
protected SystemTray systemTray;
protected TrayIcon trayIcon;
protected JPopupMenu systemTrayPopupMenu;
protected Image iconImage;
/* Added a "hidden dialog" */
protected JDialog hiddenDialog;
public SwingSystemTray () throws IOException {
iconImage = getIcon ();
if (SystemTray.isSupported()) {
systemTray = SystemTray.getSystemTray();
systemTrayPopupMenu = buildSystemTrayJPopupMenu();
trayIcon = new TrayIcon(iconImage, "Application Name", null /* Popup Menu */);
trayIcon.addMouseListener (new MouseAdapter () {
#Override
public void mouseReleased (MouseEvent me) {
if (me.isPopupTrigger()) {
systemTrayPopupMenu.setLocation(me.getX(), me.getY());
/* Place the hidden dialog at the same location */
hiddenDialog.setLocation(me.getX(), me.getY());
/* Now the popup menu's invoker is the hidden dialog */
systemTrayPopupMenu.setInvoker(hiddenDialog);
hiddenDialog.setVisible(true);
systemTrayPopupMenu.setVisible(true);
}
}
});
trayIcon.addActionListener(new ActionListener() {
#Override
public void actionPerformed (ActionEvent ae) {
System.out.println("actionPerformed");
}
});
try {
systemTray.add(trayIcon);
} catch (AWTException e) {
System.out.println("Could not place item at tray. Exiting.");
}
}
/* Initialize the hidden dialog as a headless, titleless dialog window */
hiddenDialog = new JDialog ();
hiddenDialog.setSize(10, 10);
/* Add the window focus listener to the hidden dialog */
hiddenDialog.addWindowFocusListener(new WindowFocusListener () {
#Override
public void windowLostFocus (WindowEvent we ) {
hiddenDialog.setVisible(false);
}
#Override
public void windowGainedFocus (WindowEvent we) {}
});
}
protected JPopupMenu buildSystemTrayJPopupMenu () {
final JPopupMenu menu = new JPopupMenu ();
final JMenuItem showMenuItem = new JMenuItem("Show");
final JMenuItem hideMenuItem = new JMenuItem("Hide");
final JMenuItem exitMenuItem = new JMenuItem("Exit");
hideMenuItem.setEnabled(false);
ActionListener listener = new ActionListener () {
#Override
public void actionPerformed (ActionEvent ae) {
/* We want to make sure the hidden dialog goes away after selection */
hiddenDialog.setVisible(false);
Object source = ae.getSource();
if (source == showMenuItem) {
System.out.println("Shown");
showMenuItem.setEnabled(false);
hideMenuItem.setEnabled(true);
}
else if (source == hideMenuItem) {
System.out.println("Hidden");
hideMenuItem.setEnabled(false);
showMenuItem.setEnabled(true);
}
else if (source == exitMenuItem) {
System.exit(0);
}
}
};
for (JMenuItem item : new JMenuItem [] {showMenuItem, hideMenuItem, exitMenuItem}) {
if (item == exitMenuItem) menu.addSeparator();
menu.add(item);
item.addActionListener(listener);
}
return menu;
}
protected Image getIcon () throws IOException {
// Build the 16x16 image programmatically, start with BMP Header
byte [] iconData = new byte[822];
System.arraycopy(new byte [] {0x42,0x4d,0x36,0x03, 0,0,0,0, 0,0,0x36,0,
0,0,0x28,0, 0,0,16,0, 0,0,16,0, 0,0,16,0, 24,0,0,0, 0,0,0,3},
0, iconData, 0, 36);
for (int i = 36; i < 822; iconData[i++] = 0);
for (int i = 56; i < 822; i += 3) iconData[i] = -1;
return ImageIO.read(new java.io.ByteArrayInputStream(iconData));
}
}
This solution gives me requirement #2 that I was looking for, which is to make the JPopupMenu disappear when it loses focus on a system tray using the Windows system look and feel.
Note: I have not gotten the JPopupMenu feature to work on the system tray in CentOS/RedHat Linux. For those, I will have to just use a normal AWT PopupMenu.
A JPopupMenu can't be displayed by itself. That is it needs to be added to a window. Try to use a WindowListener and then hide the popup on a windowDeactivated() event. After the popup is visible you should be able to get the window by using:
Window window = SwingUtilities.windowForComonent(systemTrayPopupMenu);
I just used a MouseListener on the JPopup menu which invokes a timer Thread upon mouse exit; if the mouse re-enters, I reset the "mouseStillOnMenu" flag. Set the "Thread.sleep() value to however long you want the user to be able leave the menu - if you click on a a menu item normally, the default menu close behavior is invoked and closes the menu.
#Override
public void mouseEntered(MouseEvent arg0) {
mouseStillOnMenu = true;
}
#Override
public void mouseExited(MouseEvent arg0) {
mouseStillOnMenu = false;
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000); //waits one second before checking if mouse is still on the menu
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (!isMouseStillOnMenu()) {
jpopup.setVisible(false);
}
}
}).start();
}
Im creating a very simple tray menu with the following code:
final Frame frame = new Frame("");
frame.setUndecorated(true);
// Check the SystemTray is supported
if (!SystemTray.isSupported()) {
System.out.println("SystemTray is not supported");
return;
}
final TrayIcon trayIcon = new TrayIcon(Toolkit.getDefaultToolkit().getImage(
new URL("http://url.com/trayIcon.png")), "Library Drop");
final SystemTray tray = SystemTray.getSystemTray();
// Create a pop-up menu components
final PopupMenu popup = createPopupMenu();
trayIcon.setPopupMenu(popup);
trayIcon.addMouseListener(new MouseAdapter() {
//#Override
public void mouseClicked(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON1) {
frame.add(popup);
popup.show(frame, e.getXOnScreen(), e.getYOnScreen());
}
}
});
try {
frame.setResizable(false);
frame.setVisible(true);
tray.add(trayIcon);
} catch (AWTException e) {
System.out.println("TrayIcon could not be added.");
}
} catch (MalformedURLException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
protected static PopupMenu createPopupMenu() {
final PopupMenu popup = new PopupMenu();
MenuItem aboutItem = new MenuItem("Accept");
MenuItem aboutItem1 = new MenuItem("Dont accept");
MenuItem aboutItem2 = new MenuItem("Quit");
// Add components to pop-up menu
popup.add(aboutItem);
popup.add(aboutItem1);
popup.addSeparator();
popup.add(aboutItem2);
return popup;
}
How can i listen and check when a user selects "Accept", "Dont accept", etc?
Also for some reason the height is maximum on the trayIcon, how can i tell the tray icon to be exactly X by Y pixles?
Edit: height/width issue is only in Mac, works fine on Windows
Simply use addActionListener on your MenuItems.
MenuItem aboutItem = new MenuItem("Accept");
aboutItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
System.out.println("Accept clicked!");
}
});
Also, if you happen to be using Java 8 or later, it becomes even simpler:
MenuItem aboutItem = new MenuItem("Accept");
aboutItem.addActionListener(evt -> System.out.println("Accept clicked!"));
I have read and understood how the Robot class in java works. Only thing I would like to ask, is how do I press and release the mouse button inside an if statement. For example I would to make a click only if (and right after) the space button is pressed/released. I would use the code:
try {
Robot robot = new Robot();
if (/*insert my statement here*/) {
try {
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.mouseRelease(InputEvent.BUTTON1_MASK);
} catch (InterruptedException ex) {}
}
} catch (AWTException e) {}
Unfortunately, there isn't a way to directly control hardware (well, in fact there is, but you would have to use JNI/JNA), this means that you can't simply check if a key is pressed.
You can use KeyBindings to bind the space key to an action, when the spacebar is pressed you set a flag to true, when it's released you set that flag to false. In order to use this solution, your application has to be a GUI application, this won't work with console applications.
Action pressedAction = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
spaceBarPressed = true;
}
};
Action releasedAction = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
spaceBarPressed = false;
}
};
oneOfYourComponents.getInputMap().put(KeyStroke.getKeyStroke("SPACE"), "pressed");
oneOfYourComponents.getInputMap().put(KeyStroke.getKeyStroke("released SPACE"), "released");
oneOfYourComponents.getActionMap().put("pressed", pressedAction);
oneOfYourComponents.getActionMap().put("released", releasedAction);
Then, use
try {
Robot robot = new Robot();
if (spaceBarPressed) {
try {
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.mouseRelease(InputEvent.BUTTON1_MASK);
} catch (InterruptedException ex) {
//handle the exception here
}
}
} catch (AWTException e) {
//handle the exception here
}
As GGrec wrote, a better way to do it would be to execute your mouse press directly when the keyboard event is fired:
Action pressedAction = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
try {
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.mouseRelease(InputEvent.BUTTON1_MASK);
} catch (InterruptedException ex) {
//handle the exception here
}
}
};
My suggestion is that you listen for the keyboard event, and when you receive it, you execute your code without the if statement. Add the listener to your canvas, or whatever.
Careful not to recreate the Robot class each time.
new KeyAdapter() {
#Override
public void keyReleased(final KeyEvent e) {
if (e.keyCode == KeyEvent.VK_SPACE)
try {
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.mouseRelease(InputEvent.BUTTON1_MASK);
} catch (InterruptedException ex) {
}
}
}
Is it possible to listen to events from browser with Java?
The main task is to add command "copy to file" to pop-up menu of right click of the mouse. This command must add selected text in browser, in Notepad, in winword (any selectable text) to specific text file.
I've just tried code which adds icon to tray but I do not know whether it can it be developed for solving my task.
import java.awt.*;
import java.awt.event.*;
public class SystemTrayTest
{
public SystemTrayTest()
{
final TrayIcon trayIcon;
if (SystemTray.isSupported()) {
SystemTray tray = SystemTray.getSystemTray();
Image image = Toolkit.getDefaultToolkit().getImage("tray.gif");
MouseListener mouseListener = new MouseListener() {
public void mouseClicked(MouseEvent e) {
System.out.println("Tray Icon - Mouse clicked!");
}
public void mouseEntered(MouseEvent e) {
System.out.println("Tray Icon - Mouse entered!");
}
public void mouseExited(MouseEvent e) {
System.out.println("Tray Icon - Mouse exited!");
}
public void mousePressed(MouseEvent e) {
System.out.println("Tray Icon - Mouse pressed!");
}
public void mouseReleased(MouseEvent e) {
System.out.println("Tray Icon - Mouse released!");
}
};
ActionListener exitListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("Exiting...");
System.exit(0);
}
};
PopupMenu popup = new PopupMenu();
MenuItem defaultItem = new MenuItem("Exit");
defaultItem.addActionListener(exitListener);
popup.add(defaultItem);
trayIcon = new TrayIcon(image, "Tray Demo", popup);
ActionListener actionListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
trayIcon.displayMessage("Action Event",
"An Action Event Has Been Peformed!",
TrayIcon.MessageType.INFO);
}
};
trayIcon.setImageAutoSize(true);
trayIcon.addActionListener(actionListener);
trayIcon.addMouseListener(mouseListener);
// Depending on which Mustang build you have, you may need to uncomment
// out the following code to check for an AWTException when you add
// an image to the system tray.
// try {
tray.add(trayIcon);
// } catch (AWTException e) {
// System.err.println("TrayIcon could not be added.");
// }
} else {
System.err.println("System tray is currently not supported.");
}
}
/**
* #param args the command line arguments
*/
public static void main(String[] args)
{
SystemTrayTest main = new SystemTrayTest();
}
}
You are talking about accessing clipboard events. this may helps you. How do we get notified about system clipboard events?