2 *******************************************************************************
\r
3 * Copyright (C) 1997-2010, International Business Machines Corporation and *
\r
4 * others. All Rights Reserved. *
\r
5 *******************************************************************************
\r
7 package com.ibm.icu.dev.demo.holiday;
\r
9 import java.awt.Color;
\r
10 import java.awt.Dimension;
\r
11 import java.awt.Font;
\r
12 import java.awt.FontMetrics;
\r
13 import java.awt.Graphics;
\r
14 import java.awt.Insets;
\r
15 import java.awt.Panel;
\r
18 * Various graphical borders. The border itself is a Panel so that it can
\r
19 * contain other Components (i.e. it borders something). You use the
\r
20 * HolidayBorderPanel like any other Panel: you set the layout that you prefer and
\r
21 * add Components to it. Beware that a null layout does not obey the insets
\r
22 * of the panel so if you use null layouts, adjust your measurements to
\r
23 * handle the border by calling insets().
\r
25 * @author Andy Clark, Taligent Inc.
\r
28 public class HolidayBorderPanel extends Panel {
\r
32 private static final long serialVersionUID = 4669213306492461159L;
\r
35 /** Solid border. */
\r
36 public final static int SOLID = 0;
\r
37 /** A raised border. */
\r
38 public final static int RAISED = 1;
\r
39 /** A lowered border. */
\r
40 public final static int LOWERED = 2;
\r
41 /** An etched in border. */
\r
42 public final static int IN = 3;
\r
43 /** An etched out border. */
\r
44 public final static int OUT = 4;
\r
46 /** Left alignment. */
\r
47 public final static int LEFT = 0;
\r
48 /** Center alignment. */
\r
49 public final static int CENTER = 1;
\r
50 /** Right alignment. */
\r
51 public final static int RIGHT = 2;
\r
53 /** Default style (IN). */
\r
54 public final static int DEFAULT_STYLE = IN;
\r
55 /** Default thickness (10). */
\r
56 public final static int DEFAULT_THICKNESS = 10;
\r
57 /** Default thickness for solid borders (4). */
\r
58 public final static int DEFAULT_SOLID_THICKNESS = 4;
\r
59 /** Default thickness for raised borders (2). */
\r
60 public final static int DEFAULT_RAISED_THICKNESS = 2;
\r
61 /** Default thickness for lowered borders (2). */
\r
62 public final static int DEFAULT_LOWERED_THICKNESS = 2;
\r
63 /** Default thickness for etched-in borders (10). */
\r
64 public final static int DEFAULT_IN_THICKNESS = 10;
\r
65 /** Default thickness for etched-out borders (10). */
\r
66 public final static int DEFAULT_OUT_THICKNESS = 10;
\r
67 /** Default gap between border and contained component (5). */
\r
68 public final static int DEFAULT_GAP = 5;
\r
69 /** Default color (black). Applies to SOLID and etched borders. */
\r
70 public final static Color DEFAULT_COLOR = Color.black;
\r
72 /** Default font (TimesRoman,PLAIN,14). Only applies to etched borders. */
\r
73 public final static Font DEFAULT_FONT = new Font("TimesRoman", Font.PLAIN, 14);
\r
74 /** Default alignment (LEFT). Only applies to etched borders. */
\r
75 public final static int DEFAULT_ALIGNMENT = LEFT;
\r
79 private int thickness;
\r
81 private Color color;
\r
84 private String text;
\r
85 private int alignment;
\r
88 * Constructor. Makes default border.
\r
90 public HolidayBorderPanel() {
\r
93 style = DEFAULT_STYLE;
\r
94 thickness = DEFAULT_THICKNESS;
\r
96 color = DEFAULT_COLOR;
\r
99 font = DEFAULT_FONT;
\r
100 alignment = DEFAULT_ALIGNMENT;
\r
105 * Constructor. Makes an etched IN border with given text caption.
\r
107 * @param text Text caption
\r
109 public HolidayBorderPanel(String text) {
\r
117 * Constructor. Makes SOLID border with color and thickness given.
\r
119 * @param color The color for the border.
\r
120 * @param thickness The thickness of the border.
\r
122 public HolidayBorderPanel(Color color, int thickness) {
\r
126 this.color = color;
\r
127 this.thickness = thickness;
\r
131 * Constructor. Makes a border of the given style with the default
\r
132 * thickness for that style.
\r
134 * @param style The style for this border.
\r
136 public HolidayBorderPanel(int style) {
\r
139 // set thickness appropriate to this style
\r
141 case SOLID: thickness = DEFAULT_SOLID_THICKNESS; break;
\r
142 case RAISED: thickness = DEFAULT_RAISED_THICKNESS; break;
\r
143 case LOWERED: thickness = DEFAULT_LOWERED_THICKNESS; break;
\r
144 case IN: thickness = DEFAULT_IN_THICKNESS; break;
\r
145 case OUT: thickness = DEFAULT_OUT_THICKNESS; break;
\r
147 thickness = DEFAULT_THICKNESS;
\r
150 this.style = style;
\r
154 * Constructor. Makes border with given style and thickness.
\r
156 * @param style The style for this border.
\r
157 * @param thickness The thickness for this border.
\r
159 public HolidayBorderPanel(int style, int thickness) {
\r
162 this.style = style;
\r
163 this.thickness = thickness;
\r
167 * Returns the insets of this panel..
\r
169 public Insets getInsets() {
\r
170 int adjustment = 0;
\r
172 // adjust for text string
\r
173 if (style == IN || style == OUT) {
\r
174 if (text != null && text.length() > 0) {
\r
176 // set font and get info
\r
177 int height = getGraphics().getFontMetrics(font).getHeight();
\r
178 if (height > thickness)
\r
179 adjustment = height - thickness;
\r
181 catch (Exception e) {
\r
182 // nothing: just in case there is no graphics context
\r
183 // at the beginning.
\r
184 System.out.print("");
\r
189 // return appropriate insets
\r
190 int dist = thickness + gap;
\r
191 return new Insets(dist + adjustment, dist, dist, dist);
\r
195 * Sets the style of the border
\r
197 * @param style The new style.
\r
199 public HolidayBorderPanel setStyle(int style) {
\r
201 // set the style and re-layout the panel
\r
202 this.style = style;
\r
210 * Gets the style of the border
\r
212 public int getStyle() {
\r
218 * Sets the thickness of the border.
\r
220 * @param thickness The new thickness
\r
222 public HolidayBorderPanel setThickness(int thickness) {
\r
224 if (thickness > 0) {
\r
225 this.thickness = thickness;
\r
234 * Gets the thickness of the border.
\r
236 public int getThickness() {
\r
242 * Sets the gap between the border and the contained Component.
\r
244 * @param gap The new gap, in pixels.
\r
246 public HolidayBorderPanel setGap(int gap) {
\r
258 * Gets the gap between the border and the contained Component.
\r
260 public int getGap() {
\r
266 * Sets the current color for SOLID borders and the caption text
\r
267 * color for etched borders.
\r
269 * @param color The new color.
\r
271 public HolidayBorderPanel setColor(Color color) {
\r
273 this.color = color;
\r
274 if (style == SOLID || style == IN || style == OUT)
\r
281 * Gets the current color for SOLID borders and the caption
\r
282 * text color for etched borders.
\r
284 public Color getColor() {
\r
290 * Sets the font. Only applies to etched borders.
\r
292 public HolidayBorderPanel setTextFont(Font font) {
\r
295 if (font != null) {
\r
297 if (style == IN || style == OUT) {
\r
307 * Gets the font of the text. Only applies to etched borders.
\r
309 public Font getTextFont() {
\r
315 * Sets the text. Only applies to etched borders.
\r
317 * @param text The new text.
\r
319 public HolidayBorderPanel setText(String text) {
\r
322 if (style == IN || style == OUT) {
\r
331 * Gets the text. Only applies to etched borders.
\r
333 public String getText() {
\r
339 * Sets the text alignment. Only applies to etched borders.
\r
341 * @param alignment The new alignment.
\r
343 public HolidayBorderPanel setAlignment(int alignment) {
\r
345 this.alignment = alignment;
\r
346 if (style == IN || style == OUT) {
\r
355 * Gets the text alignment.
\r
357 public int getAlignment() {
\r
363 * Repaints the border.
\r
365 * @param g The graphics context.
\r
367 public void paint(Graphics g) {
\r
369 // get current dimensions
\r
370 Dimension size = getSize();
\r
371 int width = size.width;
\r
372 int height = size.height;
\r
375 Color light = getBackground().brighter().brighter().brighter();
\r
376 Color dark = getBackground().darker().darker().darker();
\r
380 case RAISED: // 3D Border (in or out)
\r
382 Color topleft = null;
\r
383 Color bottomright = null;
\r
386 if (style == RAISED) {
\r
388 bottomright = dark;
\r
392 bottomright = light;
\r
396 g.setColor(topleft);
\r
397 for (int i = 0; i < thickness; i++) {
\r
398 g.drawLine(i, i, width - i - 2, i);
\r
399 g.drawLine(i, i + 1, i, height - i - 1);
\r
401 g.setColor(bottomright);
\r
402 for (int i = 0; i < thickness; i++) {
\r
403 g.drawLine(i + 1, height - i - 1, width - i - 1, height - i - 1);
\r
404 g.drawLine(width - i - 1, i, width - i - 1, height - i - 2);
\r
408 case IN: // Etched Border (in or out)
\r
413 // set font and get info
\r
414 Font oldfont = g.getFont();
\r
416 FontMetrics fm = g.getFontMetrics();
\r
417 int ascent = fm.getAscent();
\r
425 // Calculate adjustment for text
\r
426 int adjustment = 0;
\r
427 if (text != null && text.length() > 0) {
\r
428 if (ascent > thickness)
\r
429 adjustment = (ascent - thickness) / 2;
\r
432 // The adjustment is there so that we always draw the
\r
433 // light rectangle first. Otherwise, your eye picks up
\r
434 // the discrepancy where the light rect. passes over
\r
435 // the darker rect.
\r
436 int x = thickness / 2;
\r
437 int y = thickness / 2 + adjustment;
\r
438 int w = width - thickness - 1;
\r
439 int h = height - thickness - 1 - adjustment;
\r
443 g.drawRect(x + adjust1, y + adjust1, w, h);
\r
445 g.drawRect(x + adjust2, y + adjust2, w, h);
\r
447 // draw text, if applicable
\r
448 if (text != null && text.length() > 0) {
\r
449 // calculate drawing area
\r
450 int fontheight = fm.getHeight();
\r
451 int strwidth = fm.stringWidth(text);
\r
453 int textwidth = width - 2 * (thickness + 5);
\r
454 if (strwidth > textwidth)
\r
455 strwidth = textwidth;
\r
457 // calculate offset for alignment
\r
459 switch (alignment) {
\r
461 offset = (width - strwidth) / 2;
\r
464 offset = width - strwidth - thickness - 5;
\r
467 default: // assume left alignment if invalid
\r
468 offset = thickness + 5;
\r
472 // clear drawing area and set clipping region
\r
473 g.clearRect(offset - 5, 0, strwidth + 10, fontheight);
\r
474 g.clipRect(offset, 0, strwidth, fontheight);
\r
478 g.drawString(text, offset, ascent);
\r
480 // restore old clipping area
\r
481 g.clipRect(0, 0, width, height);
\r
484 g.setFont(oldfont);
\r
488 default: // assume SOLID
\r
490 for (int i = 0; i < thickness; i++)
\r
491 g.drawRect(i, i, width - 2 * i - 1, height - 2 * i - 1);
\r
497 * Returns the settings of this HolidayBorderPanel instance as a string.
\r
499 public String toString() {
\r
500 StringBuffer str = new StringBuffer("HolidayBorderPanel[");
\r
503 str.append("style=");
\r
505 case SOLID: str.append("SOLID"); break;
\r
506 case RAISED: str.append("RAISED"); break;
\r
507 case LOWERED: str.append("LOWERED"); break;
\r
508 case IN: str.append("IN"); break;
\r
509 case OUT: str.append("OUT"); break;
\r
510 default: str.append("unknown");
\r
515 str.append("thickness=");
\r
516 str.append(thickness);
\r
520 str.append("gap=");
\r
533 str.append("text=");
\r
538 str.append("alignment=");
\r
539 switch (alignment) {
\r
540 case LEFT: str.append("LEFT"); break;
\r
541 case CENTER: str.append("CENTER"); break;
\r
542 case RIGHT: str.append("RIGHT"); break;
\r
543 default: str.append("unknown");
\r
548 return str.toString();
\r