001 /*
002 * Copyright (c) Holger Pfaff - http://pfaff.ws
003 *
004 * This software maybe used for any purpose provided the
005 * above copyright notice is retained. It is supplied as is.
006 * No warranty expressed or implied - Use at your own risk.
007 */
008
009 import java.awt.*;
010 import java.util.*;
011 import java.awt.event.*;
012 import java.applet.*;
013 import java.net.URL;
014
015 /**
016 * (#)Caption.java
017 * @author Holger Pfaff
018 * @version 3.2 19-Mar-2004<br><br>
019 *
020 * A caption (label) that can display Awt hypertext
021 *
022 */
023
024 public class Caption extends Awt {
025
026 /**
027 * our contents
028 */
029 protected String caption = null;
030
031 /**
032 * icon layout if any
033 */
034 protected int iconDist = 0; // distance between icon and caption
035 protected int iconPos = NONE; // icon position NONE LEFT RIGHT of caption
036
037 /**
038 * component states (used for implementing classes)
039 */
040 protected boolean active = false; // show component as active (e.g. button down) ?
041 protected boolean entered = false; // show component as entered (e.g. surrounding rect) ?
042
043 /**
044 * Modes
045 */
046 protected int mode = 0; // drawing modes
047
048 /**
049 * is layout invalid ? (needed for recalc of href pos)
050 */
051 protected boolean invalid = true;
052
053 /**
054 * list of hrefs in this caption. maps rectangle to string
055 */
056 protected Hashtable hrefs = new Hashtable();
057
058 /**
059 * list of hrefs in this caption. maps rectangle to string
060 */
061 protected Rectangle activeRect = null;
062
063 /**
064 * Constructor for an empty caption
065 */
066 public Caption() {
067 this("");
068 }
069
070 /**
071 * Standard constructor
072 *
073 * @param caption the text
074 */
075 public Caption(String caption) {
076 this(caption, LEFT);
077 }
078
079 /**
080 * Constructor with additional alignment specification
081 *
082 * @param caption the text
083 * @param mode the line mode
084 */
085 public Caption(String caption, int mode) {
086 this.caption = caption;
087 this.insets = new Insets(1,1,1,1);
088 this.mode = mode;
089 if(getClass() == Caption.class) {
090 addMouseListener(this);
091 addMouseMotionListener(this);
092 }
093 }
094
095 /**
096 * set a new caption
097 *
098 * @param caption the text
099 */
100 public void setCaption(String c) {
101 if(c == null || caption == null || caption.equals(c) == false) {
102 caption = c;
103 doMeasure();
104 repaint();
105 }
106 }
107
108 /**
109 * get current caption
110 */
111 public String getCaption() {
112 return caption;
113 }
114
115 /**
116 * set a new caption (compat with java.awt.Label)
117 *
118 * @param label the text
119 */
120 public void setLabel(String l) {
121 setCaption(l);
122 }
123
124 /**
125 * get current caption (compat with java.awt.Label)
126 */
127 public String getLabel() {
128 return getCaption();
129 }
130
131 /**
132 * set a new caption (compat with java.awt.Label)
133 *
134 * @param label the text
135 */
136 public void setTitle(String l) {
137 setCaption(l);
138 }
139
140 /**
141 * get current caption (compat with java.awt.Label)
142 */
143 public String getTitle() {
144 return getCaption();
145 }
146
147 /**
148 * set a new caption (compat with java.awt.TextComponent)
149 *
150 * @param t the text
151 */
152 public void setText(String t) {
153 setCaption(t);
154 }
155
156 /**
157 * get current caption (compat with java.awt.TextComponent)
158 */
159 public String getText() {
160 return getCaption();
161 }
162
163 /**
164 * set the mode
165 *
166 * @param m the mode
167 */
168 public void setMode(int m) {
169 if(mode != m) {
170 mode = m;
171 doMeasure();
172 repaint();
173 }
174 }
175
176 /**
177 * get current mode
178 */
179 public int getMode() {
180 return mode;
181 }
182
183 /**
184 * set current activity state
185 *
186 * @param a the state
187 */
188 public void setActive(boolean a) {
189 if(active != a) {
190 active = a;
191 repaint();
192 }
193 }
194
195 /**
196 * get current state
197 */
198 public boolean isActive() {
199 return active;
200 }
201
202 /**
203 * set current entered state
204 *
205 * @param e the state
206 */
207 public void setEntered(boolean e) {
208 if(entered != e) {
209 entered = e;
210 repaint();
211 }
212 }
213
214 /**
215 * get current state
216 */
217 public boolean isEntered() {
218 return entered;
219 }
220
221 /**
222 * Overwirte paint to do the actual artwork ;-)
223 *
224 * @param g Graphics object to use
225 */
226 public void paint(Graphics g) {
227 makeBim();
228 paintBackground(big);
229
230 int btype = borderType;
231 if(borderType == RAISED && active) {
232 borderType = SUNKEN;
233 }
234 super.paint(big);
235 borderType = btype;
236
237 if(entered && !active) {
238 Rectangle br = getBorderRectangle();
239 drawRectangle(big, dim(getBackground(), -90), br.x, br.y, br.width - 1, br.height - 1, 1, 0);
240 }
241
242 Rectangle ir = getInnerRectangle();
243 Dimension id = measureIcon();
244 Dimension cd = measureCaption();
245
246 if(active) {
247 ir.x++; ir.y++;
248 }
249
250 paintCaption(big, iconPos == LEFT ? ir.x + id.width + iconDist : ir.x, ir.y, ir.width - id.width - iconDist, cd.height);
251 paintIcon(big, iconPos == RIGHT && cd.width > 0 ? ir.x + ir.width - id.width : ir.x, ir.y, id.width, id.height);
252
253 paintBim(g);
254
255 invalid = false;
256 }
257
258 /**
259 * Paint the Caption (Title)
260 *
261 * @param g Graphics object to use
262 * @param x x-position of describing rect
263 * @param y y-position of describing rect
264 * @param w width of describing rect
265 * @param h height of describing rect
266 */
267 public void paintCaption(Graphics g, int x, int y, int w, int h) {
268 drawCaption(g, isEnabled() ? getForeground() : getBackground(), getFont(), caption, x, y, w, h, isEnabled() ? mode : mode | Awt.SUNKEN, "\n", this);
269 }
270
271 /**
272 * Paint the Icon
273 *
274 * @param g Graphics object to use
275 * @param x x-position of describing rect
276 * @param y y-position of describing rect
277 * @param w width of describing rect
278 * @param h height of describing rect
279 */
280 public void paintIcon(Graphics g, int x, int y, int w, int h) {
281 }
282
283 /**
284 * calculate Caption (Title) size including a fix one pixel border left/right two pixel top/bottom
285 */
286 public Dimension measureCaption() {
287 return measureCaption(caption, getFont(), getFont(), "\n");
288 }
289
290 /**
291 * calculate Icon size - intended as a placeholder for implementing classes
292 */
293 public Dimension measureIcon() {
294 return new Dimension();
295 }
296
297 /**
298 * calculate required sizes
299 */
300 public Dimension measure() {
301 Dimension bd = super.measure();
302 Dimension cd = measureCaption();
303 Dimension id = measureIcon();
304 bd.width += cd.width > 0 ? cd.width + iconDist + id.width : id.width;
305 bd.height += Math.max(cd.height, id.height);
306 return bd;
307 }
308
309 /**
310 * Overwrite Awt.invalidate()
311 */
312 public void invalidate() {
313 hrefs.clear();
314 invalid = true;
315 super.invalidate();
316 }
317
318 /**
319 * Overwrite Awt.doHref()
320 */
321 public void doHref(String s, int x, int y, int w, int h) {
322 if(invalid) {
323 hrefs.put(new Rectangle(x, y, w, h), s);
324 }
325 }
326
327 /**
328 * get current Hyper reference if any
329 */
330 public String getHref() {
331 return activeRect == null ? null : exHref((String) hrefs.get(activeRect));
332 }
333
334 /**
335 * implement java.awt.event.MouseListener
336 */
337 public void mousePressed(MouseEvent e) {
338 if(activeRect != null) {
339 try {
340 getAppletContext(this).showDocument(new URL(getHref()), "_blank");
341 } catch(Exception x) {
342 Awt.error("Only supported in applet mode", this);
343 }
344 }
345 }
346
347 /**
348 * implement java.awt.event.MouseListener
349 */
350 public void mouseExited(MouseEvent e) {
351 mouseMoved(e);
352 }
353
354 /**
355 * implement java.awt.event.MouseListener
356 */
357 public void mouseMoved(MouseEvent e) {
358 for(Enumeration enum = hrefs.keys() ; enum.hasMoreElements() ;) {
359 Rectangle r = (Rectangle) enum.nextElement();
360 if(r.contains(e.getPoint())) {
361 if(activeRect == null || activeRect.equals(r) == false) {
362 setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
363 activeRect = r;
364 }
365 return;
366 }
367 }
368 if(activeRect != null) {
369 activeRect = null;
370 setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
371 }
372 }
373 }