001: /* ===========================================================================
002: * $RCSfile: TreeControl.java,v $
003: * ===========================================================================
004: *
005: * RetroGuard -- an obfuscation package for Java classfiles.
006: *
007: * Copyright (c) 1998-2006 Mark Welsh (markw@retrologic.com)
008: *
009: * This program can be redistributed and/or modified under the terms of the
010: * Version 2 of the GNU General Public License as published by the Free
011: * Software Foundation.
012: *
013: * This program is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016: * GNU General Public License for more details.
017: *
018: */
019:
020: package COM.rl.util;
021:
022: import java.io.*;
023: import java.awt.*;
024: import java.awt.event.*;
025: import java.util.*;
026:
027: /**
028: * A tree control which maintains its state simultaneously in one or more
029: * List UI elements.
030: *
031: * @author Mark Welsh
032: */
033: public class TreeControl implements ActionListener, ItemListener {
034: // Constants -------------------------------------------------------------
035:
036: // Fields ----------------------------------------------------------------
037: private java.awt.List[] lists;
038: private Vector content;
039:
040: // Class Methods ---------------------------------------------------------
041:
042: // Instance Methods ------------------------------------------------------
043: /** Ctor - multiple synchronized lists. */
044: public TreeControl(java.awt.List[] lists) {
045: init(lists);
046: }
047:
048: /** Ctor - single list. */
049: public TreeControl(java.awt.List list) {
050: java.awt.List[] lists = { list };
051: init(lists);
052: }
053:
054: // Private initializer required because array specifiers cannot be constructed inline.
055: private void init(java.awt.List[] lists) {
056: // Intercept ActionEvent's from the lists, clear them, and make them single select
057: this .lists = lists;
058: for (int i = 0; i < lists.length; i++) {
059: java.awt.List list = lists[i];
060: list.addActionListener(this );
061: list.addItemListener(this );
062: list.removeAll();
063: list.setMultipleMode(false);
064: }
065:
066: // No content initially in the lists
067: content = new Vector();
068: }
069:
070: /** Get an indexed entry. */
071: public TreeEntry getEntry(int i) throws Exception {
072: return (TreeEntry) content.elementAt(i);
073: }
074:
075: /** Add an element to the root of the tree. */
076: public void add(TreeEntry entry) {
077: if (entry.canOpen()) {
078: entry.setOpen(false);
079: }
080: content.addElement(entry);
081: for (int i = 0; i < lists.length; i++) {
082: lists[i].add(entry.toString());
083: }
084: }
085:
086: /** Remove all elements from the tree. */
087: public void removeAll() {
088: content.removeAllElements();
089: for (int i = 0; i < lists.length; i++) {
090: lists[i].removeAll();
091: }
092: }
093:
094: /** Sole action is to open or close the selected list item. */
095: public void actionPerformed(ActionEvent e) {
096: // Disable lists
097: for (int i = 0; i < lists.length; i++) {
098: lists[i].setEnabled(false);
099: }
100:
101: // Get the source List's current item index
102: if (e.getSource() instanceof java.awt.List) {
103: int index = ((java.awt.List) e.getSource())
104: .getSelectedIndex();
105: if (index != -1) {
106: // Get the associated TreeEntry
107: TreeEntry entry = (TreeEntry) content.elementAt(index);
108: if (entry.canOpen()) {
109: if (entry.isOpen()) {
110: close(index + 1, entry);
111: } else {
112: open(index + 1, entry);
113: }
114: }
115: }
116: }
117:
118: // Enable lists
119: for (int i = 0; i < lists.length; i++) {
120: lists[i].setEnabled(true);
121: }
122: }
123:
124: /** Synchronize the lists when a selection is made in one of them. */
125: public void itemStateChanged(ItemEvent e) {
126: // Get the source List's current item index
127: if (e.getSource() instanceof java.awt.List) {
128: java.awt.List sourceList = (java.awt.List) e.getSource();
129: int index = sourceList.getSelectedIndex();
130: if (index != -1) {
131: for (int i = 0; i < lists.length; i++) {
132: if (lists[i] != sourceList) {
133: lists[i].select(index);
134: }
135: }
136: }
137: }
138: }
139:
140: // Open a single TreeEntry into the Lists
141: private void open(int index, TreeEntry entry) {
142: for (Enumeration enm = entry.elements(); enm.hasMoreElements();) {
143: TreeEntry childEntry = (TreeEntry) enm.nextElement();
144: content.insertElementAt(childEntry, index);
145: for (int i = 0; i < lists.length; i++) {
146: lists[i].add(childEntry.toString(), index);
147: }
148: index++;
149: }
150: entry.setOpen(true);
151: }
152:
153: // Recursively close a TreeEntry in the Lists
154: private void close(int index, TreeEntry entry) {
155: for (int i = 0; i < entry.childCount(); i++) {
156: TreeEntry childEntry = (TreeEntry) content.elementAt(index);
157: content.removeElementAt(index);
158: for (int j = 0; j < lists.length; j++) {
159: lists[j].remove(index);
160: }
161: if (childEntry.isOpen()) {
162: close(index, childEntry);
163: }
164: }
165: entry.setOpen(false);
166: }
167: }
|