package ij.gui;
import java.awt.*;
import java.util.*;
/**Custom component for displaying multiple lines. Based on
MultiLineLabel class from "Java in a Nutshell" by David Flanagan.*/
public class MultiLineLabel extends Canvas {
String[] lines;
int num_lines;
int margin_width = 6;
int margin_height = 6;
int line_height;
int line_ascent;
int[] line_widths;
int min_width, max_width;
// Breaks the specified label up into an array of lines.
public MultiLineLabel(String label) {
this(label, 0);
}
public MultiLineLabel(String label, int minimumWidth) {
StringTokenizer t = new StringTokenizer(label, "\n");
num_lines = t.countTokens();
lines = new String[num_lines];
line_widths = new int[num_lines];
for(int i = 0; i < num_lines; i++) lines[i] = t.nextToken();
min_width = minimumWidth;
}
// Figures out how wide each line of the label
// is, and how wide the widest line is.
protected void measure() {
FontMetrics fm = this.getFontMetrics(this.getFont());
// If we don't have font metrics yet, just return.
if (fm == null) return;
line_height = fm.getHeight();
line_ascent = fm.getAscent();
max_width = 0;
for(int i = 0; i < num_lines; i++) {
line_widths[i] = fm.stringWidth(lines[i]);
if (line_widths[i] > max_width) max_width = line_widths[i];
}
}
public void setFont(Font f) {
super.setFont(f);
measure();
repaint();
}
// This method is invoked after our Canvas is first created
// but before it can actually be displayed. After we've
// invoked our superclass's addNotify() method, we have font
// metrics and can successfully call measure() to figure out
// how big the label is.
public void addNotify() {
super.addNotify();
measure();
}
// Called by a layout manager when it wants to
// know how big we'd like to be.
public Dimension getPreferredSize() {
return new Dimension(Math.max(min_width, max_width + 2*margin_width),
num_lines * line_height + 2*margin_height);
}
// Called when the layout manager wants to know
// the bare minimum amount of space we need to get by.
public Dimension getMinimumSize() {
return new Dimension(Math.max(min_width, max_width), num_lines * line_height);
}
// Draws the label
public void paint(Graphics g) {
int x, y;
Dimension d = this.getSize();
if (!ij.IJ.isLinux()) setAntialiasedText(g);
y = line_ascent + (d.height - num_lines * line_height)/2;
for(int i = 0; i < num_lines; i++, y += line_height) {
x = margin_width;
g.drawString(lines[i], x, y);
}
}
void setAntialiasedText(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
}
}