Fixed issue with icon scaling in popup menu
This commit is contained in:
parent
3d22f97026
commit
a2a1c092cb
|
@ -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,15 +115,69 @@ class SwingMenuEntry implements MenuEntry {
|
|||
@Override
|
||||
public
|
||||
void run() {
|
||||
setImageIcon(imagePath);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private
|
||||
void setImageIcon(final String imagePath) {
|
||||
if (imagePath != null && !imagePath.isEmpty()) {
|
||||
menuItem.setIcon(new ImageIcon(imagePath));
|
||||
|
||||
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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user