1 | package vishnu.testvis.visual;
|
---|
2 |
|
---|
3 | import java.awt.*;
|
---|
4 | import java.util.*;
|
---|
5 |
|
---|
6 | /**
|
---|
7 | * A custom component that displays multiple lines of text with specified
|
---|
8 | * margins and alignment. In Java 1.1, we could extend Component instead
|
---|
9 | * of Canvas, making this a more efficient "Lightweight component"
|
---|
10 | * from Java Examples in a Nutshell,
|
---|
11 | * @author Flanagan, David - O'Rielly 1997 NY
|
---|
12 | */
|
---|
13 | public class MultiLineLabel extends Canvas {
|
---|
14 | // User-specified attributes
|
---|
15 | protected String label; // The label, not broken into lines
|
---|
16 | protected int margin_width; // Left and right margins
|
---|
17 | protected int margin_height; // Top and bottom margins
|
---|
18 | protected int alignment; // The alignment of the text.
|
---|
19 | public static final int LEFT = 0, CENTER = 1, RIGHT = 2; // alignment values
|
---|
20 | // Computed state values
|
---|
21 | protected int num_lines; // The number of lines
|
---|
22 | protected String[] lines; // The label, broken into lines
|
---|
23 | protected int[] line_widths; // How wide each line is
|
---|
24 | protected int max_width; // The width of the widest line
|
---|
25 | protected int line_height; // Total height of the font
|
---|
26 | protected int line_ascent; // Font height above baseline
|
---|
27 | protected boolean measured = false; // Have the lines been measured?
|
---|
28 |
|
---|
29 | // Here are five versions of the constructor
|
---|
30 | public MultiLineLabel(String label, int margin_width,
|
---|
31 | int margin_height, int alignment) {
|
---|
32 | this.label = label; // Remember all the properties
|
---|
33 | this.margin_width = margin_width;
|
---|
34 | this.margin_height = margin_height;
|
---|
35 | this.alignment = alignment;
|
---|
36 | newLabel(); // Break the label up into lines
|
---|
37 | }
|
---|
38 | public MultiLineLabel(String label, int margin_width, int margin_height) {
|
---|
39 | this(label, margin_width, margin_height, LEFT);
|
---|
40 | }
|
---|
41 | public MultiLineLabel(String label, int alignment) {
|
---|
42 | this(label, 10, 10, alignment);
|
---|
43 | }
|
---|
44 | public MultiLineLabel(String label) { this(label, 10, 10, LEFT); }
|
---|
45 | public MultiLineLabel() { this(""); }
|
---|
46 |
|
---|
47 | // Methods to set and query the various attributes of the component
|
---|
48 | // Note that some query methods are inherited from the superclass.
|
---|
49 | public void setLabel(String label) {
|
---|
50 | this.label = label;
|
---|
51 | newLabel(); // Break the label into lines
|
---|
52 | measured = false; // Note that we need to measure lines
|
---|
53 | repaint(); // Request a redraw
|
---|
54 | }
|
---|
55 | public void setFont(Font f) {
|
---|
56 | super.setFont(f); // tell our superclass about the new font
|
---|
57 | measured = false; // Note that we need to remeasure lines
|
---|
58 | repaint(); // Request a redraw
|
---|
59 | }
|
---|
60 | public void setForeground(Color c) {
|
---|
61 | super.setForeground(c); // tell our superclass about the new color
|
---|
62 | repaint(); // Request a redraw (size is unchanged)
|
---|
63 | }
|
---|
64 | public void setAlignment(int a) { alignment = a; repaint(); }
|
---|
65 | public void setMarginWidth(int mw) { margin_width = mw; repaint(); }
|
---|
66 | public void setMarginHeight(int mh) { margin_height = mh; repaint(); }
|
---|
67 | public String getLabel() { return label; }
|
---|
68 | public int getAlignment() { return alignment; }
|
---|
69 | public int getMarginWidth() { return margin_width; }
|
---|
70 | public int getMarginHeight() { return margin_height; }
|
---|
71 |
|
---|
72 | /**
|
---|
73 | * This method is called by a layout manager when it wants to
|
---|
74 | * know how big we'd like to be. In Java 1.1, getPreferredSize() is
|
---|
75 | * the preferred version of this method. We use this deprecated version
|
---|
76 | * so that this component can interoperate with 1.0 components.
|
---|
77 | */
|
---|
78 | public Dimension getPreferredSize() {
|
---|
79 | if (!measured) measure();
|
---|
80 | return new Dimension(max_width + 2*margin_width,
|
---|
81 | num_lines * line_height + 2*margin_height);
|
---|
82 | }
|
---|
83 |
|
---|
84 | /**
|
---|
85 | * This method is called when the layout manager wants to know
|
---|
86 | * the bare minimum amount of space we need to get by.
|
---|
87 | * For Java 1.1, we'd use getMinimumSize().
|
---|
88 | */
|
---|
89 | public Dimension getMinimumSize() { return getPreferredSize(); }
|
---|
90 |
|
---|
91 | /**
|
---|
92 | * This method draws the label (same method that applets use).
|
---|
93 | * Note that it handles the margins and the alignment, but that
|
---|
94 | * it doesn't have to worry about the color or font--the superclass
|
---|
95 | * takes care of setting those in the Graphics object we're passed.
|
---|
96 | */
|
---|
97 | public void paint(Graphics g) {
|
---|
98 | int x, y;
|
---|
99 | Dimension size = this.getSize(); // use getSize() in Java 1.1
|
---|
100 | if (!measured) measure();
|
---|
101 | y = line_ascent + (size.height - num_lines * line_height)/2;
|
---|
102 | for(int i = 0; i < num_lines; i++, y += line_height) {
|
---|
103 | switch(alignment) {
|
---|
104 | default:
|
---|
105 | case LEFT: x = margin_width; break;
|
---|
106 | case CENTER: x = (size.width - line_widths[i])/2; break;
|
---|
107 | case RIGHT: x = size.width - margin_width - line_widths[i]; break;
|
---|
108 | }
|
---|
109 | g.drawString(lines[i], x, y);
|
---|
110 | }
|
---|
111 | }
|
---|
112 |
|
---|
113 | /** This internal method breaks a specified label up into an array of lines.
|
---|
114 | * It uses the StringTokenizer utility class. */
|
---|
115 | protected synchronized void newLabel() {
|
---|
116 | StringTokenizer t = new StringTokenizer(label, "\n");
|
---|
117 | num_lines = t.countTokens();
|
---|
118 | lines = new String[num_lines];
|
---|
119 | line_widths = new int[num_lines];
|
---|
120 | for(int i = 0; i < num_lines; i++) lines[i] = t.nextToken();
|
---|
121 | }
|
---|
122 |
|
---|
123 | /** This internal method figures out how the font is, and how wide each
|
---|
124 | * line of the label is, and how wide the widest line is. */
|
---|
125 | protected synchronized void measure() {
|
---|
126 | FontMetrics fm = this.getFontMetrics(this.getFont());
|
---|
127 | line_height = fm.getHeight();
|
---|
128 | line_ascent = fm.getAscent();
|
---|
129 | max_width = 0;
|
---|
130 | for(int i = 0; i < num_lines; i++) {
|
---|
131 | line_widths[i] = fm.stringWidth(lines[i]);
|
---|
132 | if (line_widths[i] > max_width) max_width = line_widths[i];
|
---|
133 | }
|
---|
134 | measured = true;
|
---|
135 | }
|
---|
136 | }
|
---|