KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > opencms > util > ant > CmsAntTaskSelectionTreeDialog


1 /*
2  * File : $Source: /usr/local/cvs/opencms/src-components/org/opencms/util/ant/CmsAntTaskSelectionTreeDialog.java,v $
3  * Date : $Date: 2006/03/27 14:53:01 $
4  * Version: $Revision: 1.3 $
5  *
6  * This library is part of OpenCms -
7  * the Open Source Content Mananagement System
8  *
9  * Copyright (c) 2005 Alkacon Software GmbH (http://www.alkacon.com)
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * Lesser General Public License for more details.
20  *
21  * For further information about Alkacon Software GmbH, please see the
22  * company website: http://www.alkacon.com
23  *
24  * For further information about OpenCms, please see the
25  * project website: http://www.opencms.org
26  *
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30  */

31
32 package org.opencms.util.ant;
33
34 import java.awt.BorderLayout JavaDoc;
35 import java.awt.Container JavaDoc;
36 import java.awt.Dimension JavaDoc;
37 import java.awt.GridLayout JavaDoc;
38 import java.awt.Toolkit JavaDoc;
39 import java.awt.event.ActionEvent JavaDoc;
40 import java.awt.event.ActionListener JavaDoc;
41 import java.awt.event.WindowAdapter JavaDoc;
42 import java.awt.event.WindowEvent JavaDoc;
43 import java.util.Enumeration JavaDoc;
44 import java.util.Iterator JavaDoc;
45 import java.util.LinkedList JavaDoc;
46 import java.util.List JavaDoc;
47 import java.util.StringTokenizer JavaDoc;
48
49 import javax.swing.BorderFactory JavaDoc;
50 import javax.swing.BoxLayout JavaDoc;
51 import javax.swing.JButton JavaDoc;
52 import javax.swing.JDialog JavaDoc;
53 import javax.swing.JFrame JavaDoc;
54 import javax.swing.JLabel JavaDoc;
55 import javax.swing.JPanel JavaDoc;
56 import javax.swing.JScrollPane JavaDoc;
57 import javax.swing.JTree JavaDoc;
58 import javax.swing.border.Border JavaDoc;
59 import javax.swing.tree.DefaultMutableTreeNode JavaDoc;
60 import javax.swing.tree.DefaultTreeModel JavaDoc;
61 import javax.swing.tree.TreeModel JavaDoc;
62 import javax.swing.tree.TreeNode JavaDoc;
63 import javax.swing.tree.TreePath JavaDoc;
64
65 /**
66  * This is a highly configurable Swing GUI dialog for selection.
67  * <p>
68  *
69  * @author Michael Moossen (original non-tree version)
70  * @author Achim Westermann (modified tree version)
71  *
72  * @version $Revision: 1.3 $
73  *
74  * @since 6.1.6
75  *
76  * @see CmsAntTaskSelectionPrompt
77  */

78 public class CmsAntTaskSelectionTreeDialog extends JDialog JavaDoc implements ActionListener JavaDoc {
79
80     /** Constant for border width. */
81     private static final int C_BORDER_SIZE = 10;
82
83     /** Serial version UID required for safe serialization. */
84     private static final long serialVersionUID = -8439685952987222098L;
85
86     /** Aborted flag. */
87     protected boolean m_aborted = false;
88
89     /** The list of all module names. * */
90     private List JavaDoc m_allModuleList;
91
92     /** Border. */
93     private final Border JavaDoc m_border = BorderFactory.createEmptyBorder(C_BORDER_SIZE, C_BORDER_SIZE, 0, C_BORDER_SIZE);
94
95     /** Panel for buttons. */
96     private final JPanel JavaDoc m_buttons = new JPanel JavaDoc();
97
98     /** Cancel button. */
99     private final JButton JavaDoc m_cancel = new JButton JavaDoc("Cancel");
100
101     /** Main Panel. */
102     private final JPanel JavaDoc m_content = new JPanel JavaDoc();
103
104     /** Label for prompt. */
105     private JLabel JavaDoc m_label = null;
106
107     /** Ok button. */
108     private final JButton JavaDoc m_ok = new JButton JavaDoc("Ok");
109
110     /** Associated ant task. */
111     private final CmsAntTaskSelectionTreePrompt m_promptTask;
112
113     /** Select all button. */
114     private final JButton JavaDoc m_selAll = new JButton JavaDoc("All");
115
116     /** Select none button. */
117     private final JButton JavaDoc m_selNone = new JButton JavaDoc("None");
118
119     /** The tree for selection of sets of modudles. . */
120     private JTree JavaDoc m_tree;
121
122     /**
123      * Default Constructor.
124      * <p>
125      *
126      * @param promptTask the <code>{@link CmsAntTaskSelectionPrompt}</code> object.
127      * <p>
128      */

129     public CmsAntTaskSelectionTreeDialog(CmsAntTaskSelectionTreePrompt promptTask) {
130
131         super((JFrame JavaDoc)null, promptTask.getTitle(), true);
132         m_promptTask = promptTask;
133
134         m_label = new JLabel JavaDoc(m_promptTask.getPrompt());
135
136         addWindowListener(new WindowAdapter JavaDoc() {
137
138             public void windowClosed(WindowEvent JavaDoc e) {
139
140                 setVisible(false);
141             }
142         });
143
144         getRootPane().setDefaultButton(m_ok);
145         Container JavaDoc contentPane = getContentPane();
146         contentPane.setLayout(new BoxLayout JavaDoc(contentPane, BoxLayout.Y_AXIS));
147
148         m_label.setBorder(m_border);
149         if (!m_promptTask.isSingleSelection()) {
150             JPanel JavaDoc p1 = new JPanel JavaDoc();
151             p1.add(new JLabel JavaDoc("Select: "));
152             m_selAll.addActionListener(this);
153             p1.add(m_selAll);
154             m_selNone.addActionListener(this);
155             p1.add(m_selNone);
156             JPanel JavaDoc p = new JPanel JavaDoc(new BorderLayout JavaDoc());
157             p.add(m_label, BorderLayout.NORTH);
158             p.add(p1, BorderLayout.SOUTH);
159             contentPane.add(p);
160         } else {
161             getContentPane().add(m_label);
162         }
163
164         JScrollPane JavaDoc scrollpane = new JScrollPane JavaDoc(m_content);
165         scrollpane.setBorder(m_border);
166
167         scrollpane.setPreferredSize(new Dimension JavaDoc(300, 800));
168         // parse the String-list to a clean list as it is not only used for tree-creation but for
169
// tree-selection determination too:
170
this.parseModuleList();
171         TreeModel JavaDoc treeModel = createTree();
172         m_tree = new SelectionTree();
173         m_tree.setModel(treeModel);
174         m_tree.setRootVisible(false);
175         m_tree.setShowsRootHandles(true);
176         expandTree(new TreePath JavaDoc(treeModel.getRoot()));
177         selectDefaultNodes((DefaultMutableTreeNode JavaDoc)treeModel.getRoot(), "", new TreePath JavaDoc(treeModel.getRoot()));
178
179         // layout: let the tree start in upper left edge instead of being centered within the pane
180
// - it would start to move as it expands and changes bounds.
181
m_content.setLayout(new GridLayout JavaDoc(1, 1));
182         m_content.add(m_tree);
183         m_content.setBorder(BorderFactory.createLoweredBevelBorder());
184
185         contentPane.add(scrollpane);
186
187         m_buttons.setBorder(BorderFactory.createEmptyBorder(
188             C_BORDER_SIZE,
189             C_BORDER_SIZE,
190             C_BORDER_SIZE / 2,
191             C_BORDER_SIZE));
192         m_ok.addActionListener(this);
193         m_buttons.add(m_ok);
194         m_cancel.addActionListener(this);
195         m_buttons.add(m_cancel);
196         getContentPane().add(m_buttons, BorderLayout.SOUTH);
197
198         pack();
199     }
200
201     /**
202      * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
203      */

204     public void actionPerformed(ActionEvent JavaDoc e) {
205
206         Object JavaDoc source = e.getSource();
207         if (source == m_ok) {
208             m_aborted = false;
209             setVisible(false);
210         } else if (source == m_cancel) {
211             m_aborted = true;
212             setVisible(false);
213         } else if (source == m_selAll) {
214             m_tree.setSelectionPath(new TreePath JavaDoc(m_tree.getModel().getRoot()));
215         } else if (source == m_selNone) {
216             m_tree.clearSelection();
217         }
218         m_tree.invalidate();
219         // m_tree.cancelEditing();
220
m_tree.repaint();
221     }
222
223     /**
224      * Returns <code>null</code> if the dialog was canceled, or a list of selected items if not.
225      * <p>
226      *
227      * @return the user selection
228      */

229     public String JavaDoc getSelection() {
230
231         center();
232         setVisible(true);
233
234         // Ret is the complete String with all modules separated by ... look at that constant
235
StringBuffer JavaDoc ret = new StringBuffer JavaDoc();
236         // TODO query the selected paths for all subnodes.
237
TreePath JavaDoc[] pathArr = m_tree.getSelectionPaths();
238         // avoid NPE but skip loop:
239
if (pathArr == null) {
240             pathArr = new TreePath JavaDoc[0];
241         }
242         TreePath JavaDoc path;
243         StringBuffer JavaDoc pathString;
244         DefaultMutableTreeNode JavaDoc node;
245
246         // pathString is the path string of the selected TreePath from the tree.
247
// it may be a leaf (single selection) or not. In the latter case iteration
248
// continues to all subnodes to add all reachable leafs as module names.
249
// Furthermore every non-leaf-node may be a module name like: org.opencms.workplace and
250
// org.opencms.workplace.tools.content...
251
for (int i = 0; i < pathArr.length; i++) {
252             pathString = new StringBuffer JavaDoc();
253             path = pathArr[i];
254             // build the path string to the selected path:
255
Object JavaDoc[] entries = path.getPath();
256             // skip "root"
257
for (int j = 1; j < entries.length; j++) {
258                 pathString.append(entries[j]);
259                 if (j < entries.length - 1) {
260                     pathString.append(".");
261                 }
262             }
263             node = (DefaultMutableTreeNode JavaDoc)path.getLastPathComponent();
264             if (node.isLeaf()) {
265                 ret.append(pathString.toString());
266                 ret.append(CmsAntTaskSelectionTreePrompt.LIST_SEPARATOR);
267             } else {
268                 // first look, wether this is already a module, even if not leaf, (e.g.
269
// org.opencms.workplace <-> org.opencms.workplace.tools.accounts...)
270
if (m_allModuleList.contains(pathString.toString())) {
271                     ret.append(pathString.toString());
272                     ret.append(CmsAntTaskSelectionTreePrompt.LIST_SEPARATOR);
273                 } else {
274                     // nop
275
}
276                 // search all leaf nodes and append subpaths:
277

278                 ret.append(getSubpaths(node, pathString.toString()));
279             }
280
281         }
282         dispose();
283         if (m_aborted || ret.toString().trim().length() < CmsAntTaskSelectionTreePrompt.LIST_SEPARATOR.length()) {
284             return null;
285         } else {
286             return ret.toString();
287         }
288     }
289
290     /**
291      * Centers the dialog on the screen.
292      * <p>
293      *
294      * If the size of the dialog exceeds that of the screen, then the size of the dialog is reset to
295      * the size of the screen.
296      * <p>
297      */

298     private void center() {
299
300         Dimension JavaDoc screen = Toolkit.getDefaultToolkit().getScreenSize();
301         Dimension JavaDoc window = getSize();
302         // ensure that no parts of the dialog will be off-screen
303
int height = window.height;
304         int width = window.width;
305         if (window.height > screen.height) {
306             window.height = screen.height;
307             height = screen.height - 50;
308             width = width + 50;
309         }
310         if (window.width > screen.width) {
311             window.width = screen.width;
312         }
313         int xCoord = (screen.width / 2 - window.width / 2);
314         int yCoord = (screen.height / 2 - window.height / 2);
315         setLocation(xCoord, yCoord);
316         setSize(width, height);
317     }
318
319     private TreeModel JavaDoc createTree() {
320
321         // for every entry: cut into paths, build a tree path that collates equal paths.
322
DefaultMutableTreeNode JavaDoc root = new DefaultMutableTreeNode JavaDoc("root");
323         TreeModel JavaDoc tm = new DefaultTreeModel JavaDoc(root);
324         Iterator JavaDoc itModules = m_allModuleList.iterator();
325         StringTokenizer JavaDoc itPath;
326         Enumeration JavaDoc childEnum;
327         String JavaDoc pathElement;
328         DefaultMutableTreeNode JavaDoc node, child;
329         boolean found = false;
330         while (itModules.hasNext()) {
331             itPath = new StringTokenizer JavaDoc((String JavaDoc)itModules.next(), ".");
332             node = root;
333             while (itPath.hasMoreTokens()) {
334                 // is this node already there?
335
pathElement = itPath.nextToken();
336                 childEnum = node.children();
337                 found = false;
338                 while (childEnum.hasMoreElements()) {
339                     child = (DefaultMutableTreeNode JavaDoc)childEnum.nextElement();
340                     if (pathElement.equals(child.getUserObject())) {
341
342                         // found node for path String
343
// reuse old path, descend and continue with next path element.
344
node = child;
345                         found = true;
346                         break;
347                     }
348                 }
349                 if (!found) {
350                     // did not break, node was not found
351
child = new DefaultMutableTreeNode JavaDoc();
352                     child.setUserObject(pathElement);
353                     node.add(child);
354                     node = child;
355                 }
356             }
357         }
358         return tm;
359
360     }
361
362     /**
363      * Recursive depth first traversal that stops at expansion level and expands those paths.
364      * <p>
365      *
366      * @param treePath the current path in recursion
367      */

368     private void expandTree(TreePath JavaDoc treePath) {
369
370         if (treePath.getPathCount() == m_promptTask.getExpansionLevels()) {
371             m_tree.expandPath(treePath);
372
373         } else {
374             DefaultMutableTreeNode JavaDoc treeNode = (DefaultMutableTreeNode JavaDoc)treePath.getLastPathComponent();
375             Enumeration JavaDoc children = treeNode.children();
376             while (children.hasMoreElements()) {
377                 expandTree(treePath.pathByAddingChild(children.nextElement()));
378             }
379         }
380
381     }
382
383     private String JavaDoc getSubpaths(TreeNode JavaDoc node, String JavaDoc parentPath) {
384
385         Enumeration JavaDoc children = node.children();
386         TreeNode JavaDoc child;
387         String JavaDoc path = parentPath;
388         StringBuffer JavaDoc ret = new StringBuffer JavaDoc();
389         while (children.hasMoreElements()) {
390             child = (TreeNode JavaDoc)children.nextElement();
391             if (parentPath.length() == 0) {
392                 path = child.toString();
393             } else {
394                 path = parentPath + "." + child.toString();
395             }
396             if (child.isLeaf()) {
397                 ret.append(path);
398                 ret.append(CmsAntTaskSelectionTreePrompt.LIST_SEPARATOR);
399             } else {
400                 ret.append(getSubpaths(child, path));
401             }
402         }
403         return ret.toString();
404     }
405
406     /**
407      * Parses the string of comma separated module names obtained from the ant script into the
408      * internal list of module names for better access in several locations.
409      * <p>
410      *
411      */

412     private void parseModuleList() {
413
414         m_allModuleList = new LinkedList JavaDoc();
415         StringTokenizer JavaDoc itPaths = new StringTokenizer JavaDoc(
416             m_promptTask.getAllValues(),
417             CmsAntTaskSelectionPrompt.LIST_SEPARATOR);
418
419         String JavaDoc token;
420         while (itPaths.hasMoreElements()) {
421             token = itPaths.nextToken().trim();
422             m_allModuleList.add(token);
423         }
424     }
425
426     /**
427      * Recursivley selects the nodes that are qualified by the default selections.
428      *
429      * @param node the current Node
430      */

431     private void selectDefaultNodes(DefaultMutableTreeNode JavaDoc node, String JavaDoc path, TreePath JavaDoc treePath) {
432
433         // allow root property to be set:
434
String JavaDoc defaultString = m_promptTask.getDefaultValue();
435         if ("root".equalsIgnoreCase(defaultString.trim())) {
436             if (node == m_tree.getModel().getRoot()) {
437                 m_tree.setSelectionPath(treePath);
438             }
439         } else {
440             StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(defaultString, CmsAntTaskSelectionTreePrompt.LIST_SEPARATOR);
441             String JavaDoc defaultEntry;
442             while (tokenizer.hasMoreTokens()) {
443                 defaultEntry = tokenizer.nextToken();
444                 // don't print in recursions for path
445
if (node.getLevel() == 0) {
446                     System.out.println("Preselection: " + defaultEntry);
447                 }
448                 if (defaultEntry.equals(path)) {
449                     m_tree.addSelectionPath(treePath);
450                     return;
451                 }
452             }
453             Enumeration JavaDoc children = node.children();
454             DefaultMutableTreeNode JavaDoc subNode;
455             String JavaDoc subPath;
456             while (children.hasMoreElements()) {
457                 subPath = path;
458                 if (subPath.length() != 0) {
459                     subPath += ".";
460                 }
461                 subNode = (DefaultMutableTreeNode JavaDoc)children.nextElement();
462                 subPath += subNode.toString();
463                 selectDefaultNodes(subNode, subPath, treePath.pathByAddingChild(subNode));
464             }
465
466         }
467     }
468 }
Popular Tags