View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership. The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License. You may obtain a copy of the License at
9    * 
10   *      http://www.apache.org/licenses/LICENSE-2.0
11   * 
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.river.example.browser;
19  
20  import net.jini.core.entry.Entry;
21  import java.lang.reflect.Field;
22  import java.lang.reflect.Array;
23  import java.awt.Component;
24  import java.awt.BorderLayout;
25  import java.util.logging.Level;
26  import javax.swing.JPanel;
27  import javax.swing.JScrollPane;
28  import javax.swing.JTree;
29  import javax.swing.JLabel;
30  import javax.swing.tree.DefaultTreeModel;
31  import javax.swing.tree.TreeCellRenderer;
32  import javax.swing.plaf.metal.MetalLookAndFeel;
33  
34  /**
35   *
36   * @author Sun Microsystems, Inc.
37   *
38   * @version 0.2 06/04/98
39   *
40   */
41  abstract class EntryTreePanel extends JPanel {
42    /**
43     * running mode. 
44     *
45     * @serial
46     */
47    private boolean isControllable;
48  
49  
50    /**
51     * @serial
52     */
53  
54    private JScrollPane scrollPane;
55  
56    /**
57     * @serial
58     */
59    protected JTree tree;
60  
61    /**
62     * @serial
63     */
64    protected ObjectNode root;
65  
66    /**
67     * @serial
68     */
69    protected DefaultTreeModel model;
70  
71    /**
72     * @serial
73     */
74    private boolean showModifier = false;
75  
76    /**
77     * @serial
78     */
79    private boolean showPackage = false;
80  
81  
82    public EntryTreePanel(boolean isControllable) {
83      this.isControllable = isControllable;
84  
85      // Init this panel
86      setLayout(new BorderLayout());
87  
88      // Init tree node and model (attribute tree nodes)
89      root = new ObjectNode(isControllable);
90      //initTree();
91      model = new DefaultTreeModel(root);
92  
93      // Init tree view
94      tree = new JTree(model);
95      //tree.addMouseListener(new DoubleClicker(this));
96      tree.setRootVisible(false);
97      ObjectNodeRenderer renderer = new ObjectNodeRenderer();
98      tree.setCellRenderer(renderer);
99      tree.setRowHeight(0);	// let the renderer handle it
100     scrollPane = new JScrollPane(tree);
101     add(scrollPane, "Center");
102 
103     tree.validate();
104     scrollPane.validate();
105   }
106 
107   protected abstract Entry[] getEntryArray();
108 
109 
110   protected void initTree() {
111     Entry[] entries = getEntryArray();
112     if(entries == null)
113       entries = new Entry[0];
114 
115     for(int i = 0; i < entries.length; i++){
116       // check controllability
117       boolean nodeControllable = false;
118       if(isControllable && ! (entries[i] instanceof net.jini.lookup.entry.ServiceControlled)) {
119 	nodeControllable = true;
120       }
121 
122       ObjectNode node = new ObjectNode(entries[i], nodeControllable);
123       root.add(node);
124       try {
125 	recursiveObjectTree(node);
126       } catch(IllegalAccessException e){
127 	Browser.logger.log(Level.INFO, "entry access failed", e);
128       }
129     }
130   }
131 
132   public void refreshPanel() {
133     // reconstruct nodes
134     root.removeAllChildren();
135     initTree();
136     
137     model.nodeStructureChanged(root);
138 
139     tree.validate();
140     scrollPane.validate();
141   }
142 
143   protected void recursiveObjectTree(ObjectNode node)
144     throws IllegalArgumentException, IllegalAccessException {
145 
146     Object obj = node.getObject();
147     if(obj == null)
148       return;
149     //Field[] fields = obj.getClass().getDeclaredFields();
150     Field[] fields = obj.getClass().getFields();
151 
152     for(int i = 0; i < fields.length; i++){
153       Field f = fields[i];
154 
155       if(Introspector.isHidden(f))
156 	continue;
157 
158       Class clazz = f.getType();
159       ObjectNode child = null;
160       String fname = f.getName();
161       if(clazz.isPrimitive()){
162 	String clazzName = clazz.toString();
163 	Object fobj = null;
164 	if("int".equals(clazzName)){
165 	  fobj = Integer.valueOf(f.getInt(obj));
166 	} else if("boolean".equals(clazzName)){
167 	  fobj = new Boolean(f.getBoolean(obj));
168 	} else if("byte".equals(clazzName)){
169 	  fobj = Byte.valueOf(f.getByte(obj));
170 	} else if("char".equals(clazzName)){
171 	  fobj = Character.valueOf(f.getChar(obj));
172 	} else if("double".equals(clazzName)){
173 	  fobj = new Double(f.getDouble(obj));
174 	} else if("float".equals(clazzName)){
175 	  fobj = new Float(f.getFloat(obj));
176 	} else if("long".equals(clazzName)){
177 	  fobj = Long.valueOf(f.getLong(obj));
178 	}
179 
180 	child = new ObjectNode(fobj, clazz, fname, true);
181       } else if(Introspector.isWrapper(clazz) || Introspector.isString(clazz)) {
182 	child = new ObjectNode(f.get(obj), clazz, fname, true);
183       } else if(clazz.isArray()){
184 	child = new ObjectNode(f.get(obj), clazz, fname, false);
185 	child.setAdministrable(node.isAdministrable());
186 	child.setControllable(node.isControllable());
187 	recursiveArrayTree(child, f);
188       } else {
189 	// unknown type
190 	Object subobj = f.get(obj);
191 
192 	// check if sub object has a viewable members.
193 	if(countViewableFields(clazz) > 0){
194 	  child = new ObjectNode(subobj, clazz, fname, false);
195 	  child.setAdministrable(node.isAdministrable());
196 	  child.setControllable(node.isControllable());
197 	  recursiveObjectTree(child);
198 	} else {
199 	  child = new ObjectNode(subobj, clazz, fname, true);
200 	}
201       }
202       node.add(child);
203     }
204   }
205 
206   private int countViewableFields(Class clazz) {
207 
208     int count = 0;
209     //Field[] fields = obj.getClass().getDeclaredFields();
210     //Field[] fields = obj.getClass().getFields();
211     Field[] fields = clazz.getFields();
212     for(int i = 0; i < fields.length; i++){
213       Field f = fields[i];
214 
215       if(Introspector.isHidden(f))
216 	continue;
217 
218       count++;
219     }
220 
221     return count;
222   }
223 
224   private void recursiveArrayTree(ObjectNode node, Field f)
225     throws IllegalArgumentException, IllegalAccessException {
226 
227     String name = node.getFieldName();
228     Object aobj = node.getObject();
229 
230     int length = Array.getLength(aobj);
231 
232     Class clazz = f.getType().getComponentType();
233 
234     if(clazz.isPrimitive() || Introspector.isWrapper(clazz) || Introspector.isString(clazz)){
235       // primitive, wrapper objects, string array
236       for(int i = 0; i < length; i++){
237 	Object elem = Array.get(aobj, i);
238 	//String fname = name + "[" + i + "]"; 
239 	ObjectNode child = new ObjectNode(elem, clazz, name, i, true);
240 	node.add(child);
241       }
242     } else {
243       // Object or Array (*sigh*)
244       for(int i = 0; i < length; i++){
245 	Object elem = Array.get(aobj, i);
246 	//String fname = name + "[" + i + "]"; 
247 	ObjectNode child = new ObjectNode(elem, clazz, name, i, false);
248 	recursiveObjectTree(child);
249 	child.setAdministrable(node.isAdministrable());
250 	child.setControllable(node.isControllable());
251 
252 	node.add(child);
253       }
254     }
255   }
256 
257 
258   class ObjectNodeRenderer implements TreeCellRenderer {
259     private JLabel label;
260 
261     public ObjectNodeRenderer() {
262       label = new JLabel();
263       label.setOpaque(true);
264     }
265     
266     public Component getTreeCellRendererComponent(JTree tree,
267 						  Object value,
268 						  boolean isSelected,
269 						  boolean isExpanded,
270 						  boolean isLeaf,
271 						  int row,
272 						  boolean cellHasFocus){
273 
274       //label.setFont(tree.getFont());
275       label.setForeground(tree.getForeground());
276       if(isSelected){
277 	//label.setBackground(UIManager.getColor("Tree.backgroundSelectionColor"));
278 	//label.setForeground(UIManager.getColor("Tree.textSelectionColor"));
279 	label.setBackground(MetalLookAndFeel.getPrimaryControl());
280       } else {
281 	//label.setBackground(UIManager.getColor("Tree.backgroundNonSelectionColor"));
282 	//label.setForeground(UIManager.getColor("Tree.textNonSelectionColor"));
283 	label.setBackground(tree.getBackground());
284       }
285 
286       ObjectNode node = (ObjectNode) value;
287       label.setText(node.getTitle());
288       label.setIcon(node.getIcon());
289       return label;
290     }
291   }
292 }