001: /*
002: * Gruntspud Copyright (C) 2002 Brett Smith. Written by: Brett Smith
003: * <t_magicthize@users.sourceforge.net> This program is free software; you can
004: * redistribute it and/or modify it under the terms of the GNU Library General
005: * Public License as published by the Free Software Foundation; either version
006: * 2 of the License, or (at your option) any later version. This program is
007: * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
008: * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
009: * PARTICULAR PURPOSE. See the GNU Library General Public License for more
010: * details. You should have received a copy of the GNU Library General Public
011: * License along with this program; if not, write to the Free Software
012: * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
013: */
014:
015: package gruntspud.ui.view;
016:
017: import gruntspud.CVSFileNode;
018: import gruntspud.Constants;
019: import gruntspud.GruntspudContext;
020: import gruntspud.ui.FileNameTextField;
021:
022: import java.awt.AWTEvent;
023: import java.awt.Rectangle;
024: import java.util.Collections;
025: import java.util.Vector;
026:
027: import javax.swing.Icon;
028: import javax.swing.JTree;
029: import javax.swing.ToolTipManager;
030: import javax.swing.plaf.TreeUI;
031: import javax.swing.plaf.basic.BasicTreeUI;
032: import javax.swing.tree.DefaultTreeModel;
033: import javax.swing.tree.TreeCellRenderer;
034: import javax.swing.tree.TreePath;
035: import javax.swing.tree.TreeSelectionModel;
036:
037: import com.sun.java.swing.plaf.windows.WindowsTreeUI;
038: import com.sun.java.swing.plaf.windows.WindowsTreeUI.WindowsTreeCellRenderer;
039:
040: /**
041: * Description of the Class
042: *
043: * @author magicthize @created 26 May 2002
044: */
045: public class CVSFileNodeTree extends JTree {
046:
047: private GruntspudContext context;
048:
049: /**
050: * Constructor for the CVSFileNodeTree object
051: */
052: public CVSFileNodeTree(CVSFileNode root, String textMask,
053: GruntspudContext context) {
054: super (new FilteredTreeModel(root));
055: this .context = context;
056:
057: //
058: setShowsRootHandles(true);
059: setTreeStyle();
060: setCellRenderer(new CVSFileNodeTreeCellRenderer(context));
061: FileNameTextField.setFocusable(this , true);
062: setAutoscrolls(false);
063: setExpandsSelectedPaths(true);
064: setRowHeight(16);
065: ToolTipManager.sharedInstance().registerComponent(this );
066: getSelectionModel().setSelectionMode(
067: TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
068:
069: enableEvents(AWTEvent.KEY_EVENT_MASK);
070:
071: setHideFileNodes(context.getHost().getBooleanProperty(
072: Constants.OPTIONS_DISPLAY_HIDE_FILES_IN_TREE, false));
073: ((CVSFileNodeTreeCellRenderer) getCellRenderer())
074: .setShowSubstTypes(context
075: .getHost()
076: .getBooleanProperty(
077: Constants.OPTIONS_DISPLAY_SUBST_TYPES_IN_TREE,
078: true));
079: ;
080: ((CVSFileNodeTreeCellRenderer) getCellRenderer())
081: .setHighlight(context
082: .getHost()
083: .getBooleanProperty(
084: Constants.OPTIONS_DISPLAY_HIGHLIGHT_READ_ONLY_AND_MISSING_FILES,
085: true));
086: ((CVSFileNodeTreeCellRenderer) getCellRenderer())
087: .setTextMask(textMask);
088: String lineStyle = context.getHost().getProperty(
089: Constants.OPTIONS_DISPLAY_EXPLORER_LINE_STYLE, "None");
090: Constants.UI_LOG.debug("Line style is " + lineStyle);
091: putClientProperty("JTree.lineStyle", lineStyle);
092: }
093:
094: private void setTreeStyle() {
095: Icon expanded = context.getHost().getIcon(
096: Constants.ICON_TOOL_SMALL_DEFAULT_TREE_EXPANDED);
097: Icon collapsed = context.getHost().getIcon(
098: Constants.ICON_TOOL_SMALL_DEFAULT_TREE_COLLAPSED);
099: if (expanded != null && collapsed != null) {
100: javax.swing.plaf.ComponentUI treeUI = getUI();
101: if (treeUI instanceof javax.swing.plaf.basic.BasicTreeUI) {
102: ((javax.swing.plaf.basic.BasicTreeUI) treeUI)
103: .setExpandedIcon(expanded);
104: ((javax.swing.plaf.basic.BasicTreeUI) treeUI)
105: .setCollapsedIcon(collapsed);
106: ((javax.swing.plaf.basic.BasicTreeUI) treeUI)
107: .setLeftChildIndent(6);
108: ((javax.swing.plaf.basic.BasicTreeUI) treeUI)
109: .setRightChildIndent(8);
110: }
111: }
112: }
113:
114: public void updateUI() {
115: super .updateUI();
116: if (context != null) {
117: setTreeStyle();
118: }
119: }
120:
121: /**
122: * DOCUMENT ME!
123: *
124: * @return DOCUMENT ME!
125: */
126: public boolean isHideFileNodes() {
127: return ((FilteredTreeModel) getModel()).isHideFileNodes();
128: }
129:
130: /**
131: * DOCUMENT ME!
132: *
133: * @param hideFileNodes
134: * DOCUMENT ME!
135: */
136: public void setHideFileNodes(boolean hideFileNodes) {
137: ((FilteredTreeModel) getModel())
138: .setHideFileNodes(hideFileNodes);
139: }
140:
141: /**
142: * Gets the selectedFileNode attribute of the CVSFileNodeTree object
143: *
144: * @return The selectedFileNode value
145: */
146: public CVSFileNode getSelectedFileNode() {
147: return (CVSFileNode) getLastSelectedPathComponent();
148: }
149:
150: /**
151: * Gets the selectedFileNodes attribute of the CVSFileNodeTree object
152: *
153: * @return The selectedFileNodes value
154: */
155: public CVSFileNode[] getSelectedFileNodes() {
156: TreePath[] p = getSelectionPaths();
157:
158: if (p == null) {
159: return null;
160: }
161:
162: Vector v = new Vector();
163: CVSFileNode[] n = new CVSFileNode[p.length];
164:
165: for (int i = 0; i < p.length; i++) {
166: v.addElement(p[i].getLastPathComponent());
167:
168: }
169: Collections.sort(v);
170: v.copyInto(n);
171:
172: return n;
173: }
174:
175: /**
176: * Sets the selectedFileNode attribute of the CVSFileNodeTree object
177: *
178: * @param node
179: * The new selectedFileNode value
180: */
181: public void setSelectedFileNode(CVSFileNode node) {
182: setSelectedFileNodes((node == null) ? null
183: : new CVSFileNode[] { node });
184: }
185:
186: /**
187: * Sets the selectedFileNodes attribute of the CVSFileNodeTree object
188: *
189: * @param node
190: * The new selectedFileNodes value
191: */
192: public void setSelectedFileNodes(CVSFileNode[] node) {
193: clearSelection();
194: if (node != null) {
195: Vector v = new Vector();
196: for (int i = 0; i < node.length; i++) {
197: if (node[i] != null) {
198: TreePath t = new TreePath(
199: ((DefaultTreeModel) getModel())
200: .getPathToRoot(node[i]));
201: v.addElement(t);
202: }
203: }
204: TreePath[] pa = new TreePath[v.size()];
205: v.copyInto(pa);
206: if (pa.length > 0) {
207: setSelectionPaths(pa);
208: scrollPathToVisible(pa[0]);
209: }
210: }
211: }
212:
213: public void setUI(TreeUI ui) {
214: if (ui.getClass().getName().equals(
215: "com.sun.java.swing.plaf.windows.WindowsTreeUI")
216: && System.getProperty("java.version").equals("1.4.2")) {
217:
218: ui = new FixedWindowsTreeUI();
219: }
220: super .setUI(ui);
221: }
222:
223: private static class FixedWindowsTreeUI extends BasicTreeUI {
224:
225: protected void ensureRowsAreVisible(int beginRow, int endRow) {
226: if (tree != null && beginRow >= 0
227: && endRow < getRowCount(tree)) {
228: Rectangle visRect = tree.getVisibleRect();
229: if (beginRow == endRow) {
230: Rectangle scrollBounds = getPathBounds(tree,
231: getPathForRow(tree, beginRow));
232:
233: if (scrollBounds != null) {
234: scrollBounds.x = visRect.x;
235: scrollBounds.width = visRect.width;
236: tree.scrollRectToVisible(scrollBounds);
237: }
238: } else {
239: Rectangle beginRect = getPathBounds(tree,
240: getPathForRow(tree, beginRow));
241: Rectangle testRect = beginRect;
242: int beginY = beginRect.y;
243: int maxY = beginY + visRect.height;
244:
245: for (int counter = beginRow + 1; counter <= endRow; counter++) {
246: testRect = getPathBounds(tree, getPathForRow(
247: tree, counter));
248: if ((testRect.y + testRect.height) > maxY)
249: counter = endRow;
250: }
251: tree.scrollRectToVisible(new Rectangle(visRect.x,
252: beginY, 1, testRect.y + testRect.height
253: - beginY));
254: }
255: }
256: }
257:
258: protected TreeCellRenderer createDefaultCellRenderer() {
259: return new WindowsTreeUI().new WindowsTreeCellRenderer();
260: }
261:
262: }
263: }
|