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.util.*;
010 import java.awt.*;
011 import java.awt.event.*;
012
013 /**
014 * (#)Cal.java
015 * @author Holger Pfaff
016 * @version 3.2 19-Mar-2004<br><br>
017 *
018 * A Panel with an optional border, titlestring and helptext that
019 * can be minimized if desired
020 */
021
022 public class BorderPanel extends Caption {
023
024 /**
025 * helptext for this panel null for none
026 */
027 protected String helpText = null;
028
029 /**
030 * nulllayout is used when minimized
031 */
032 protected NullLayout nullLayout = new NullLayout();
033
034 /**
035 * can this panel be minimized ?
036 */
037 protected boolean miniMizable = false;
038
039 /**
040 * mouse over icon ?
041 */
042 private boolean moi = false;
043
044 /**
045 * mouse over title ?
046 */
047 private boolean mot = false;
048
049 /**
050 * space surrounding the caption
051 */
052 private Insets captionInsets = new Insets(1,2,1,2);
053
054 /**
055 * space surrounding the (minimize-) icon
056 */
057 private Insets iconInsets = new Insets(1,1,1,1);
058
059 /**
060 * The default contructor creates a regualr panel w/o decoration.
061 */
062 public BorderPanel() {
063 this(NONE, null);
064 }
065
066 /**
067 * Create a panel with the specified border type.
068 *
069 * @param borderType border type.
070 */
071 public BorderPanel(int borderType) {
072 this(borderType, null);
073 }
074
075 /**
076 * Create a panel with the specified title string.
077 * Bordertype BULK is used per default
078 *
079 * @param title Title.
080 */
081 public BorderPanel(String title) {
082 this(BULK, title);
083 }
084
085 /**
086 * Create a panel with the specified border type and title string.
087 *
088 * @param borderType border type.
089 * @param title Title.
090 */
091 public BorderPanel(int borderType, String title) {
092 super(title);
093 this.borderType = borderType;
094 this.borderDepth = borderType == NONE ? 0 : 1;
095 this.iconDist = 6;
096 this.insets = new Insets(1,1,1,1);
097 this.innerInsets = new Insets(1,1,1,1);
098 addMouseListener(this);
099 addMouseMotionListener(this);
100 }
101
102 /**
103 * Set the help text for this panel
104 *
105 * @param helpText help text.
106 */
107 public void setHelptext(String helpText) {
108 this.helpText = helpText;
109 }
110
111 /**
112 * Get this panels help text
113 */
114 public String getHelptext() {
115 return helpText;
116 }
117
118 /**
119 * Set the miniMizable property for this panel
120 *
121 * @param miniMizable can this panel be minimized?
122 */
123 public void setMinimizable(boolean miniMizable) {
124 this.miniMizable = miniMizable;
125 }
126
127 /**
128 * Get this panels miniMizable property
129 */
130 public boolean minimizable() {
131 return miniMizable;
132 }
133
134 /**
135 * Force this panel to a specific state
136 *
137 * @param m minimized=true maximized=false
138 */
139 public void setMini(boolean m) {
140 if(m) {
141 if(mini() == false) {
142 nullLayout.setBaseLayout(getLayout());
143 super.setLayout(nullLayout);
144 }
145 } else {
146 if(mini() == true) {
147 super.setLayout(nullLayout.getBaseLayout());
148 }
149 }
150 //if(getFont() != null) refreshAll();
151 refreshAll();
152 }
153
154 /**
155 * Get this panels state
156 */
157 public boolean mini() {
158 return getLayout() instanceof NullLayout;
159 }
160
161 /**
162 * Overwite setLayout() to be able to save old layout
163 */
164 public void setLayout(LayoutManager l) {
165 if(mini()) {
166 nullLayout.setBaseLayout(l);
167 } else {
168 super.setLayout(l);
169 }
170 }
171
172 /**
173 * calculate required sizes for this panel
174 */
175 public Dimension measure() {
176 Dimension d = getLayout() == null ? new Dimension() : getLayout().preferredLayoutSize(this);
177 int w = getInsets().left + iconDist + measureIcon().width + iconDist + measureCaption().width + getInsets().right;
178 d.width = Math.max(d.width, w);
179 return d;
180 }
181
182 /**
183 * calculate Caption (Title) size including a fix one pixel border left/right two pixel top/bottom
184 */
185 public Dimension measureCaption() {
186 if(titleVisible()) {
187 Dimension d = super.measureCaption();
188 d.width += captionInsets.left + captionInsets.right;
189 d.height += captionInsets.top + captionInsets.bottom;
190 return d;
191 } else {
192 return new Dimension();
193 }
194 }
195
196 /**
197 * calculate Icon size including a fix one pixel border left/right two pixel top/bottom
198 */
199 public Dimension measureIcon() {
200 int h = measureCaption("X", getFont(), getFont(), "").height;
201 return iconVisible() ? new Dimension(h + iconInsets.left + iconInsets.right, h + iconInsets.top + iconInsets.bottom) : new Dimension();
202 }
203
204 /**
205 * calculate titlehight, if any
206 */
207 public int measureTitleHeight() {
208 int th = Math.max(measureCaption().height, measureIcon().height);
209 return th == 0 ? 0 : th + insets.top;
210 }
211
212 /**
213 * get Insets for this panel. insets + innerInsets + titlehight
214 */
215 public Insets getInsets() {
216 return new Insets(insets.top + borderDepth + innerInsets.top + measureTitleHeight(),
217 insets.left + borderDepth + innerInsets.left,
218 insets.bottom + borderDepth + innerInsets.bottom,
219 insets.right + borderDepth + innerInsets.right);
220 }
221
222 /**
223 * is title currently visible ?
224 */
225 public boolean titleVisible() {
226 return getLabel() != null && getLabel().length() > 0;
227 }
228
229 /**
230 * is icon currently visible ?
231 */
232 public boolean iconVisible() {
233 return miniMizable;
234 }
235
236 /**
237 * calculate title position & size
238 */
239 protected Rectangle getTitleRectangle() {
240 Dimension d = measureCaption();
241 Rectangle r = new Rectangle();
242 r.x = insets.left + iconDist;
243 r.x += iconVisible() ? measureIcon().width + iconDist : 0;
244 r.y = insets.top;
245 r.width = d.width;
246 r.height = d.height;
247 return r;
248 }
249
250 /**
251 * calculate icon position & size
252 */
253 protected Rectangle getIconRectangle() {
254 Dimension d = measureIcon();
255 Rectangle r = new Rectangle();
256 r.x = insets.left + iconDist;
257 r.y = insets.top;
258 r.width = d.width;
259 r.height = d.height;
260 return r;
261 }
262
263 /**
264 * Overwirte paint to do the actual artwork ;-)
265 *
266 * @param g Graphics object to use
267 */
268 public void paint(Graphics g) {
269 if(g == null) return;
270 int th = measureTitleHeight();
271 Rectangle br = getRectangle();
272 Rectangle tr = getTitleRectangle();
273 Rectangle ir = getIconRectangle();
274
275 makeBim();
276 paintBackground(big);
277 if(borderType == BULK && th > 0) th = th/2 - borderDepth;
278 if(borderDepth > 0) paintBorder(big, br.x, br.y + th, br.width - 1, br.height - th - 1);
279 if(titleVisible()) paintCaption(big, tr.x, tr.y, tr.width, tr.height);
280 if(iconVisible()) paintIcon(big, ir.x, ir.y, ir.width, ir.height);
281 paintBim(g);
282 }
283
284 /**
285 * Paint the Caption (Title)
286 *
287 * @param g Graphics object to use
288 * @param x x-position of describing rect
289 * @param y y-position of describing rect
290 * @param w width of describing rect
291 * @param h height of describing rect
292 */
293 public void paintCaption(Graphics g, int x, int y, int w, int h) {
294 paintBackground(g, x - 1, y, w - 1 + 1, h - 1);
295 super.paintCaption(g, x + captionInsets.left, y + captionInsets.top, w - captionInsets.left - captionInsets.right, h - captionInsets.top - captionInsets.bottom);
296 if(mot) drawRectangle(g, dim(getBackground(), -110), x - 1, y, w - 1 + 1, h - 1, 1, 0);
297 }
298
299 /**
300 * Paint the Icon
301 *
302 * @param g Graphics object to use
303 * @param x x-position of describing rect
304 * @param y y-position of describing rect
305 * @param w width of describing rect
306 * @param h height of describing rect
307 */
308 public void paintIcon(Graphics g, int x, int y, int w, int h) {
309 paintBackground(g, x + 1, y, w - 3, h - 1);
310 drawTriangle(g, getBackground(), x + 1 + iconInsets.left, y + 1 + iconInsets.top, w - 2 - iconInsets.left - iconInsets.right, h - 2 - iconInsets.top - iconInsets.bottom, 1, RAISED | (mini() ? N : S));
311 if(moi) drawRectangle(g, dim(getBackground(), -110), x, y, w - 1, h - 1, 1, 0);
312 }
313
314 /**
315 * implement java.awt.event.MouseListener
316 */
317 public void mouseExited(MouseEvent e) {
318 if(moi || mot) {
319 moi = mot = false;
320 repaint();
321 }
322 }
323
324 /**
325 * implement java.awt.event.MouseListener
326 */
327 public void mouseMoved(MouseEvent e) {
328 boolean i = getIconRectangle().contains(e.getPoint());
329 boolean t = getTitleRectangle().contains(e.getPoint());
330 if(i != moi || t != mot) {
331 moi = i; mot = t;
332 repaint();
333 }
334 }
335
336 /**
337 * implement java.awt.event.MouseListener
338 */
339 public void mouseClicked(MouseEvent e) {
340 if(getIconRectangle().contains(e.getPoint())) {
341 setMini(!mini());
342 } else {
343 if(helpText != null) {
344 DialogBox.infoDialog(helpText).show(this); mouseExited(e);
345 }
346 }
347 repaint();
348 }
349 }