I would like to show some numbers on my tray icon indicating a number of events that happened to the user like what is done in this facebook notifications icons:
Do you think that it is possible ?
Thank you
You can do this using the TaskBar and TaskItem classes although it may not work on all platforms.
TaskBar taskBar = Display.getDefault().getSystemTaskBar();
// TODO may return null if not supported on the platform
// Get application item
TaskItem taskItem = taskBar.getItem(null);
if (taskItem != null)
taskItem.setOverlayText("your text");
Also try:
TaskItem taskItem = taskBar.getItem(shell);
where shell is your main application shell. The TaskItem JavaDoc suggests trying both methods of getting the TaskItem:
For better cross platform support, the application code should first
try to set this feature on the TaskItem for the main shell then on the
TaskItem for the application.
Related
I am using Winium + Java for automation testing of Windows application, and trying to access tool bar menu.
When I tried to detect elements using UI Automation Verify, I couldn't see child elements under tool bar element like below screenshot.
enter image description here
But my tool bar definitely has sub menu items like screenshot and I need to access them.
enter image description here
I tried below java code, but it didn't work
WebElement el = driver.findElement(By.id('59398'));
el.click();
WebElement child = el.findElement(By.name('Start'));
child.click();
when I tried
driver.findElement(By.name"Start').click();
it clicked my windows start menu, not my application's menu.
Is there any way to access items under this tool bar?
You can try use another UI Inspector
eg. UI SPY or Inspector.exe
Probably your ID is not a AutomationID (process id?)
You should find a main window (parent of your app) (Example for calc) and get a parameter like AutomationId, ClassName or Name
I see this is MFC application, and this is an app side MFC library problem. If you hover mouse over toolbar button using Inspect.exe, the info is available but you can't reach this button from the hierarchy (the buttons have no parent somehow). Possible workaround involves combined Win32 API and UI Automation approach:
get button rectangle using Win32 API (but there is no text).
use ElementFromPoint method of UI Automation API and get actual texts to choose the right button.
P.S. My suggestion is applicable for Java + Winium in theory. But I can't estimate the complexity because I'm not a Java expert. So below is Python solution.
We have plans to implemented this mixed way in pywinauto. See issue #413. It contains Python code sample how to do that. We've had no chance to integrate it yet.
from ctypes.wintypes import tagPOINT
import pywinauto
app = pywinauto.Application().start(r'.\apps\MFC_samples\RebarTest.exe')
menu_bar = app.RebarTest.MenuBar.wrapper_object()
point = menu_bar.button(0).rectangle().mid_point()
point = menu_bar.client_to_screen(point)
elem = pywinauto.uia_defines.IUIA().iuia.ElementFromPoint(tagPOINT(point[0], point[1]))
element = pywinauto.uia_element_info.UIAElementInfo(elem)
print(element.name)
Code:
public byte[] getThumbnail(byte[] imageBytes) throws Exception {
ByteArrayInputStream inputStream = new ByteArrayInputStream(imageBytes);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
Thumbnails.of(inputStream).size(50, 50).keepAspectRatio(true)
.outputFormat("jpg").toOutputStream(outputStream);
byte[] picture = outputStream.toByteArray();
return picture;
}
I am trying to generate a thumbnail from an image in the above code.
When I call the above function, it launches a Java icon, which is shown in my attached screenshot. If I try to close this icon, my application gets closed.
The dock icon appears, because some of the imaging code you use, use awt under the hoods. This triggers the dock icon to appear on OS X. It's possible to suppress the icon, though.
The cross platform way of doing it, is running you application in "headless" mode, that is, with no user interaction using mouse, keyboard or screen feedback (ie. windows). You can specify headless mode at startup, using the system property java.awt.headless on the command line like this:
java -Djava.awt.headless=true
Alternatively, in code like this:
System.setProperty("java.awt.headless", "true");
For OS X (and an Apple JRE) you can alternatively use the system property apple.awt.UIElement, it will suppress the dock icon only, but otherwise let your app use windows etc.:
java -Dapple.awt.UIElement=true
From the documentation:
Suppresses the normal application Dock icon and menu bar from appearing. Only appropriate for background applications which show a tray icon or other alternate user interface for accessing the apps windows. Unlike java.awt.headless=true, this does not suppress windows and dialogs from actually appearing on screen.
The default value is false.
I've got a Java swing program that runs in full screen mode. It's effectively a kiosk program in that I want it to lock out everything else while it's running. This is running on a Windows 8.1 tablet, so of course the tablet is touchscreen, and therefore if you do an "edge swipe" (drag your finger from the right) the charms bar pops up and you can get to the Start screen from there. Is there some way to disable this from happening in Java? (Or is there some third-party solution not involving Java that can work in tandem to achieve the same result?)
You can disable edge gestures while your app is active and full screen by setting the System.EdgeGesture.DisableTouchWhenFullScreen property on the window.
I don't know if Java provides a direct way to set this (probably not), but you should be able to set this from a JNI.
Here's a C++ snippet from the DisableTouchWhenFullScreen docs:
HRESULT SetTouchDisableProperty(HWND hwnd, BOOL fDisableTouch)
{
IPropertyStore* pPropStore;
HRESULT hrReturnValue = SHGetPropertyStoreForWindow(hwnd, IID_PPV_ARGS(&pPropStore));
if (SUCCEEDED(hrReturnValue))
{
PROPVARIANT var;
var.vt = VT_BOOL;
var.boolVal = fDisableTouch ? VARIANT_TRUE : VARIANT_FALSE;
hrReturnValue = pPropStore->SetValue(PKEY_EdgeGesture_DisableTouchWhenFullscreen, var);
pPropStore->Release();
}
return hrReturnValue;
}
What I ended up doing was to write a batch script that kills explorer.exe and then re-spawns it after the app exits, based on this answer on Super User.
I'm trying to develop a Mac OsX app provided by a system tray icon, so after the first attempt with the simplest code to achieve it I noticed that every apps tray icon's (both system and user apps) on mac osX (10.8) allows to activate the relative popup menu with both left and right click on it but with my project only the left (MouseEvent.BOTTON1) button causes the popup menu to pulldown. Here's my code:
public class SystemTrayDemo
{
private SystemTray tray;
private TrayIcon tray_icon;
public SystemTrayDemo()
{
if (!SystemTray.isSupported())
{
JOptionPane.showMessageDialog(null, "System tray not supported!");
return;
}
else
tray = SystemTray.getSystemTray();
final PopupMenu popup = new PopupMenu();
MenuItem exit = new MenuItem("Exit");
exit.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
if (tray != null)
{
tray.remove(tray_icon);
System.exit(0);
}
}
});
popup.add(exit);
//add tray icon
tray_icon = new TrayIcon(getIcon("images/wifi.png"), "Open documents...", popup);
tray_icon.setImageAutoSize(true);
try
{
tray.add(tray_icon); // adds icon
}
catch (AWTException ex) {}
}
private Image getIcon(String name)
{
URL _url = getClass().getResource(name);
return new ImageIcon(_url).getImage();
}
public static void main(String args[])
{
new SystemTrayDemo();
}
}
but how I already said, only through left mouse button click.
So during a further attempt I've tried to mimic the behavior of the tray icons of every other apps using a MouseListener and firing a left button event on right click event using dispatchEvent() method like so:
public static void fireMouseEvent(Component c)
{
MouseEvent me = new MouseEvent(c, // which
MouseEvent.MOUSE_CLICKED, // what
System.currentTimeMillis(), // when
MouseEvent.BUTTON1_MASK, // no modifiers
0, 0, // where: at (10, 10}
1, // only 1 click
true); // popup trigger
c.dispatchEvent(me);
}
the event will handled by the mouse listener but obviously TrayIcon Class is not a Component subclass and therefore the source of MouseEvent is null and I get a NPE. Here's my MouseListener:
class MouseAdapt extends java.awt.event.MouseAdapter
{
public void mouseClicked(java.awt.event.MouseEvent me)
{
int button = me.getButton();
if(button == java.awt.event.MouseEvent.BUTTON3)
{
fireMouseEvent(me.getComponent());
}
}
}
try
{
tray.add(tray_icon); // aggiungi l'icona
tray_icon.addMouseListener(new MouseAdapt());
}
catch (AWTException ex) {}
Sorry for my english, I hope that someone who have ever had some experience with that kind of projects can help me. I've searched for hours but with no luck. Thank You for your help.
Edit: There's now a library working to fix all of this here: https://github.com/dorkbox/SystemTray
to activate the [TrayIcon] relative popup menu with both left and right click
This is simply not possible on Mac + Java currently. Using reflection to invoke the underlying triggers doesn't seem to help. This is a bug.
https://bugs.openjdk.java.net/browse/JDK-8041890
only the left (MouseEvent.BOTTON1) button causes the popup menu to pulldown. Here's my code
Even this is broken in some Java versions (7u79), fixed with an upgrade...
https://bugs.openjdk.java.net/browse/JDK-7158615
Cross-Platform TrayIcon Support:
Albeit slightly off-topic, I wanted to add, some projects use a JXTrayIcon to accomplish some fancy drop-down menus in Linux/Windows, etc. These also cause problems on Mac despite a click-bug it already suffers from today as well as bugs with Gnome3 requiring a completely separate hack. But on Mac, any attempt to use the decorated menus causes the menu to linger and is a very bad experience for the end-user. The solution I settled on was to use AWT for Mac, Swing for everything else. The Java TrayIcon support is in dire need of a rewrite. JavaFX claims to help this initiative, but it's staged for Java 9. In the mean time, I'm sticking to OS-dependent hacks.
Related Tray Issues for Other Platforms
Furthermore, some Linux distributions like Ubuntu have removed the tray icon by default in the Unity desktop, causing further headaches. https://askubuntu.com/a/457212/412004
In addition, the transparency of the icon is replaced with a gray color on Gtk/Gnome or Qt/KDE powered desktops (Both OpenJDK and Oracle JRE suffer this)
https://stackoverflow.com/a/3882028/3196753
http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6453521
In addition, Gnome3 powered desktops may show it in the wrong corner, not at all, or it may show but be unclickable (Both OpenJDK and Oracle JRE suffer this)
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=660157
https://bugzilla.redhat.com/show_bug.cgi?id=1014448
In addition to that, high-DPI screens on Windows have a bug that draws the icon incorrectly: Windows 8 Distorts my TrayIcon
So in summary, the state of the System Tray in Java is OK, but due to the combination of factors is quite fragmented and buggy in JDK6, JDK7 and JDK8.
How to/What is a good library, to create a fading indicator message in Java like that of Outlook when you get a message, or Ubuntu/Gnome when you've connected to a network?
Java 1.6 has a TrayIcon class that can be used to display notification messages.
SystemTray tray = SystemTray.getSystemTray();
Image image = Toolkit.getDefaultToolkit().getImage("tray.gif");
TrayIcon trayIcon = new TrayIcon(image, "Tray Demo");
tray.add(trayIcon);
trayIcon.displayMessage("Hello, World", "notification demo", MessageType.INFO);
Here's the result:
On Linux you may also have a little program called notify-send. It makes it easy to invokes the standard freedesktop.org notification system from the shell. You can also run it from Java.
String[] notifyCmd = {"notify-send", "Hello, World!"};
Runtime.getRuntime().exec(notifyCmd);
I had to apt-get install libnotify-bin to get this on my Ubuntu box.
I've tested these things on Windows 7 and Ubuntu 9.10. In each case the notification disappeared after some time which is I suppose the fading indicator effect that you want.
I would use Trident animation library. Your task would be almost trivial if you use it.
Also you could take a look at Timing Framework, but it wasn't updated for a long time.