Fixed issue with icon scaling in popup menu

This commit is contained in:
nathan 2016-02-21 00:56:30 +01:00
parent 3d22f97026
commit a2a1c092cb

View File

@ -20,16 +20,28 @@ import dorkbox.systemTray.ImageUtil;
import dorkbox.systemTray.MenuEntry;
import dorkbox.systemTray.SystemTray;
import dorkbox.systemTray.SystemTrayMenuAction;
import dorkbox.util.FileUtil;
import dorkbox.util.SwingUtil;
import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JMenuItem;
import javax.swing.UIManager;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
class SwingMenuEntry implements MenuEntry {
private static final String tempDirPath = ImageUtil.TEMP_DIR.getAbsolutePath();
private final SwingSystemTrayMenuPopup parent;
private final SystemTray systemTray;
private final JMenuItem menuItem;
@ -38,6 +50,11 @@ class SwingMenuEntry implements MenuEntry {
private volatile String text;
private volatile SystemTrayMenuAction callback;
private int iconHeight = -1;
SwingMenuEntry(final SwingSystemTrayMenuPopup parentMenu, final String label, final String imagePath, final SystemTrayMenuAction callback,
final SystemTray systemTray) {
this.parent = parentMenu;
@ -58,7 +75,7 @@ class SwingMenuEntry implements MenuEntry {
menuItem.addActionListener(swingCallback);
if (imagePath != null && !imagePath.isEmpty()) {
menuItem.setIcon(new ImageIcon(imagePath));
setImageIcon(imagePath);
}
parentMenu.add(menuItem);
@ -98,16 +115,70 @@ class SwingMenuEntry implements MenuEntry {
@Override
public
void run() {
if (imagePath != null && !imagePath.isEmpty()) {
menuItem.setIcon(new ImageIcon(imagePath));
}
else {
menuItem.setIcon(null);
}
setImageIcon(imagePath);
}
});
}
private
void setImageIcon(final String imagePath) {
if (imagePath != null && !imagePath.isEmpty()) {
if (iconHeight != 0) {
// this will (and should) be the correct size for the system. On the systems tested, it was 16
// see: http://en-human-begin.blogspot.de/2007/11/javas-icons-by-default.html
Icon icon = UIManager.getIcon("FileView.fileIcon");
iconHeight = icon.getIconHeight();
}
ImageIcon origIcon = new ImageIcon(imagePath);
int origIconHeight = origIcon.getIconHeight();
int origIconWidth = origIcon.getIconWidth();
int savedIconHeight = this.iconHeight;
// it is necessary to resize this icon, so that it matches what our preferred size is for icons
if (origIconHeight != savedIconHeight && savedIconHeight != 0) {
//noinspection SuspiciousNameCombination
Dimension scaledDimension = getScaledDimension(origIconWidth, origIconHeight, savedIconHeight, savedIconHeight);
Image image = origIcon.getImage();
// scale it the smoothly
Image newImage = image.getScaledInstance(scaledDimension.width, scaledDimension.height, java.awt.Image.SCALE_SMOOTH);
origIcon = new ImageIcon(newImage);
// save it to temp spot on disk (so we don't have to KEEP on doing this). (but it MUST be the temp location, otherwise
// it's always 'on the fly')
if (imagePath.startsWith(tempDirPath)) {
// have to delete the old one
File file = new File(imagePath);
boolean delete = file.delete();
if (delete) {
// now write out the new one
String extension = FileUtil.getExtension(imagePath);
if (extension == null) {
extension = ".png"; // this is just made up
}
BufferedImage bufferedImage = getBufferedImage(image);
try {
ImageIO.write(bufferedImage, extension, file);
} catch (IOException e) {
// this shouldn't happen, but you never know...
e.printStackTrace();
}
}
}
}
menuItem.setIcon(origIcon);
}
else {
menuItem.setIcon(null);
}
}
@Override
public
void setImage(final String imagePath) {
@ -171,4 +242,48 @@ class SwingMenuEntry implements MenuEntry {
}
});
}
private static
Dimension getScaledDimension(int originalWidth, int originalHeight, int boundWidth, int boundHeight) {
//this function comes from http://stackoverflow.com/questions/10245220/java-image-resize-maintain-aspect-ratio
int newWidth = originalWidth;
int newHeight = originalHeight;
// first check if we need to scale width
if (originalWidth > boundWidth) {
//scale width to fit
newWidth = boundWidth;
//scale height to maintain aspect ratio
newHeight = (newWidth * originalHeight) / originalWidth;
}
// then check if we need to scale even with the new height
if (newHeight > boundHeight) {
//scale height to fit instead
newHeight = boundHeight;
//scale width to maintain aspect ratio
newWidth = (newHeight * originalWidth) / originalHeight;
}
return new Dimension(newWidth, newHeight);
}
private static
BufferedImage getBufferedImage(Image image) {
if (image instanceof BufferedImage) {
return (BufferedImage) image;
}
BufferedImage bimage = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB);
Graphics2D bGr = bimage.createGraphics();
bGr.drawImage(image, 0, 0, null);
bGr.dispose();
// Return the buffered image
return bimage;
}
}