/*
 * For work developed by the HSQL Development Group:
 *
 * Copyright (c) 2001-2019, The HSQL Development Group
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * Neither the name of the HSQL Development Group nor the names of its
 * contributors may be used to endorse or promote products derived from this
 * software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *
 *
 * For work originally developed by the Hypersonic SQL Group:
 *
 * Copyright (c) 1995-2000, The Hypersonic SQL Group.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * Neither the name of the Hypersonic SQL Group nor the names of its
 * contributors may be used to endorse or promote products derived from this
 * software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * This software consists of voluntary contributions made by many individuals
 * on behalf of the Hypersonic SQL Group.
 */


package org.hsqldb.util;

import java.util.Vector;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Event;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Panel;
import java.awt.Scrollbar;
import java.awt.SystemColor;
import java.awt.Toolkit;

Author:Thomas Mueller (Hypersonic SQL Group)
Version:1.7.0
Since:Hypersonic SQL
/** * * @author Thomas Mueller (Hypersonic SQL Group) * @version 1.7.0 * @since Hypersonic SQL */
class Tree extends Panel { // static private static Font fFont; private static FontMetrics fMetrics; private static int iRowHeight; private static int iIndentWidth; private int iMaxTextLength; // drawing private Dimension dMinimum; private Graphics gImage; private Image iImage; // height / width private int iWidth, iHeight; private int iFirstRow; private int iTreeWidth, iTreeHeight; private int iX, iY; // data private Vector vData; private int iRowCount; // scrolling private Scrollbar sbHoriz, sbVert; private int iSbWidth, iSbHeight; static { fFont = new Font("Dialog", Font.PLAIN, 12); fMetrics = Toolkit.getDefaultToolkit().getFontMetrics(fFont); iRowHeight = getMaxHeight(fMetrics); iIndentWidth = 12; }
Constructor declaration
/** * Constructor declaration * */
Tree() { super(); vData = new Vector(); setLayout(null); sbHoriz = new Scrollbar(Scrollbar.HORIZONTAL); add(sbHoriz); sbVert = new Scrollbar(Scrollbar.VERTICAL); add(sbVert); }
Method declaration
Params:
  • d –
/** * Method declaration * * * @param d */
public void setMinimumSize(Dimension d) { dMinimum = d; }
Method declaration
Params:
  • x –
  • y –
  • w –
  • h –
/** * Method declaration * * * @param x * @param y * @param w * @param h */
// fredt@users 20011210 - patch 450412 by elise@users // with additional replacement of deprecated methods public void setBounds(int x, int y, int w, int h) { super.setBounds(x, y, w, h); iSbHeight = sbHoriz.getPreferredSize().height; iSbWidth = sbVert.getPreferredSize().width; iHeight = h - iSbHeight; iWidth = w - iSbWidth; sbHoriz.setBounds(0, iHeight, iWidth, iSbHeight); sbVert.setBounds(iWidth, 0, iSbWidth, iHeight); adjustScroll(); iImage = null; repaint(); }
Method declaration
/** * Method declaration * */
public void removeAll() { vData = new Vector(); iRowCount = 0; adjustScroll(); iMaxTextLength = 10; repaint(); }
Method declaration
Params:
  • key –
  • value –
  • state –
  • color –
/** * Method declaration * * * @param key * @param value * @param state * @param color */
public void addRow(String key, String value, String state, int color) { String[] row = new String[4]; if (value == null) { value = ""; } row[0] = key; row[1] = value; row[2] = state; // null / "-" / "+" row[3] = String.valueOf(color); vData.addElement(row); int len = fMetrics.stringWidth(value); if (len > iMaxTextLength) { iMaxTextLength = len; } iRowCount++; }
Method declaration
Params:
  • key –
  • value –
/** * Method declaration * * * @param key * @param value */
public void addRow(String key, String value) { addRow(key, value, null, 0); }
Method declaration
/** * Method declaration * */
public void update() { adjustScroll(); repaint(); }
Method declaration
/** * Method declaration * */
void adjustScroll() { iTreeHeight = iRowHeight * (iRowCount + 1); // correct would be iMaxTextLength + iMaxIndent*iIndentWidth iTreeWidth = iMaxTextLength * 2; sbHoriz.setValues(iX, iWidth, 0, iTreeWidth); int v = iY / iRowHeight, h = iHeight / iRowHeight; sbVert.setValues(v, h, 0, iRowCount + 1); iX = sbHoriz.getValue(); iY = iRowHeight * sbVert.getValue(); }
Method declaration
Params:
  • e –
/** * Method declaration * * * @param e */
// fredt@users 20020130 - comment by fredt // to remove this deprecated method we need to rewrite the Tree class as a // ScrollPane component public boolean handleEvent(Event e) { switch (e.id) { case Event.SCROLL_LINE_UP : case Event.SCROLL_LINE_DOWN : case Event.SCROLL_PAGE_UP : case Event.SCROLL_PAGE_DOWN : case Event.SCROLL_ABSOLUTE : iX = sbHoriz.getValue(); iY = iRowHeight * sbVert.getValue(); repaint(); return true; } return super.handleEvent(e); }
Method declaration
Params:
  • g –
/** * Method declaration * * * @param g */
public void paint(Graphics g) { if (g == null || iWidth <= 0 || iHeight <= 0) { return; } g.setColor(SystemColor.control); g.fillRect(iWidth, iHeight, iSbWidth, iSbHeight); if (iImage == null) { iImage = createImage(iWidth, iHeight); gImage = iImage.getGraphics(); gImage.setFont(fFont); } gImage.setColor(Color.white); gImage.fillRect(0, 0, iWidth, iHeight); int[] lasty = new int[100]; String[] root = new String[100]; root[0] = ""; int currentindent = 0; int y = iRowHeight; y -= iY; boolean closed = false; for (int i = 0; i < iRowCount; i++) { String[] s = (String[]) vData.elementAt(i); String key = s[0]; String data = s[1]; String folder = s[2]; int ci = currentindent; for (; ci > 0; ci--) { if (key.startsWith(root[ci])) { break; } } if (root[ci].length() < key.length()) { ci++; } if (closed && ci > currentindent) { continue; } closed = folder != null && folder.equals("+"); root[ci] = key; int x = iIndentWidth * ci - iX; gImage.setColor(Color.lightGray); gImage.drawLine(x, y, x + iIndentWidth, y); gImage.drawLine(x, y, x, lasty[ci]); lasty[ci + 1] = y; int py = y + iRowHeight / 3; int px = x + iIndentWidth * 2; if (folder != null) { lasty[ci + 1] += 4; int rgb = Integer.parseInt(s[3]); gImage.setColor(rgb == 0 ? Color.white : new Color(rgb)); gImage.fillRect(x + iIndentWidth - 3, y - 3, 7, 7); gImage.setColor(Color.black); gImage.drawRect(x + iIndentWidth - 4, y - 4, 8, 8); gImage.drawLine(x + iIndentWidth - 2, y, x + iIndentWidth + 2, y); if (folder.equals("+")) { gImage.drawLine(x + iIndentWidth, y - 2, x + iIndentWidth, y + 2); } } else { px -= iIndentWidth; } gImage.setColor(Color.black); gImage.drawString(data, px, py); currentindent = ci; y += iRowHeight; } g.drawImage(iImage, 0, 0, this); }
Method declaration
Params:
  • g –
/** * Method declaration * * * @param g */
public void update(Graphics g) { paint(g); }
Method declaration
/** * Method declaration */
public Dimension preferredSize() { return dMinimum; }
Method declaration
/** * Method declaration */
public Dimension getPreferredSize() { return dMinimum; }
Method declaration
/** * Method declaration */
public Dimension getMinimumSize() { return dMinimum; }
Method declaration
/** * Method declaration */
public Dimension minimumSize() { return dMinimum; }
Method declaration
Params:
  • e –
  • x –
  • y –
/** * Method declaration * * * @param e * @param x * @param y */
public boolean mouseDown(Event e, int x, int y) { if (iRowHeight == 0 || x > iWidth || y > iHeight) { return true; } y += iRowHeight / 2; String[] root = new String[100]; root[0] = ""; int currentindent = 0; int cy = iRowHeight; boolean closed = false; int i = 0; y += iY; for (; i < iRowCount; i++) { String[] s = (String[]) vData.elementAt(i); String key = s[0]; String folder = s[2]; int ci = currentindent; for (; ci > 0; ci--) { if (key.startsWith(root[ci])) { break; } } if (root[ci].length() < key.length()) { ci++; } if (closed && ci > currentindent) { continue; } if (cy <= y && cy + iRowHeight > y) { break; } root[ci] = key; closed = folder != null && folder.equals("+"); currentindent = ci; cy += iRowHeight; } if (i >= 0 && i < iRowCount) { String[] s = (String[]) vData.elementAt(i); String folder = s[2]; if (folder != null && folder.equals("+")) { folder = "-"; } else if (folder != null && folder.equals("-")) { folder = "+"; } s[2] = folder; vData.setElementAt(s, i); repaint(); } return true; }
Method declaration
Params:
  • f –
/** * Method declaration * * * @param f */
private static int getMaxHeight(FontMetrics f) { return f.getHeight() + 2; } }