ModernDocking.util.TextIcon Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of modern-docking-api Show documentation
Show all versions of modern-docking-api Show documentation
Modern docking library for Java Swing
package ModernDocking.util;
import javax.swing.*;
import java.awt.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Map;
/**
* The TextIcon will paint a String of text as an Icon. The Icon
* can be used by any Swing component that supports icons.
* TextIcon supports two different layout styles:
*
* - Horizontally - does normal rendering of the text by using the
* Graphics.drawString(...) method
*
- Vertically - Each character is displayed on a separate line
*
*
* TextIcon was designed to be rendered on a specific JComponent as it
* requires FontMetrics information in order to calculate its size and to do
* the rendering. Therefore, it should only be added to component it was
* created for.
* By default, the text will be rendered using the Font and foreground color
* of its associated component. However, this class does allow you to override
* these properties. Also starting in JDK6 the desktop renderering hints will
* be used to renderer the text. For versions not supporting the rendering
* hints antialiasing will be turned on.
*/
public class TextIcon implements Icon, PropertyChangeListener
{
/**
* Layout of text icon
*/
public enum Layout
{
/**
* Text is horizontal in the icon
*/
HORIZONTAL,
/**
* Text is vertical in the icon
*/
VERTICAL
}
private final JComponent component;
private final Layout layout;
private String text;
private Font font;
private Color foreground;
private int padding;
// Used for the implementation of Icon interface
private int iconWidth;
private int iconHeight;
// Used for Layout.VERTICAL to save reparsing the text every time the
// icon is repainted
private String[] strings;
private int[] stringWidths;
/**
* Convenience constructor to create a TextIcon with a HORIZONTAL layout.
*
* @param component the component to which the icon will be added
* @param text the text to be rendered on the Icon
*/
public TextIcon(JComponent component, String text)
{
this(component, text, Layout.HORIZONTAL);
}
/**
* Create a TextIcon specifying all the properties.
*
* @param component the component to which the icon will be added
* @param text the text to be rendered on the Icon
* @param layout specify the layout of the text. Must be one of
* the Layout enums: HORIZONTAL or VERTICAL
*/
public TextIcon(JComponent component, String text, Layout layout)
{
this.component = component;
this.layout = layout;
setText( text );
component.addPropertyChangeListener("font", this);
}
/**
* Get the Layout enum
*
* @return the Layout enum
*/
public Layout getLayout()
{
return layout;
}
/**
* Get the text String that will be rendered on the Icon
*
* @return the text of the Icon
*/
public String getText()
{
return text;
}
/**
* Set the text to be rendered on the Icon
*
* @param text the text to be rendered on the Icon
*/
public void setText(String text)
{
this.text = text;
calculateIconDimensions();
}
/**
* Get the Font used to render the text. This will default to the Font
* of the component unless the Font has been overridden by using the
* setFont() method.
*
* @return the Font used to render the text
*/
public Font getFont()
{
if (font == null) {
return component.getFont();
}
else {
return font;
}
}
/**
* Set the Font to be used for rendering the text
*
* @param font the Font to be used for rendering the text
*/
public void setFont(Font font)
{
this.font = font;
calculateIconDimensions();
}
/**
* Get the foreground Color used to render the text. This will default to
* the foreground Color of the component unless the foreground Color has
* been overridden by using the setForeground() method.
*
* @return the Color used to render the text
*/
public Color getForeground()
{
if (foreground == null) {
return component.getForeground();
}
else {
return foreground;
}
}
/**
* Set the foreground Color to be used for rendering the text
*
* @param foreground the foreground Color to be used for rendering the text
*/
public void setForeground(Color foreground)
{
this.foreground = foreground;
component.repaint();
}
/**
* Get the padding used when rendering the text
*
* @return the padding specified in pixels
*/
public int getPadding()
{
return padding;
}
/**
* By default, the size of the Icon is based on the size of the rendered
* text. You can specify some padding to be added to the start and end
* of the text when it is rendered.
*
* @param padding the padding amount in pixels
*/
public void setPadding(int padding)
{
this.padding = padding;
calculateIconDimensions();
}
/**
* Calculate the size of the Icon using the FontMetrics of the Font.
*/
private void calculateIconDimensions()
{
Font font = getFont();
FontMetrics fm = component.getFontMetrics( font );
if (layout == Layout.HORIZONTAL)
{
iconWidth = fm.stringWidth( text ) + (padding * 2);
iconHeight = fm.getHeight();
}
else if (layout == Layout.VERTICAL)
{
int maxWidth = 0;
strings = new String[text.length()];
stringWidths = new int[text.length()];
// Find the widest character in the text string
for (int i = 0; i < text.length(); i++)
{
strings[i] = text.substring(i, i + 1);
stringWidths[i] = fm.stringWidth( strings[i] );
maxWidth = Math.max(maxWidth, stringWidths[i]);
}
// Add a minimum of 2 extra pixels, plus the leading value,
// on each side of the character.
iconWidth = maxWidth + ((fm.getLeading() + 2) * 2);
// Decrease then normal gap betweens lines of text by taking into
// account the descent.
iconHeight = (fm.getHeight() - fm.getDescent()) * text.length();
iconHeight += padding * 2;
}
component.revalidate();
}
//
// Implement the Icon Interface
//
/**
* Gets the width of this icon.
*
* @return the width of the icon in pixels.
*/
@Override
public int getIconWidth()
{
return iconWidth;
}
/**
* Gets the height of this icon.
*
* @return the height of the icon in pixels.
*/
@Override
public int getIconHeight()
{
return iconHeight;
}
/**
* Paint the icons of this compound icon at the specified location
*
* @param c The component to which the icon is added
* @param g the graphics context
* @param x the X coordinate of the icon's top-left corner
* @param y the Y coordinate of the icon's top-left corner
*/
@Override
public void paintIcon(Component c, Graphics g, int x, int y)
{
Graphics2D g2 = (Graphics2D)g.create();
// The "desktophints" is supported in JDK6
Toolkit toolkit = Toolkit.getDefaultToolkit();
Map map = (Map)(toolkit.getDesktopProperty("awt.font.desktophints"));
if (map != null) {
g2.addRenderingHints(map);
}
else {
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
}
g2.setFont( getFont() );
g2.setColor( getForeground() );
FontMetrics fm = g2.getFontMetrics();
if (layout == Layout.HORIZONTAL)
{
g2.translate(x, y + fm.getAscent());
g2.drawString(text, padding, 0);
}
else if (layout == Layout.VERTICAL)
{
int offsetY = fm.getAscent() - fm.getDescent() + padding;
int incrementY = fm.getHeight() - fm.getDescent();
for (int i = 0; i < text.length(); i++)
{
int offsetX = Math.round((getIconWidth() - stringWidths[i]) / 2.0f);
g2.drawString(strings[i], x + offsetX, y + offsetY);
offsetY += incrementY;
}
}
g2.dispose();
}
//
// Implement the PropertyChangeListener interface
//
public void propertyChange(PropertyChangeEvent e)
{
// Handle font change when using the default font
if (font == null) {
calculateIconDimensions();
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy