001: package jimm.datavision.gui;
002:
003: import jimm.datavision.*;
004: import jimm.datavision.field.Field;
005: import jimm.datavision.field.ColumnField;
006: import jimm.datavision.field.SpecialField;
007: import jimm.datavision.gui.cmd.FPDeleteCommand;
008: import jimm.datavision.source.DataSource;
009: import jimm.datavision.source.Column;
010: import jimm.datavision.source.Table;
011: import jimm.datavision.gui.Designer;
012: import jimm.datavision.gui.cmd.NameableRenameCommand;
013: import jimm.datavision.gui.cmd.FPCutCommand;
014: import jimm.util.I18N;
015: import java.awt.Dimension;
016: import java.awt.BorderLayout;
017: import java.awt.event.*;
018: import java.util.*;
019: import javax.swing.*;
020: import javax.swing.event.*;
021: import javax.swing.tree.*;
022:
023: /**
024: * A window that lets the user drag any field available onto the report and
025: * create, edit, delete, and rename formulas, parameters, and user columns.
026: * <p>
027: * Uses a {@link FieldPickerTree}. The classes used to store information about
028: * leaf nodes are subclasses of {@link FPLeafInfo} and are found in
029: * FPLeafInfo.java.
030: *
031: * @see FPTableInfo
032: * @author Jim Menard, <a href="mailto:jimm@io.com">jimm@io.com</a>
033: */
034: class FieldPickerWin extends JDialog implements ActionListener,
035: TreeSelectionListener, TreeWillExpandListener, Observer {
036:
037: public static final int REPORT_DATABASE_FIELDS = 0;
038: public static final int FORMULAS = 1;
039: public static final int PARAMETERS = 2;
040: public static final int USERCOLS = 3;
041: public static final int SPECIAL_FIELDS = 4;
042: public static final int ALL_DATABASE_FIELDS = 5;
043: // public static final int GROUP_NAME_FIELDS = XXXX;
044:
045: protected Report report;
046: protected Designer designer;
047: protected JMenuItem cutItem, editFormulaItem, renameFormulaItem,
048: editParameterItem, renameParameterItem, editUserColumnItem,
049: renameUserColumnItem, deleteItem;
050: protected FieldPickerTree tree;
051: protected DefaultTreeModel treeModel;
052: protected DefaultMutableTreeNode formulaCategoryNode;
053: protected DefaultMutableTreeNode parameterCategoryNode;
054: protected DefaultMutableTreeNode userColumnCategoryNode;
055: protected DefaultMutableTreeNode selectedNode;
056: protected FPLeafInfo selectedInfo;
057: protected Comparator nameComparator;
058:
059: /**
060: * Constructor.
061: *
062: * @param designer the design window to which this dialog belongs
063: * @param report the report
064: * @param startingType the index of the starting type to display
065: */
066: FieldPickerWin(Designer designer, Report report, int startingType) {
067: super (designer.getFrame(), I18N.get("FieldPickerWin.title"));
068: this .report = report;
069: this .designer = designer;
070:
071: // Note: this comparator imposes orderings that are inconsistent with
072: // equals.
073: nameComparator = new Comparator() {
074: public int compare(Object o1, Object o2) {
075: String name1 = ((Nameable) o1).getName();
076: String name2 = ((Nameable) o2).getName();
077: return name1.compareTo(name2);
078: }
079: };
080:
081: buildWindow(startingType);
082:
083: pack();
084: show();
085: }
086:
087: public void update(Observable o, Object arg) {
088: // Primitive and overkill, but it works.
089: tree.repaint();
090: }
091:
092: /**
093: * Builds the contents of the window.
094: *
095: * @param startingType the index of the starting type to display
096: */
097: protected void buildWindow(int startingType) {
098: buildMenuBar();
099:
100: DefaultMutableTreeNode top = new DefaultMutableTreeNode();
101: createNodes(top);
102: treeModel = new DefaultTreeModel(top);
103:
104: tree = new FieldPickerTree(treeModel);
105: tree.setRootVisible(false);
106: tree.getSelectionModel().setSelectionMode(
107: TreeSelectionModel.SINGLE_TREE_SELECTION);
108:
109: // Make specified starting type visible and expanded
110: tree.expandRow(startingType);
111:
112: // Listen for selection changes and node expansions
113: tree.addTreeSelectionListener(this );
114: tree.addTreeWillExpandListener(this );
115:
116: // Create the scroll pane and add the tree to it.
117: JScrollPane treeView = new JScrollPane(tree);
118: treeView.setMinimumSize(new Dimension(100, 100));
119: treeView.setPreferredSize(new Dimension(200, 300));
120:
121: getContentPane().add(treeView, BorderLayout.CENTER);
122: }
123:
124: /**
125: * Builds the window menu bar.
126: */
127: protected void buildMenuBar() {
128: JMenuBar bar = new JMenuBar();
129: bar.add(buildFileMenu());
130: bar.add(buildEditMenu());
131: bar.add(buildFieldMenu());
132: setJMenuBar(bar);
133: }
134:
135: /**
136: * Builds and returns the "File" menu.
137: *
138: * @return a menu
139: */
140: protected JMenu buildFileMenu() {
141: JMenu menu = MenuUtils.readMenu("FieldPickerWin.menu_file");
142: MenuUtils.addToMenu(this , menu,
143: "FieldPickerWin.menu_file_close");
144: return menu;
145: }
146:
147: /**
148: * Builds and returns the "Edit" menu.
149: *
150: * @return a menu
151: */
152: protected JMenu buildEditMenu() {
153: JMenu menu = MenuUtils.readMenu("FieldPickerWin.menu_edit");
154:
155: MenuUtils
156: .addToMenu(this , menu, "FieldPickerWin.menu_edit_undo");
157: MenuUtils
158: .addToMenu(this , menu, "FieldPickerWin.menu_edit_redo");
159: menu.addSeparator();
160: cutItem = MenuUtils.addToMenu(this , menu,
161: "FieldPickerWin.menu_edit_cut");
162: MenuUtils
163: .addToMenu(this , menu, "FieldPickerWin.menu_edit_copy");
164: MenuUtils.addToMenu(this , menu,
165: "FieldPickerWin.menu_edit_paste");
166: deleteItem = MenuUtils.addToMenu(this , menu,
167: "FieldPickerWin.menu_edit_delete");
168:
169: return menu;
170: }
171:
172: /**
173: * Builds and returns the "Field" menu.
174: *
175: * @return a menu
176: */
177: protected JMenu buildFieldMenu() {
178: JMenu menu = MenuUtils.readMenu("FieldPickerWin.menu_field");
179:
180: MenuUtils.addToMenu(this , menu,
181: "FieldPickerWin.menu_field_new_formula");
182: editFormulaItem = MenuUtils.addToMenu(this , menu,
183: "FieldPickerWin.menu_field_edit_formula");
184: renameFormulaItem = MenuUtils.addToMenu(this , menu,
185: "FieldPickerWin.menu_field_rename_formula");
186:
187: menu.addSeparator();
188:
189: MenuUtils.addToMenu(this , menu,
190: "FieldPickerWin.menu_field_new_param");
191: editParameterItem = MenuUtils.addToMenu(this , menu,
192: "FieldPickerWin.menu_field_edit_param");
193: renameParameterItem = MenuUtils.addToMenu(this , menu,
194: "FieldPickerWin.menu_field_rename_param");
195:
196: menu.addSeparator();
197:
198: MenuUtils.addToMenu(this , menu,
199: "FieldPickerWin.menu_field_new_usercol");
200: editUserColumnItem = MenuUtils.addToMenu(this , menu,
201: "FieldPickerWin.menu_field_edit_usercol");
202: renameUserColumnItem = MenuUtils.addToMenu(this , menu,
203: "FieldPickerWin.menu_field_rename_usercol");
204:
205: return menu;
206: }
207:
208: /**
209: * Creates tree nodes.
210: *
211: * @param top top-level tree node
212: */
213: protected void createNodes(DefaultMutableTreeNode top) {
214: createUsedDatabaseTables(top);
215: createFormulas(top);
216: createParameters(top);
217: createUserColumns(top);
218: createSpecialFields(top);
219: createAllDatabaseTables(top);
220: }
221:
222: /**
223: * Creates nodes representing tables and columns for columns used by report.
224: *
225: * @param top top-level tree node
226: */
227: protected void createUsedDatabaseTables(DefaultMutableTreeNode top) {
228: DefaultMutableTreeNode categoryNode = new DefaultMutableTreeNode(
229: I18N.get("FieldPickerWin.db_fields"));
230: top.add(categoryNode);
231:
232: // Store list of tables actually used by the report in a sorted set.
233: final TreeSet tables = new TreeSet(nameComparator);
234: final TreeSet noTableCols = new TreeSet(nameComparator);
235:
236: // Walk the list of all columns used by the report, adding the table
237: // to the sorted set of tables.
238: report.withFieldsDo(new FieldWalker() {
239: public void step(Field f) {
240: if (f instanceof ColumnField) {
241: Column col = ((ColumnField) f).getColumn();
242: Table t = col.getTable();
243: if (t == null)
244: noTableCols.add(col);
245: else
246: tables.add(t);
247: }
248: }
249: });
250:
251: // Add tables and columns under tables
252: for (Iterator iter = tables.iterator(); iter.hasNext();)
253: addTableNode(categoryNode, (Table) iter.next());
254:
255: // Add colums that have no table
256: for (Iterator iter = noTableCols.iterator(); iter.hasNext();) {
257: Column column = (Column) iter.next();
258: ColumnInfo info = new ColumnInfo(column, designer);
259: categoryNode.add(new DefaultMutableTreeNode(info, false));
260: }
261: }
262:
263: /**
264: * Creates nodes representing formula fields.
265: *
266: * @param top top-level tree node
267: */
268: protected void createFormulas(DefaultMutableTreeNode top) {
269: formulaCategoryNode = new DefaultMutableTreeNode(I18N
270: .get("FieldPickerWin.formulas"));
271: top.add(formulaCategoryNode);
272:
273: TreeSet formulas = new TreeSet(nameComparator);
274:
275: for (Iterator iter = report.formulas(); iter.hasNext();)
276: formulas.add(iter.next());
277:
278: for (Iterator iter = formulas.iterator(); iter.hasNext();) {
279: Formula f = (Formula) iter.next();
280: FormulaInfo info = new FormulaInfo(report, f, designer);
281: formulaCategoryNode.add(new DefaultMutableTreeNode(info));
282: f.addObserver(this );
283: }
284: }
285:
286: /**
287: * Creates nodes representing parameter fields.
288: *
289: * @param top top-level tree node
290: */
291: protected void createParameters(DefaultMutableTreeNode top) {
292: parameterCategoryNode = new DefaultMutableTreeNode(I18N
293: .get("FieldPickerWin.parameters"));
294: top.add(parameterCategoryNode);
295:
296: TreeSet parameters = new TreeSet(nameComparator);
297:
298: for (Iterator iter = report.parameters(); iter.hasNext();)
299: parameters.add(iter.next());
300:
301: for (Iterator iter = parameters.iterator(); iter.hasNext();) {
302: Parameter p = (Parameter) iter.next();
303: ParameterInfo info = new ParameterInfo(report, p, designer);
304: parameterCategoryNode.add(new DefaultMutableTreeNode(info));
305: p.addObserver(this );
306: }
307: }
308:
309: /**
310: * Creates nodes representing user column fields.
311: *
312: * @param top top-level tree node
313: */
314: protected void createUserColumns(DefaultMutableTreeNode top) {
315: userColumnCategoryNode = new DefaultMutableTreeNode(I18N
316: .get("FieldPickerWin.usercols"));
317: top.add(userColumnCategoryNode);
318:
319: TreeSet usercols = new TreeSet(nameComparator);
320:
321: for (Iterator iter = report.userColumns(); iter.hasNext();)
322: usercols.add(iter.next());
323:
324: for (Iterator iter = usercols.iterator(); iter.hasNext();) {
325: UserColumn uc = (UserColumn) iter.next();
326: UserColumnInfo info = new UserColumnInfo(report, uc,
327: designer);
328: userColumnCategoryNode
329: .add(new DefaultMutableTreeNode(info));
330: uc.addObserver(this );
331: }
332: }
333:
334: /**
335: * Creates nodes representing each possible special field.
336: *
337: * @param top top-level tree node
338: */
339: protected void createSpecialFields(DefaultMutableTreeNode top) {
340: DefaultMutableTreeNode categoryNode = new DefaultMutableTreeNode(
341: I18N.get("FieldPickerWin.specials"));
342: top.add(categoryNode);
343:
344: HashMap strs = SpecialField.specialFieldNames();
345: TreeSet sortedKeys = new TreeSet(strs.keySet());
346:
347: for (Iterator iter = sortedKeys.iterator(); iter.hasNext();) {
348: String key = (String) iter.next();
349: String val = (String) strs.get(key);
350: key = SpecialField.TYPE_STRING + ':' + key;
351: SpecialInfo info = new SpecialInfo(val, key, designer);
352:
353: DefaultMutableTreeNode node = new DefaultMutableTreeNode(
354: info);
355: categoryNode.add(node);
356: }
357: }
358:
359: /**
360: * Creates notes representing tables and columns for all tables in the
361: * database.
362: *
363: * @param top top-level tree node
364: */
365: protected void createAllDatabaseTables(DefaultMutableTreeNode top) {
366: DefaultMutableTreeNode categoryNode = new DefaultMutableTreeNode(
367: I18N.get("FieldPickerWin.all"));
368: top.add(categoryNode);
369:
370: // Store list of tables actually used by the report in a sorted set.
371: final TreeSet tables = new TreeSet(nameComparator);
372: final TreeSet noTableCols = new TreeSet(nameComparator);
373:
374: // Walk data source's list of tables. If there are no tables for the
375: // data source, then instead add all columns to the noTableCols set.
376: DataSource source = report.getDataSource();
377: Iterator iter = source.tables();
378: if (iter != null) {
379: while (iter.hasNext())
380: tables.add(iter.next());
381: }
382:
383: if (tables.isEmpty()) {
384: for (iter = source.columns(); iter.hasNext();)
385: noTableCols.add(iter.next());
386: }
387:
388: // Add nodes for tables and columns under tables
389: for (iter = tables.iterator(); iter.hasNext();)
390: addTableNode(categoryNode, (Table) iter.next());
391:
392: // Add nodes for columns that have no table
393: for (iter = noTableCols.iterator(); iter.hasNext();) {
394: Column column = (Column) iter.next();
395: ColumnInfo info = new ColumnInfo(column, designer);
396: categoryNode.add(new DefaultMutableTreeNode(info, false));
397: }
398: }
399:
400: /**
401: * Creates and adds a node representing a data source table. The node is
402: * given one dummy node that will be removed when the table node loads its
403: * column nodes.
404: *
405: * @param categoryNode the parent node
406: * @param table the database table
407: */
408: protected void addTableNode(DefaultMutableTreeNode categoryNode,
409: Table table) {
410: FPTableInfo info = new FPTableInfo(table, designer);
411: DefaultMutableTreeNode tableNode = new DefaultMutableTreeNode(
412: info);
413: info.setTableNode(tableNode);
414: categoryNode.add(tableNode);
415:
416: // Add a dummy node that will be removed when the table node
417: // loads its column nodes.
418: tableNode.add(new DefaultMutableTreeNode(""));
419: }
420:
421: /**
422: * Opens a name editor to (re)name a nameable object. Returns <code>true</code>
423: * if the user clicked OK, <code>false</code> if the user clicked Cancel.
424: *
425: * @param nameable a nameable object
426: * @param editTitleKey I18N lookup key for "edit" title
427: * @param newTitleKey I18N lookup key for "new" title
428: * @param promptKey I18N lookup key for prompt
429: * @param unnamedKey I18N lookup key for "unnamed" name
430: * @return <code>true</code> if the user clicked OK, <code>false</code>
431: * if the user clicked Cancel
432: */
433: protected boolean rename(Nameable nameable, String newTitleKey,
434: String editTitleKey, String promptKey, String unnamedKey) {
435: String oldName = nameable.getName();
436: String title = (oldName == null || oldName.length() == 0) ? I18N
437: .get(newTitleKey)
438: : I18N.get(editTitleKey);
439: String name = new AskStringDialog((JFrame) this .getOwner(),
440: title, I18N.get(promptKey), oldName).getString();
441:
442: if (name == null) // User cancelled
443: return false;
444:
445: if (name.length() == 0)
446: name = I18N.get(unnamedKey);
447: designer.performCommand(new NameableRenameCommand(nameable,
448: oldName, name));
449: return true;
450: }
451:
452: /**
453: * Adds a newly created editable object to the tree, makes it visible,
454: * and opens its editor.
455: *
456: * @param info describes what is being added to add to the tree
457: * @param categoryNode where in the tree to put the new item
458: */
459: protected void addEditableToTree(FPLeafInfo info,
460: DefaultMutableTreeNode categoryNode) {
461: // Add to tree
462: DefaultMutableTreeNode node = new DefaultMutableTreeNode(info);
463: treeModel.insertNodeInto(node, categoryNode, categoryNode
464: .getChildCount());
465:
466: // Make leaf visible and make it the current selection
467: TreePath path = new TreePath(node.getPath());
468: tree.scrollPathToVisible(path);
469: tree.setSelectionPath(path);
470:
471: editSelection(); // Open editor
472: }
473:
474: /**
475: * Creates a new formula, adds it to the report and the tree, and opens
476: * the formula editor.
477: */
478: protected void newFormula() {
479: // Create formula and let user enter name
480: Formula f = new Formula(null, report, "", "");
481: if (renameFormula(f) == false)
482: return; // User cancelled
483:
484: // Add to report and to tree and open editor
485: report.addFormula(f);
486: addEditableToTree(new FormulaInfo(report, f, designer),
487: formulaCategoryNode);
488: }
489:
490: /**
491: * Opens a name editor to rename the currently select formula. Returns
492: * <code>true</code> if the user clicked OK, <code>false</code> if the
493: * user clicked Cancel.
494: *
495: * @return <code>true</code> if the user clicked OK, <code>false</code>
496: * if the user clicked Cancel
497: */
498: protected boolean renameFormula() {
499: return renameFormula((Formula) selectedInfo.getLeaf());
500: }
501:
502: /**
503: * Opens a name editor to (re)name a formula. Returns <code>true</code>
504: * if the user clicked OK, <code>false</code> if the user clicked Cancel.
505: *
506: * @param f a formula
507: * @return <code>true</code> if the user clicked OK, <code>false</code>
508: * if the user clicked Cancel
509: */
510: protected boolean renameFormula(Formula f) {
511: return rename(f, "FieldPickerWin.new_formula_name_title",
512: "FieldPickerWin.edit_formula_name_title",
513: "FieldPickerWin.formula_name_prompt",
514: "FieldPickerWin.unnamed_formula");
515: }
516:
517: /**
518: * Opens an editor on the currently selected item.
519: */
520: protected void editSelection() {
521: selectedInfo.openEditor();
522: }
523:
524: /**
525: * Creates a new parameter, adds it to the report and the tree, and opens
526: * the parameter editor.
527: */
528: protected void newParameter() {
529: // Create parameter and let user edit it.
530: Parameter p = new Parameter(null, report);
531: if (renameParameter(p) == false)
532: return; // User cancelled
533:
534: // Add to report and to tree and open editor
535: report.addParameter(p);
536: addEditableToTree(new ParameterInfo(report, p, designer),
537: parameterCategoryNode);
538: }
539:
540: /**
541: * Opens a name editor to rename the currently select parameter. Returns
542: * <code>true</code> if the user clicked OK, <code>false</code> if the
543: * user clicked Cancel.
544: *
545: * @return <code>true</code> if the user clicked OK, <code>false</code>
546: * if the user clicked Cancel
547: */
548: protected boolean renameParameter() {
549: return renameParameter((Parameter) selectedInfo.getLeaf());
550: }
551:
552: /**
553: * Opens a name editor to (re)name a parameter. Returns <code>true</code>
554: * if the user clicked OK, <code>false</code> if the user clicked Cancel.
555: *
556: * @param p a parameter
557: * @return <code>true</code> if the user clicked OK, <code>false</code>
558: * if the user clicked Cancel
559: */
560: protected boolean renameParameter(Parameter p) {
561: return rename(p, "FieldPickerWin.new_param_name_title",
562: "FieldPickerWin.edit_param_name_title",
563: "FieldPickerWin.param_name_prompt",
564: "FieldPickerWin.unnamed_parameter");
565: }
566:
567: /**
568: * Creates a new user column, adds it to the report and the tree, and opens
569: * the user column editor.
570: */
571: protected void newUserColumn() {
572: // Create user column and let user enter name
573: UserColumn uc = new UserColumn(null, report, "");
574: if (renameUserColumn(uc) == false)
575: return; // User cancelled
576:
577: // Add to report and to tree and open editor
578: report.addUserColumn(uc);
579: addEditableToTree(new UserColumnInfo(report, uc, designer),
580: userColumnCategoryNode);
581: }
582:
583: /**
584: * Opens a name editor to rename the currently select user column. Returns
585: * <code>true</code> if the user clicked OK, <code>false</code> if the
586: * user clicked Cancel.
587: *
588: * @return <code>true</code> if the user clicked OK, <code>false</code>
589: * if the user clicked Cancel
590: */
591: protected boolean renameUserColumn() {
592: return renameUserColumn((UserColumn) selectedInfo.getLeaf());
593: }
594:
595: /**
596: * Opens a name editor to (re)name a user column. Returns <code>true</code>
597: * if the user clicked OK, <code>false</code> if the user clicked Cancel.
598: *
599: * @param f a user column
600: * @return <code>true</code> if the user clicked OK, <code>false</code>
601: * if the user clicked Cancel
602: */
603: protected boolean renameUserColumn(UserColumn f) {
604: return rename(f, "FieldPickerWin.new_usercol_name_title",
605: "FieldPickerWin.edit_usercol_name_title",
606: "FieldPickerWin.usercol_name_prompt",
607: "FieldPickerWin.unnamed_usercol");
608: }
609:
610: /**
611: * Handles user actions. Actions are only allowed when legal. For example,
612: * the "Cut" menu item will only be enabled when a delete operation is
613: * possible.
614: */
615: public void actionPerformed(ActionEvent e) {
616: String cmd = e.getActionCommand();
617:
618: // File menu
619: if ("close".equals(cmd))
620: dispose();
621:
622: // Edit menu
623: else if ("cut".equals(cmd))
624: designer.performCommand(new FPCutCommand(report, designer,
625: tree, selectedNode));
626:
627: // Field menu
628: else if ("new_formula".equals(cmd))
629: newFormula();
630: else if ("edit_formula".equals(cmd))
631: editSelection();
632: else if ("rename_formula".equals(cmd))
633: renameFormula();
634: else if ("new_parameter".equals(cmd))
635: newParameter();
636: else if ("edit_parameter".equals(cmd))
637: editSelection();
638: else if ("rename_parameter".equals(cmd))
639: renameParameter();
640: else if ("new_user_column".equals(cmd))
641: newUserColumn();
642: else if ("edit_user_column".equals(cmd))
643: editSelection();
644: else if ("rename_user_column".equals(cmd))
645: renameUserColumn();
646: else if ("delete".equals(cmd))
647: designer.performCommand(new FPDeleteCommand(report,
648: designer, tree, selectedNode));
649: }
650:
651: /**
652: * Modifies the menu in response to a change in the tree's selection.
653: */
654: public void valueChanged(TreeSelectionEvent e) {
655: if (e.isAddedPath()) {
656: selectedNode = (DefaultMutableTreeNode) e.getPath()
657: .getLastPathComponent();
658: Object obj = selectedNode.getUserObject();
659: if (obj instanceof FPLeafInfo)
660: selectedInfo = (FPLeafInfo) obj;
661: else
662: selectedInfo = null;
663:
664: if (selectedInfo == null) {
665: cutItem.setEnabled(false);
666: editFormulaItem.setEnabled(false);
667: editParameterItem.setEnabled(false);
668: editUserColumnItem.setEnabled(false);
669: renameFormulaItem.setEnabled(false);
670: renameParameterItem.setEnabled(false);
671: renameUserColumnItem.setEnabled(false);
672: deleteItem.setEnabled(false);
673: } else {
674: boolean isFormula = selectedInfo instanceof FormulaInfo;
675: boolean isParameter = selectedInfo instanceof ParameterInfo;
676: boolean isUserColumn = selectedInfo instanceof UserColumnInfo;
677:
678: cutItem.setEnabled(selectedInfo.isDeletable());
679: deleteItem.setEnabled(selectedInfo.isDeletable());
680: editFormulaItem.setEnabled(isFormula);
681: editParameterItem.setEnabled(isParameter);
682: editUserColumnItem.setEnabled(isUserColumn);
683: renameFormulaItem.setEnabled(isFormula);
684: renameParameterItem.setEnabled(isParameter);
685: renameUserColumnItem.setEnabled(isUserColumn);
686: }
687:
688: } else {
689: selectedInfo = null;
690: cutItem.setEnabled(false);
691: editFormulaItem.setEnabled(false);
692: editParameterItem.setEnabled(false);
693: editUserColumnItem.setEnabled(false);
694: renameFormulaItem.setEnabled(false);
695: renameParameterItem.setEnabled(false);
696: renameUserColumnItem.setEnabled(false);
697: }
698: }
699:
700: public void treeWillExpand(TreeExpansionEvent e) {
701: DefaultMutableTreeNode node = (DefaultMutableTreeNode) e
702: .getPath().getLastPathComponent();
703: Object obj = node.getUserObject();
704: if (obj instanceof FPTableInfo)
705: ((FPTableInfo) obj).loadColumns();
706: }
707:
708: public void treeWillCollapse(TreeExpansionEvent e) {
709: }
710:
711: }
|