1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
|
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) {
init(label);
}
public MultiLineLabel(String label, int minimumWidth) {
init(label);
min_width = minimumWidth;
}
private void init(String text) {
StringTokenizer t = new StringTokenizer(text, "\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();
}
// Figures out how wide each line of the label
// is, and how wide the widest line is.
protected void measure() {
Font font = getFont();
FontMetrics fm = font!=null?getFontMetrics(font):null;
// 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 setText(String text) {
init(text);
measure();
repaint();
}
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);
}
}
|