001: /* Copyright (c) 1995-2000, The Hypersonic SQL Group.
002: * All rights reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * Redistributions of source code must retain the above copyright notice, this
008: * list of conditions and the following disclaimer.
009: *
010: * Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: *
014: * Neither the name of the Hypersonic SQL Group nor the names of its
015: * contributors may be used to endorse or promote products derived from this
016: * software without specific prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
020: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
021: * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,
022: * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
023: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
025: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
026: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
027: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
028: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029: *
030: * This software consists of voluntary contributions made by many individuals
031: * on behalf of the Hypersonic SQL Group.
032: *
033: *
034: * For work added by the HSQL Development Group:
035: *
036: * Copyright (c) 2001-2005, The HSQL Development Group
037: * All rights reserved.
038: *
039: * Redistribution and use in source and binary forms, with or without
040: * modification, are permitted provided that the following conditions are met:
041: *
042: * Redistributions of source code must retain the above copyright notice, this
043: * list of conditions and the following disclaimer.
044: *
045: * Redistributions in binary form must reproduce the above copyright notice,
046: * this list of conditions and the following disclaimer in the documentation
047: * and/or other materials provided with the distribution.
048: *
049: * Neither the name of the HSQL Development Group nor the names of its
050: * contributors may be used to endorse or promote products derived from this
051: * software without specific prior written permission.
052: *
053: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
054: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
055: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
056: * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
057: * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
058: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
059: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
060: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
061: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
062: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
063: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
064: */
065:
066: package org.hsqldb.util;
067:
068: import java.util.Vector;
069: import java.awt.Color;
070: import java.awt.Cursor;
071: import java.awt.Dimension;
072: import java.awt.Event;
073: import java.awt.Font;
074: import java.awt.FontMetrics;
075: import java.awt.Graphics;
076: import java.awt.Image;
077: import java.awt.Panel;
078: import java.awt.Scrollbar;
079: import java.awt.SystemColor;
080:
081: // sqlbob@users 20020401 - patch 1.7.0 by sqlbob (RMP) - enhancements
082:
083: /**
084: *
085: * @author Thomas Mueller (Hypersonic SQL Group)
086: * @version 1.8.0
087: * @since Hypersonic SQL
088: */
089: class Grid extends Panel {
090:
091: // drawing
092: private Dimension dMinimum;
093:
094: // boucherb@users changed access for databasemanager2
095: protected Font fFont;
096:
097: // --------------------------------------------------
098: private FontMetrics fMetrics;
099: private Graphics gImage;
100: private Image iImage;
101:
102: // height / width
103: private int iWidth, iHeight;
104: private int iRowHeight, iFirstRow;
105: private int iGridWidth, iGridHeight;
106: private int iX, iY;
107:
108: // data
109: // boucherb@users changed access for databasemanager2
110: protected String[] sColHead = new String[0];
111: protected Vector vData = new Vector();
112:
113: // --------------------------------------------------
114: private int[] iColWidth;
115: private int iColCount;
116:
117: // boucherb@users changed access for databasemanager2
118: protected int iRowCount;
119:
120: // --------------------------------------------------
121: // scrolling
122: private Scrollbar sbHoriz, sbVert;
123: private int iSbWidth, iSbHeight;
124: private boolean bDrag;
125: private int iXDrag, iColDrag;
126:
127: /**
128: * Constructor declaration
129: *
130: */
131: public Grid() {
132:
133: super ();
134:
135: fFont = new Font("Dialog", Font.PLAIN, 12);
136:
137: setLayout(null);
138:
139: sbHoriz = new Scrollbar(Scrollbar.HORIZONTAL);
140:
141: add(sbHoriz);
142:
143: sbVert = new Scrollbar(Scrollbar.VERTICAL);
144:
145: add(sbVert);
146: }
147:
148: /**
149: * Method declaration
150: *
151: *
152: * @return
153: */
154: String[] getHead() {
155: return sColHead;
156: }
157:
158: /**
159: * Method declaration
160: *
161: *
162: * @return
163: */
164: Vector getData() {
165: return vData;
166: }
167:
168: /**
169: * Method declaration
170: *
171: *
172: * @param d
173: */
174: public void setMinimumSize(Dimension d) {
175: dMinimum = d;
176: }
177:
178: /**
179: * Method declaration
180: *
181: *
182: * @param x
183: * @param y
184: * @param w
185: * @param h
186: */
187: public void setBounds(int x, int y, int w, int h) {
188:
189: // fredt@users 20011210 - patch 450412 by elise@users
190: super .setBounds(x, y, w, h);
191:
192: iSbHeight = sbHoriz.getPreferredSize().height;
193: iSbWidth = sbVert.getPreferredSize().width;
194: iHeight = h - iSbHeight;
195: iWidth = w - iSbWidth;
196:
197: sbHoriz.setBounds(0, iHeight, iWidth, iSbHeight);
198: sbVert.setBounds(iWidth, 0, iSbWidth, iHeight);
199: adjustScroll();
200:
201: iImage = null;
202:
203: repaint();
204: }
205:
206: /**
207: * Method declaration
208: *
209: *
210: * @param head
211: */
212: public void setHead(String[] head) {
213:
214: iColCount = head.length;
215: sColHead = new String[iColCount];
216: iColWidth = new int[iColCount];
217:
218: for (int i = 0; i < iColCount; i++) {
219: sColHead[i] = head[i];
220: iColWidth[i] = 100;
221: }
222:
223: iRowCount = 0;
224: iRowHeight = 0;
225: vData = new Vector();
226: }
227:
228: /**
229: * Method declaration
230: *
231: *
232: * @param data
233: */
234: public void addRow(String[] data) {
235:
236: if (data.length != iColCount) {
237: return;
238: }
239:
240: String[] row = new String[iColCount];
241:
242: for (int i = 0; i < iColCount; i++) {
243: row[i] = data[i];
244:
245: if (row[i] == null) {
246: row[i] = "(null)";
247: }
248: }
249:
250: vData.addElement(row);
251:
252: iRowCount++;
253: }
254:
255: /**
256: * Method declaration
257: *
258: */
259: public void update() {
260: adjustScroll();
261: repaint();
262: }
263:
264: /**
265: * Method declaration
266: *
267: */
268: void adjustScroll() {
269:
270: if (iRowHeight == 0) {
271: return;
272: }
273:
274: int w = 0;
275:
276: for (int i = 0; i < iColCount; i++) {
277: w += iColWidth[i];
278: }
279:
280: iGridWidth = w;
281: iGridHeight = iRowHeight * (iRowCount + 1);
282:
283: sbHoriz.setValues(iX, iWidth, 0, iGridWidth);
284:
285: int v = iY / iRowHeight, h = iHeight / iRowHeight;
286:
287: sbVert.setValues(v, h, 0, iRowCount + 1);
288:
289: iX = sbHoriz.getValue();
290: iY = iRowHeight * sbVert.getValue();
291: }
292:
293: /**
294: * Method declaration
295: *
296: *
297: * @param e
298: *
299: * @return
300: */
301:
302: // fredt@users 20020130 - comment by fredt
303: // to remove this deprecated method we need to rewrite the Grid class as a
304: // ScrollPane component
305: // sqlbob: I believe that changing to the JDK1.1 event handler
306: // would require browsers to use the Java plugin.
307: public boolean handleEvent(Event e) {
308:
309: switch (e.id) {
310:
311: case Event.SCROLL_LINE_UP:
312: case Event.SCROLL_LINE_DOWN:
313: case Event.SCROLL_PAGE_UP:
314: case Event.SCROLL_PAGE_DOWN:
315: case Event.SCROLL_ABSOLUTE:
316: iX = sbHoriz.getValue();
317: iY = iRowHeight * sbVert.getValue();
318:
319: repaint();
320:
321: return true;
322: }
323:
324: return super .handleEvent(e);
325: }
326:
327: /**
328: * Method declaration
329: *
330: *
331: * @param g
332: */
333: public void paint(Graphics g) {
334:
335: if (g == null) {
336: return;
337: }
338:
339: if (sColHead.length == 0) {
340: super .paint(g);
341:
342: return;
343: }
344:
345: if (iWidth <= 0 || iHeight <= 0) {
346: return;
347: }
348:
349: g.setColor(SystemColor.control);
350: g.fillRect(iWidth, iHeight, iSbWidth, iSbHeight);
351:
352: if (iImage == null) {
353: iImage = createImage(iWidth, iHeight);
354: gImage = iImage.getGraphics();
355:
356: gImage.setFont(fFont);
357:
358: if (fMetrics == null) {
359: fMetrics = gImage.getFontMetrics();
360: }
361: }
362:
363: if (iRowHeight == 0) {
364: iRowHeight = getMaxHeight(fMetrics);
365:
366: for (int i = 0; i < iColCount; i++) {
367: calcAutoWidth(i);
368: }
369:
370: adjustScroll();
371: }
372:
373: gImage.setColor(Color.white);
374: gImage.fillRect(0, 0, iWidth, iHeight);
375: gImage.setColor(Color.darkGray);
376: gImage.drawLine(0, iRowHeight, iWidth, iRowHeight);
377:
378: int x = -iX;
379:
380: for (int i = 0; i < iColCount; i++) {
381: int w = iColWidth[i];
382:
383: gImage.setColor(SystemColor.control);
384: gImage.fillRect(x + 1, 0, w - 2, iRowHeight);
385: gImage.setColor(Color.black);
386: gImage.drawString(sColHead[i], x + 2, iRowHeight - 5);
387: gImage.setColor(Color.darkGray);
388: gImage.drawLine(x + w - 1, 0, x + w - 1, iRowHeight - 1);
389: gImage.setColor(Color.white);
390: gImage.drawLine(x + w, 0, x + w, iRowHeight - 1);
391:
392: x += w;
393: }
394:
395: gImage.setColor(SystemColor.control);
396: gImage.fillRect(0, 0, 1, iRowHeight);
397: gImage.fillRect(x + 1, 0, iWidth - x, iRowHeight);
398: gImage.drawLine(0, 0, 0, iRowHeight - 1);
399:
400: int y = iRowHeight + 1 - iY;
401: int j = 0;
402:
403: while (y < iRowHeight + 1) {
404: j++;
405:
406: y += iRowHeight;
407: }
408:
409: iFirstRow = j;
410: y = iRowHeight + 1;
411:
412: for (; y < iHeight && j < iRowCount; j++, y += iRowHeight) {
413: x = -iX;
414:
415: for (int i = 0; i < iColCount; i++) {
416: int w = iColWidth[i];
417: Color b = Color.white, t = Color.black;
418:
419: gImage.setColor(b);
420: gImage.fillRect(x, y, w - 1, iRowHeight - 1);
421: gImage.setColor(t);
422: gImage.drawString(getDisplay(i, j), x + 2, y
423: + iRowHeight - 5);
424: gImage.setColor(Color.lightGray);
425: gImage.drawLine(x + w - 1, y, x + w - 1, y + iRowHeight
426: - 1);
427: gImage.drawLine(x, y + iRowHeight - 1, x + w - 1, y
428: + iRowHeight - 1);
429:
430: x += w;
431: }
432:
433: gImage.setColor(Color.white);
434: gImage.fillRect(x, y, iWidth - x, iRowHeight - 1);
435: }
436:
437: g.drawImage(iImage, 0, 0, this );
438: }
439:
440: /**
441: * Method declaration
442: *
443: *
444: * @param g
445: */
446: public void update(Graphics g) {
447: paint(g);
448: }
449:
450: /**
451: * Method declaration
452: *
453: *
454: * @param e
455: * @param x
456: * @param y
457: *
458: * @return
459: */
460: public boolean mouseMove(Event e, int x, int y) {
461:
462: if (y <= iRowHeight) {
463: int xb = x;
464:
465: x += iX - iGridWidth;
466:
467: int i = iColCount - 1;
468:
469: for (; i >= 0; i--) {
470: if (x > -7 && x < 7) {
471: break;
472: }
473:
474: x += iColWidth[i];
475: }
476:
477: if (i >= 0) {
478: if (!bDrag) {
479: setCursor(new Cursor(Cursor.E_RESIZE_CURSOR));
480:
481: bDrag = true;
482: iXDrag = xb - iColWidth[i];
483: iColDrag = i;
484: }
485:
486: return true;
487: }
488: }
489:
490: return mouseExit(e, x, y);
491: }
492:
493: /**
494: * Method declaration
495: *
496: *
497: * @param e
498: * @param x
499: * @param y
500: *
501: * @return
502: */
503: public boolean mouseDrag(Event e, int x, int y) {
504:
505: if (bDrag && x < iWidth) {
506: int w = x - iXDrag;
507:
508: if (w < 0) {
509: w = 0;
510: }
511:
512: iColWidth[iColDrag] = w;
513:
514: adjustScroll();
515: repaint();
516: }
517:
518: return true;
519: }
520:
521: /**
522: * Method declaration
523: *
524: *
525: * @param e
526: * @param x
527: * @param y
528: *
529: * @return
530: */
531: public boolean mouseExit(Event e, int x, int y) {
532:
533: if (bDrag) {
534: setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
535:
536: bDrag = false;
537: }
538:
539: return true;
540: }
541:
542: /**
543: * Method declaration
544: *
545: *
546: * @return
547: */
548: public Dimension preferredSize() {
549: return dMinimum;
550: }
551:
552: /**
553: * Method declaration
554: *
555: *
556: * @return
557: */
558: public Dimension getPreferredSize() {
559: return dMinimum;
560: }
561:
562: /**
563: * Method declaration
564: *
565: *
566: * @return
567: */
568: public Dimension getMinimumSize() {
569: return dMinimum;
570: }
571:
572: /**
573: * Method declaration
574: *
575: *
576: * @return
577: */
578: public Dimension minimumSize() {
579: return dMinimum;
580: }
581:
582: /**
583: * Method declaration
584: *
585: *
586: * @param i
587: */
588: private void calcAutoWidth(int i) {
589:
590: int w = 10;
591:
592: w = Math.max(w, fMetrics.stringWidth(sColHead[i]));
593:
594: for (int j = 0; j < iRowCount; j++) {
595: String[] s = (String[]) (vData.elementAt(j));
596:
597: w = Math.max(w, fMetrics.stringWidth(s[i]));
598: }
599:
600: iColWidth[i] = w + 6;
601: }
602:
603: /**
604: * Method declaration
605: *
606: *
607: * @param x
608: * @param y
609: *
610: * @return
611: */
612: private String getDisplay(int x, int y) {
613: return (((String[]) (vData.elementAt(y)))[x]);
614: }
615:
616: /**
617: * Method declaration
618: *
619: *
620: * @param x
621: * @param y
622: *
623: * @return
624: */
625: private String get(int x, int y) {
626: return (((String[]) (vData.elementAt(y)))[x]);
627: }
628:
629: /**
630: * Method declaration
631: *
632: *
633: * @param f
634: *
635: * @return
636: */
637: private static int getMaxHeight(FontMetrics f) {
638: return f.getHeight() + 4;
639: }
640: }
|