001: /*
002: * TableDependencyTreeDisplay.java
003: *
004: * This file is part of SQL Workbench/J, http://www.sql-workbench.net
005: *
006: * Copyright 2002-2008, Thomas Kellerer
007: * No part of this code maybe reused without the permission of the author
008: *
009: * To contact the author please send an email to: support@sql-workbench.net
010: *
011: */
012: package workbench.gui.dbobjects;
013:
014: import java.awt.BorderLayout;
015: import java.util.ArrayList;
016: import java.util.Iterator;
017: import java.util.List;
018: import java.util.Map;
019: import java.util.Map.Entry;
020:
021: import javax.swing.JPanel;
022: import javax.swing.JTree;
023: import javax.swing.ToolTipManager;
024: import javax.swing.tree.DefaultMutableTreeNode;
025: import javax.swing.tree.TreeNode;
026: import javax.swing.tree.TreePath;
027: import workbench.WbManager;
028:
029: import workbench.db.DependencyNode;
030: import workbench.db.TableDependency;
031: import workbench.db.TableIdentifier;
032: import workbench.db.WbConnection;
033: import workbench.gui.WbSwingUtilities;
034: import workbench.gui.components.WbScrollPane;
035: import workbench.gui.renderer.DependencyTreeCellRenderer;
036: import workbench.interfaces.Resettable;
037: import workbench.log.LogMgr;
038:
039: /**
040: *
041: * @author support@sql-workbench.net
042: */
043: public class TableDependencyTreeDisplay extends JPanel implements
044: Resettable {
045: private WbConnection connection;
046: private DependencyTreeCellRenderer renderer;
047: private ArrayList<TreeNode[]> nodesToExpand;
048: private boolean showExported;
049:
050: public TableDependencyTreeDisplay() {
051: this .setLayout(new BorderLayout());
052: }
053:
054: public void setConnection(WbConnection aConn) {
055: this .connection = aConn;
056: }
057:
058: public void readReferencedTables(TableIdentifier table) {
059: if (table == null)
060: return;
061: readTree(table, true);
062: }
063:
064: public void readReferencingTables(TableIdentifier table) {
065: if (table == null)
066: return;
067: readTree(table, false);
068: }
069:
070: private void readTree(TableIdentifier aTable, boolean exportedKeys) {
071: this .renderer = new DependencyTreeCellRenderer();
072: this .showExported = exportedKeys;
073: try {
074: WbSwingUtilities.showWaitCursor(this );
075: TableDependency dep = new TableDependency(this .connection,
076: aTable);
077: if (exportedKeys) {
078: dep.readTreeForParents();
079: } else {
080: dep.readTreeForChildren();
081: }
082:
083: DependencyNode root = dep.getRootNode();
084: this .readTreeNodes(root);
085: } catch (OutOfMemoryError mem) {
086: WbManager.getInstance().showOutOfMemoryError();
087: } catch (Exception e) {
088: LogMgr.logError("TableDependencyTreeDisplay.readTree()",
089: "Error reading three", e);
090: }
091: WbSwingUtilities.showDefaultCursor(this );
092: }
093:
094: public void reset() {
095: this .removeAll();//this.createTreeDisplay(emptyRoot);
096: this .invalidate();
097: this .repaint();
098: this .doLayout();
099: }
100:
101: private void createTreeDisplay(DefaultMutableTreeNode root) {
102: this .removeAll();
103: this .invalidate();
104: JTree tree = new JTree(root);
105: ToolTipManager.sharedInstance().registerComponent(tree);
106: tree.putClientProperty("JTree.lineStyle", "Angled");
107: tree.setCellRenderer(this .renderer);
108: WbScrollPane scroll = new WbScrollPane(tree);
109: this .expandNodes(tree);
110: this .add(scroll, BorderLayout.CENTER);
111: this .updateUI();
112: this .repaint();
113: }
114:
115: private void readTreeNodes(DependencyNode root) {
116: DefaultMutableTreeNode treeRoot = null;
117: if (root.getChildren().size() > 0) {
118: treeRoot = new DefaultMutableTreeNode(root, true);
119: this .buildTree(root, treeRoot);
120: this .createTreeDisplay(treeRoot);
121: } else {
122: this .reset();
123: }
124: }
125:
126: private void buildTree(DependencyNode parent,
127: DefaultMutableTreeNode treeParent) {
128: String parenttable = parent.getTable().getTableName();
129:
130: DependencyNode child = null;
131: DefaultMutableTreeNode treeNode = null;
132: String table = null;
133:
134: List children = parent.getChildren();
135: int count = children.size();
136: for (int i = 0; i < count; i++) {
137: child = (DependencyNode) children.get(i);
138:
139: treeNode = new DefaultMutableTreeNode(child, true);
140: treeNode.setAllowsChildren(true);
141: treeParent.add(treeNode);
142:
143: int childrenCount = child.getChildren().size();
144:
145: Map columns = child.getColumns();
146: Iterator entries = columns.entrySet().iterator();
147: while (entries.hasNext()) {
148: table = child.getTable().getTableName();
149: Entry entry = (Entry) entries.next();
150: StringBuilder coldef = new StringBuilder(100);
151: coldef.append("<html><b>");
152: if (this .showExported) {
153: coldef.append(parenttable);
154: coldef.append('.');
155: coldef.append(entry.getValue());
156: } else {
157: coldef.append(table);
158: coldef.append('.');
159: coldef.append(entry.getKey());
160: }
161: coldef.append("</b> REFERENCES <b>");
162: if (this .showExported) {
163: coldef.append(table);
164: coldef.append('.');
165: coldef.append(entry.getKey());
166: } else {
167: coldef.append(parenttable);
168: coldef.append('.');
169: coldef.append(entry.getValue());
170: }
171: coldef.append("</b></html>");
172: DefaultMutableTreeNode colnode = new DefaultMutableTreeNode(
173: coldef.toString());
174: colnode.setAllowsChildren(false);
175: treeNode.add(colnode);
176: }
177:
178: if (childrenCount > 0) {
179: this .buildTree(child, treeNode);
180: TreeNode[] path = treeNode.getPath();
181: if (this .nodesToExpand == null)
182: this .nodesToExpand = new ArrayList<TreeNode[]>();
183: this .nodesToExpand.add(path);
184: }
185: }
186: }
187:
188: private void expandNodes(JTree tree) {
189: if (this .nodesToExpand == null)
190: return;
191: for (TreeNode[] nodes : nodesToExpand) {
192: TreePath path = new TreePath(nodes);
193: tree.expandPath(path);
194: }
195: this.nodesToExpand.clear();
196: this.nodesToExpand = null;
197: }
198:
199: }
|