Reputation: 15692
I want to give the user of my app the change to change font size on the fly... but what can I do about scaling up or down the JTree icons (i.e. node opened/node closed)?... typically I'm talking about standard (Metal) L&F... I'm not clear where these images are actually kept (I did a quick search on the java directory for .gif, .bmp, .png and .jpg to no avail).
If you have a gif of say 64 x 64 pixels, is there a Java way of scaling it up or down? Or do I have to have a set of icon files (gif or png or whatever) of different sizes? Does java make such a set of different sized identical icons (closed/open JTree folders) available... or does it only give you the choice of one size of icon?
Upvotes: 1
Views: 2421
Reputation: 44414
You can scale the default icons returned by UIManager.getIcon, and if the tree's cell renderer is a DefaultTreeCellRenderer, you can set the new icons there:
static Icon scale(Icon icon, double scaleFactor, JTree tree) {
int width = icon.getIconWidth();
int height = icon.getIconHeight();
width = (int) Math.ceil(width * scaleFactor);
height = (int) Math.ceil(height * scaleFactor);
BufferedImage image =
new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = image.createGraphics();
g.scale(scaleFactor, scaleFactor);
icon.paintIcon(tree, g, 0, 0);
g.dispose();
return new ImageIcon(image);
}
static void updateIcons(JTree tree) {
Font defaultFont = UIManager.getFont("Tree.font");
Font currentFont = tree.getFont();
double newScale = (double)
currentFont.getSize2D() / defaultFont.getSize2D();
DefaultTreeCellRenderer renderer =
(DefaultTreeCellRenderer) tree.getCellRenderer();
renderer.setOpenIcon(
scale(UIManager.getIcon("Tree.openIcon"), newScale, tree));
renderer.setClosedIcon(
scale(UIManager.getIcon("Tree.closedIcon"), newScale, tree));
renderer.setLeafIcon(
scale(UIManager.getIcon("Tree.leafIcon"), newScale, tree));
Collection<Integer> iconSizes = Arrays.asList(
renderer.getOpenIcon().getIconHeight(),
renderer.getClosedIcon().getIconHeight(),
renderer.getLeafIcon().getIconHeight());
// Convert points to pixels
Point2D p = new Point2D.Float(0, currentFont.getSize2D());
FontRenderContext context =
tree.getFontMetrics(currentFont).getFontRenderContext();
context.getTransform().transform(p, p);
int fontSizeInPixels = (int) Math.ceil(p.getY());
tree.setRowHeight(
Math.max(fontSizeInPixels, Collections.max(iconSizes) + 2));
}
Scaling the node handle icons may be more challenging. You can call the setCollapsedIcon and setExpandedIcon methods of BasicTreeUI, but it doesn't seem to account for the different handle size when placing the nodes and lines.
Upvotes: 2