System Tray icon looks distorted - java

I'm trying to have an icon be added and displayed to the system tray using Java. However the icon is always either too small, or its cut off in areas.
Its the second one from left in case you couldn't tell.
What am I doing wrong here? How can I get this icon to be displayed fully? What's the standard icon size to be used for system tray?
Edit: I am using AWT SystemTray and TrayIcon

After you've retrieved the actual image resource from disk, you can resize it to the size you need by creating a "fake" one on-the-fly and taking its width.
I found that this was better than using the setImageAutoSize(true) method, as that method does not scale the image smoothly at all.
BufferedImage trayIconImage = ImageIO.read(getClass().getResource("/path/to/icon.png"));
int trayIconWidth = new TrayIcon(trayIconImage).getSize().width;
TrayIcon trayIcon = new TrayIcon(trayIconImage.getScaledInstance(trayIconWidth, -1, Image.SCALE_SMOOTH));

To display the icon at an optimal size, you will need to manually resize it to the correct size. This correct size can differ between operating systems and preferences, so Java provides a method to acquire the task bar icon dimensions, which are 16x16 in the case of your example image.
if (SystemTray.isSupported()) {
SystemTray tray = SystemTray.getSystemTray();
Dimension trayIconSize = tray.getTrayIconSize();
// resize icon image to trayIconSize
// create your tray icon off of the resized image
}

According to TrayIcon.setImageAutoSize(boolean).
Sets the auto-size property. Auto-size determines whether the tray image is automatically sized to fit the space allocated for the image on the tray. By default, the auto-size property is set to false.
If auto-size is false, and the image size doesn't match the tray icon space, the image is painted as-is inside that space — if larger than the allocated space, it will be cropped.

I've ended up combining some of these answers to make the code I'm using.
This is producing a good looking icon in my system tray from a png that starts at 100x100.
It's worth noting that on a retina MacBook the icon looks worse scaled down. So I do a check elsewhere to see if it's running on a mac and don't apply this if it is.
public Image imageForTray(SystemTray theTray){
Image trayImage = Toolkit.getDefaultToolkit().getImage("my100x100icon.png");
Dimension trayIconSize = theTray.getTrayIconSize();
trayImage = trayImage.getScaledInstance(trayIconSize.width, trayIconSize.height, Image.SCALE_SMOOTH);
return trayImage;
}

Related

Java awt SystemTray - Popmenu too small on Surface 4 Pro

We've a Java application with a trayicon (SystemTray) and a popup menu (PopupMenu) that worked nicely on all platforms.
On a new Surface 4 Pro we've a problem as the size of the menu is amazingly small. Looks as not noticing it's a 'retina'/high definition display.
Is there an easy way to fix this ?
Looks like you may have to resort to setting the menu UI.
See : https://docs.oracle.com/javase/8/docs/api/javax/swing/JPopupMenu.html#setUI-javax.swing.plaf.PopupMenuUI-
Of course that means you need some way to determine that you're running on the Surface Pro in the first place.
You could try figuring out the current font size and dimensions used by the menu UI and compare that with the screen dimensions from Toolkit.getDefaultToolkit().getScreenSize()
As a general solution, which is not tied up to specific devices, you could detect screen resolution in dots-per-inch via:
java.awt.Toolkit.getDefaultToolkit().getScreenResolution()
This will return screen resolution in DPI (dots-per-inch). The bigger this value - the smaller the textual fonts will get for a specific font size.
Use the DPI to set an acceptable (or maximal) DPI settings and calculate the adjustment ratio.
You can adjust either by replacing the UI delegates fonts (for an application-wide effect)
OR, if the issue is specific for the system-tray, by deriving a larger font only for SystemTray's MenuItems:
java.awt.Font defaultFont = java.awt.Font.decode(null); // default font
float adjustmentRatio = 1.0f; // Calculate this based on your metrics
float newFontSize = defaultFont.getSize() * adjustmentRatio ;
java.awt.Font derivedFont = defaultFont.deriveFont(newFontSize);
// PopupMenu with the adjusted font size:
MenuItem item = new MenuItem("Menu Item");
item.setFont(derivedFont);
popupMenu.add(item);

how can i make high quality image icon in java swing?

I am working with a java swing application project. I want to make an image as icon in my JPanel but it seems to be low quality image when i am printing the image using the external printer. Here is the code
ImageIcon ii=new ImageIcon(scaleImage(90, 107, ImageIO.read(new File(f.getAbsolutePath()))));
image.setIcon(ii);
How can I make high quality image icon other than this method?
If you use a downscaled version of an image for an Icon, the resolution loss cannot be compensated when printing the icon.
Instead of using ImageIcon, you can create your own icon class (by implementing the javax.swing.Icon interface, it's actually quite simple), which keeps your Image at a higher resolution and paints it at a smaller size (but without quality loss, so you still can see more detail when printing it).
This can be done by applying an AffineTransform/Scale prior to drawing the Image, or by using graphics.drawImage(x,y,width,height,imageObserver).

Modifying taskbar icon of my .jar program

I'm trying to change the default java icon that appears in taskbar everytime I run my .jar program. I managed to change it with frame.setIconImage(img); but this makes icon way too small, I want it to be as big as other programs icons and have a high quality. Any way I can do that? Thanks.
As you only supplied a single icon, Windows will then scale that icon to whatever size it needs displaying it in the taskbar (could be 16x16, 32x32 or other sizes, depending on the desktop them and size of the taskbar.
If you want to have a "good looking" icon in the task bar you will need to provide a 32x32 pixel version of your icon.
Once you have that you can call setIconImages(List) instead of setIconImage() to define the icons that the operating system can use:
List<Image> icons = new ArrayList<Image>();
icons.add(getImage("someImage16x16.gif"));
icons.add(getImage("someImage32x32.gif"));
window.setIconImages(icons);
Where getImage() is some method returning the proper image icon. Essentially that would be the same steps you already used to define the current icon.
You can also supply a 64x64 and 24x24 icon using this method (just add more icons to the list).
Try looking at this example. It looks like you need to use frame.setIconImage(Toolkit.getDefaultToolkit().getImage("your_image.gif")); line

dynamic ImageIcon reduction for setFrameIcon

I have an ImageIcon that I used for a button to open this skillsFrame. This size of the image is 100x100px. As you can see in the screenshot if I just put the image it is too large(which is expected).
My question is about how to scale the image to 16x16(or whatever the default size is) so that I don't need to manually create a smaller sized version(for multiple reasons).
In case they make windows bigger in the future
Multiple operating system support
I'm sure I don't need to go on naming more...
skillsFrame = new JInternalFrame("Skills", true, true, false, false);
skillsFrame.setFrameIcon(new ImageIcon("images/gui/button_skills.png"));
And now for the image... the bar at the tops is the buttons to click to open the various JInternalFrames.
how to scale the image to 16x16(or whatever the default size is)
you have look at Image getScaledInstance(int width, int height, int hints)

How to change the size of JFrame icon

How to change the size of JFrame icon?
JFrame f = new JFrame("Test");
Image icon = Toolkit.getDefaultToolkit().getImage("icons/logo.png");
// icon.setPreferredWidth()...
f.setIconImage(icon);
Frame icons are set according to a size decided by the OS.
If you supply icons of various sizes, Windows will use the smaller one for the frame icon, and the larger one as the image to include in the window shown when the user types alt tab to change between apps.
OS X shows no frame icon at all.
See also: Sizes of frame icons used in Swing.
Top Level Containers came from Native OS, from current used theme, then not possible to increase numbers of available pixels,
some dirty hack are possible to wrote in case that you setSystemLookAndFeel, including caption, Font type&size or background, simple don't do that this way,
possible only by implements Custom Look and Feel especially some of Substance's themes can do that

Categories