KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hsqldb > util > Tree


1 /* Copyright (c) 1995-2000, The Hypersonic SQL Group.
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * Redistributions of source code must retain the above copyright notice, this
8  * list of conditions and the following disclaimer.
9  *
10  * Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * Neither the name of the Hypersonic SQL Group nor the names of its
15  * contributors may be used to endorse or promote products derived from this
16  * software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,
22  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  *
30  * This software consists of voluntary contributions made by many individuals
31  * on behalf of the Hypersonic SQL Group.
32  *
33  *
34  * For work added by the HSQL Development Group:
35  *
36  * Copyright (c) 2001-2005, The HSQL Development Group
37  * All rights reserved.
38  *
39  * Redistribution and use in source and binary forms, with or without
40  * modification, are permitted provided that the following conditions are met:
41  *
42  * Redistributions of source code must retain the above copyright notice, this
43  * list of conditions and the following disclaimer.
44  *
45  * Redistributions in binary form must reproduce the above copyright notice,
46  * this list of conditions and the following disclaimer in the documentation
47  * and/or other materials provided with the distribution.
48  *
49  * Neither the name of the HSQL Development Group nor the names of its
50  * contributors may be used to endorse or promote products derived from this
51  * software without specific prior written permission.
52  *
53  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
54  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56  * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
57  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
58  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
59  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
60  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
61  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
62  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
63  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64  */

65
66
67 package org.hsqldb.util;
68
69 import java.util.Vector JavaDoc;
70
71 import java.awt.Color JavaDoc;
72 import java.awt.Dimension JavaDoc;
73 import java.awt.Event JavaDoc;
74 import java.awt.Font JavaDoc;
75 import java.awt.FontMetrics JavaDoc;
76 import java.awt.Graphics JavaDoc;
77 import java.awt.Image JavaDoc;
78 import java.awt.Panel JavaDoc;
79 import java.awt.Scrollbar JavaDoc;
80 import java.awt.SystemColor JavaDoc;
81 import java.awt.Toolkit JavaDoc;
82
83 /**
84  *
85  * @author Thomas Mueller (Hypersonic SQL Group)
86  * @version 1.7.0
87  * @since Hypersonic SQL
88  */

89 class Tree extends Panel JavaDoc {
90
91     // static
92
private static Font JavaDoc fFont;
93     private static FontMetrics JavaDoc fMetrics;
94     private static int iRowHeight;
95     private static int iIndentWidth;
96     private int iMaxTextLength;
97
98     // drawing
99
private Dimension JavaDoc dMinimum;
100     private Graphics JavaDoc gImage;
101     private Image JavaDoc iImage;
102
103     // height / width
104
private int iWidth, iHeight;
105     private int iFirstRow;
106     private int iTreeWidth, iTreeHeight;
107     private int iX, iY;
108
109     // data
110
private Vector JavaDoc vData;
111     private int iRowCount;
112
113     // scrolling
114
private Scrollbar JavaDoc sbHoriz, sbVert;
115     private int iSbWidth, iSbHeight;
116
117     static {
118         fFont = new Font JavaDoc("Dialog", Font.PLAIN, 12);
119         fMetrics = Toolkit.getDefaultToolkit().getFontMetrics(fFont);
120         iRowHeight = getMaxHeight(fMetrics);
121         iIndentWidth = 12;
122     }
123
124     /**
125      * Constructor declaration
126      *
127      */

128     Tree() {
129
130         super();
131
132         vData = new Vector JavaDoc();
133
134         setLayout(null);
135
136         sbHoriz = new Scrollbar JavaDoc(Scrollbar.HORIZONTAL);
137
138         add(sbHoriz);
139
140         sbVert = new Scrollbar JavaDoc(Scrollbar.VERTICAL);
141
142         add(sbVert);
143     }
144
145     /**
146      * Method declaration
147      *
148      *
149      * @param d
150      */

151     public void setMinimumSize(Dimension JavaDoc d) {
152         dMinimum = d;
153     }
154
155     /**
156      * Method declaration
157      *
158      *
159      * @param x
160      * @param y
161      * @param w
162      * @param h
163      */

164
165 // fredt@users 20011210 - patch 450412 by elise@users
166
// with additional replacement of deprecated methods
167
public void setBounds(int x, int y, int w, int h) {
168
169         super.setBounds(x, y, w, h);
170
171         iSbHeight = sbHoriz.getPreferredSize().height;
172         iSbWidth = sbVert.getPreferredSize().width;
173         iHeight = h - iSbHeight;
174         iWidth = w - iSbWidth;
175
176         sbHoriz.setBounds(0, iHeight, iWidth, iSbHeight);
177         sbVert.setBounds(iWidth, 0, iSbWidth, iHeight);
178         adjustScroll();
179
180         iImage = null;
181
182         repaint();
183     }
184
185     /**
186      * Method declaration
187      *
188      */

189     public void removeAll() {
190
191         vData = new Vector JavaDoc();
192         iRowCount = 0;
193
194         adjustScroll();
195
196         iMaxTextLength = 10;
197
198         repaint();
199     }
200
201     /**
202      * Method declaration
203      *
204      *
205      * @param key
206      * @param value
207      * @param state
208      * @param color
209      */

210     public void addRow(String JavaDoc key, String JavaDoc value, String JavaDoc state, int color) {
211
212         String JavaDoc[] row = new String JavaDoc[4];
213
214         if (value == null) {
215             value = "";
216         }
217
218         row[0] = key;
219         row[1] = value;
220         row[2] = state; // null / "-" / "+"
221
row[3] = String.valueOf(color);
222
223         vData.addElement(row);
224
225         int len = fMetrics.stringWidth(value);
226
227         if (len > iMaxTextLength) {
228             iMaxTextLength = len;
229         }
230
231         iRowCount++;
232     }
233
234     /**
235      * Method declaration
236      *
237      *
238      * @param key
239      * @param value
240      */

241     public void addRow(String JavaDoc key, String JavaDoc value) {
242         addRow(key, value, null, 0);
243     }
244
245     /**
246      * Method declaration
247      *
248      */

249     public void update() {
250         adjustScroll();
251         repaint();
252     }
253
254     /**
255      * Method declaration
256      *
257      */

258     void adjustScroll() {
259
260         iTreeHeight = iRowHeight * (iRowCount + 1);
261
262         // correct would be iMaxTextLength + iMaxIndent*iIndentWidth
263
iTreeWidth = iMaxTextLength * 2;
264
265         sbHoriz.setValues(iX, iWidth, 0, iTreeWidth);
266
267         int v = iY / iRowHeight,
268             h = iHeight / iRowHeight;
269
270         sbVert.setValues(v, h, 0, iRowCount + 1);
271
272         iX = sbHoriz.getValue();
273         iY = iRowHeight * sbVert.getValue();
274     }
275
276     /**
277      * Method declaration
278      *
279      *
280      * @param e
281      *
282      * @return
283      */

284
285 // fredt@users 20020130 - comment by fredt
286
// to remove this deprecated method we need to rewrite the Tree class as a
287
// ScrollPane component
288
public boolean handleEvent(Event JavaDoc e) {
289
290         switch (e.id) {
291
292             case Event.SCROLL_LINE_UP :
293             case Event.SCROLL_LINE_DOWN :
294             case Event.SCROLL_PAGE_UP :
295             case Event.SCROLL_PAGE_DOWN :
296             case Event.SCROLL_ABSOLUTE :
297                 iX = sbHoriz.getValue();
298                 iY = iRowHeight * sbVert.getValue();
299
300                 repaint();
301
302                 return true;
303         }
304
305         return super.handleEvent(e);
306     }
307
308     /**
309      * Method declaration
310      *
311      *
312      * @param g
313      */

314     public void paint(Graphics JavaDoc g) {
315
316         if (g == null || iWidth <= 0 || iHeight <= 0) {
317             return;
318         }
319
320         g.setColor(SystemColor.control);
321         g.fillRect(iWidth, iHeight, iSbWidth, iSbHeight);
322
323         if (iImage == null) {
324             iImage = createImage(iWidth, iHeight);
325             gImage = iImage.getGraphics();
326
327             gImage.setFont(fFont);
328         }
329
330         gImage.setColor(Color.white);
331         gImage.fillRect(0, 0, iWidth, iHeight);
332
333         int[] lasty = new int[100];
334         String JavaDoc[] root = new String JavaDoc[100];
335
336         root[0] = "";
337
338         int currentindent = 0;
339         int y = iRowHeight;
340
341         y -= iY;
342
343         boolean closed = false;
344
345         for (int i = 0; i < iRowCount; i++) {
346             String JavaDoc[] s = (String JavaDoc[]) vData.elementAt(i);
347             String JavaDoc key = s[0];
348             String JavaDoc data = s[1];
349             String JavaDoc folder = s[2];
350             int ci = currentindent;
351
352             for (; ci > 0; ci--) {
353                 if (key.startsWith(root[ci])) {
354                     break;
355                 }
356             }
357
358             if (root[ci].length() < key.length()) {
359                 ci++;
360             }
361
362             if (closed && ci > currentindent) {
363                 continue;
364             }
365
366             closed = folder != null && folder.equals("+");
367             root[ci] = key;
368
369             int x = iIndentWidth * ci - iX;
370
371             gImage.setColor(Color.lightGray);
372             gImage.drawLine(x, y, x + iIndentWidth, y);
373             gImage.drawLine(x, y, x, lasty[ci]);
374
375             lasty[ci + 1] = y;
376
377             int py = y + iRowHeight / 3;
378             int px = x + iIndentWidth * 2;
379
380             if (folder != null) {
381                 lasty[ci + 1] += 4;
382
383                 int rgb = Integer.parseInt(s[3]);
384
385                 gImage.setColor(rgb == 0 ? Color.white
386                                          : new Color JavaDoc(rgb));
387                 gImage.fillRect(x + iIndentWidth - 3, y - 3, 7, 7);
388                 gImage.setColor(Color.black);
389                 gImage.drawRect(x + iIndentWidth - 4, y - 4, 8, 8);
390                 gImage.drawLine(x + iIndentWidth - 2, y,
391                                 x + iIndentWidth + 2, y);
392
393                 if (folder.equals("+")) {
394                     gImage.drawLine(x + iIndentWidth, y - 2,
395                                     x + iIndentWidth, y + 2);
396                 }
397             } else {
398                 px -= iIndentWidth;
399             }
400
401             gImage.setColor(Color.black);
402             gImage.drawString(data, px, py);
403
404             currentindent = ci;
405             y += iRowHeight;
406         }
407
408         g.drawImage(iImage, 0, 0, this);
409     }
410
411     /**
412      * Method declaration
413      *
414      *
415      * @param g
416      */

417     public void update(Graphics JavaDoc g) {
418         paint(g);
419     }
420
421     /**
422      * Method declaration
423      *
424      *
425      * @return
426      */

427     public Dimension JavaDoc preferredSize() {
428         return dMinimum;
429     }
430
431     /**
432      * Method declaration
433      *
434      *
435      * @return
436      */

437     public Dimension JavaDoc getPreferredSize() {
438         return dMinimum;
439     }
440
441     /**
442      * Method declaration
443      *
444      *
445      * @return
446      */

447     public Dimension JavaDoc getMinimumSize() {
448         return dMinimum;
449     }
450
451     /**
452      * Method declaration
453      *
454      *
455      * @return
456      */

457     public Dimension JavaDoc minimumSize() {
458         return dMinimum;
459     }
460
461     /**
462      * Method declaration
463      *
464      *
465      * @param e
466      * @param x
467      * @param y
468      *
469      * @return
470      */

471     public boolean mouseDown(Event JavaDoc e, int x, int y) {
472
473         if (iRowHeight == 0 || x > iWidth || y > iHeight) {
474             return true;
475         }
476
477         y += iRowHeight / 2;
478
479         String JavaDoc[] root = new String JavaDoc[100];
480
481         root[0] = "";
482
483         int currentindent = 0;
484         int cy = iRowHeight;
485         boolean closed = false;
486         int i = 0;
487
488         y += iY;
489
490         for (; i < iRowCount; i++) {
491             String JavaDoc[] s = (String JavaDoc[]) vData.elementAt(i);
492             String JavaDoc key = s[0];
493             String JavaDoc folder = s[2];
494             int ci = currentindent;
495
496             for (; ci > 0; ci--) {
497                 if (key.startsWith(root[ci])) {
498                     break;
499                 }
500             }
501
502             if (root[ci].length() < key.length()) {
503                 ci++;
504             }
505
506             if (closed && ci > currentindent) {
507                 continue;
508             }
509
510             if (cy <= y && cy + iRowHeight > y) {
511                 break;
512             }
513
514             root[ci] = key;
515             closed = folder != null && folder.equals("+");
516             currentindent = ci;
517             cy += iRowHeight;
518         }
519
520         if (i >= 0 && i < iRowCount) {
521             String JavaDoc[] s = (String JavaDoc[]) vData.elementAt(i);
522             String JavaDoc folder = s[2];
523
524             if (folder != null && folder.equals("+")) {
525                 folder = "-";
526             } else if (folder != null && folder.equals("-")) {
527                 folder = "+";
528             }
529
530             s[2] = folder;
531
532             vData.setElementAt(s, i);
533             repaint();
534         }
535
536         return true;
537     }
538
539     /**
540      * Method declaration
541      *
542      *
543      * @param f
544      *
545      * @return
546      */

547     private static int getMaxHeight(FontMetrics JavaDoc f) {
548         return f.getHeight() + 2;
549     }
550 }
551
Popular Tags