package org.limewire.ui.swing.util; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Rectangle; import java.awt.font.FontRenderContext; import java.awt.font.TextAttribute; import java.awt.geom.Rectangle2D; import java.util.HashMap; import java.util.Map; import javax.swing.Action; import javax.swing.Icon; import javax.swing.JComponent; import javax.swing.text.html.StyleSheet; public class FontUtils { private FontUtils() {} public static void changeSize(JComponent component, float increment) { Font font = component.getFont(); if (font == null) return; float newSize = font.getSize() + increment; component.setFont(font.deriveFont(newSize)); } public static void setSize(JComponent component, int size) { Font font = component.getFont(); if(font == null) return; component.setFont(font.deriveFont((float)size)); } public static void changeStyle(JComponent component, int style) { component.setFont(component.getFont().deriveFont(style)); } public static void bold(JComponent component) { changeStyle(component, Font.BOLD); } public static void plain(JComponent component) { changeStyle(component, Font.PLAIN); } public static void underline(JComponent component) { Font font = component.getFont(); if(font != null) { component.setFont(deriveUnderline(font, true)); } } public static boolean isUnderlined(JComponent component) { Font font = component.getFont(); if(font != null) { Map<TextAttribute, ?> map = font.getAttributes(); return map.get(TextAttribute.UNDERLINE) == TextAttribute.UNDERLINE_ON; } else { return false; } } public static void removeUnderline(JComponent component) { Font font = component.getFont(); if (font != null) { component.setFont(deriveUnderline(font, false)); } } public static Font deriveUnderline(Font font, boolean underlined) { Map<TextAttribute, ?> map = font.getAttributes(); Map<TextAttribute, Object> newMap = new HashMap<TextAttribute, Object>(map); newMap.put(TextAttribute.UNDERLINE, underlined ? TextAttribute.UNDERLINE_ON : Integer.valueOf(-1)); return font.deriveFont(newMap); } /** * Determines if a font can display up to a point in the string. * <p> * Returns -1 if it can display the whole string. */ public static boolean canDisplay(Font f, String s) { int upTo = f.canDisplayUpTo(s); if(upTo >= s.length() || upTo == -1) return true; else return false; } private static String unpackText(Object object) { if (object == null) { return null; } if (object instanceof Action) return (String) ((Action) object).getValue(Action.NAME); else return object.toString(); } public static Rectangle2D getLongestTextArea(Font font, Object... objects) { FontRenderContext frc = new FontRenderContext(null, false, false); Rectangle2D largestRect = new Rectangle(); for (int i = 0; i < objects.length; i++) { Object obj = objects[i]; Rectangle2D currentRect = font.getStringBounds(unpackText(obj), frc); if(obj instanceof Action) { Icon icon = (Icon)((Action)obj).getValue(Action.SMALL_ICON); if(icon != null) { // add some whitespace around the icons. currentRect.setRect(currentRect.getX(), currentRect.getY(), currentRect.getWidth()+icon.getIconWidth() + 10, currentRect.getHeight()); } } if (currentRect.getWidth() > largestRect.getWidth()) { largestRect = currentRect; } } return largestRect; } /** * Truncates the given message to a maxWidth in pixels. */ public static String getTruncatedMessage(String message, Font font, int maxWidth) { String ELIPSES = "..."; while (getPixelWidth(message, font) > (maxWidth)) { message = message.substring(0, message.length() - (ELIPSES.length() + 1)) + ELIPSES; } return message; } /** * Returns the width of the message in the given font. */ public static int getPixelWidth(String text, Font font) { StyleSheet css = new StyleSheet(); FontMetrics fontMetrics = css.getFontMetrics(font); return fontMetrics.stringWidth(text); } }