KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > debugger > jpda > models > LocalsTreeModel


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.debugger.jpda.models;
21
22 import com.sun.jdi.AbsentInformationException;
23 import com.sun.jdi.ArrayReference;
24 import com.sun.jdi.InternalException;
25 import com.sun.jdi.InvalidStackFrameException;
26 import com.sun.jdi.LocalVariable;
27 import com.sun.jdi.NativeMethodException;
28 import com.sun.jdi.ObjectReference;
29 import com.sun.jdi.ReferenceType;
30 import com.sun.jdi.StackFrame;
31 import com.sun.jdi.VMDisconnectedException;
32 import com.sun.jdi.Value;
33 import java.beans.Customizer JavaDoc;
34
35 import java.beans.PropertyChangeEvent JavaDoc;
36 import java.beans.PropertyChangeListener JavaDoc;
37 import java.lang.ref.WeakReference JavaDoc;
38 import java.util.ArrayList JavaDoc;
39 import java.util.List JavaDoc;
40 import java.util.Map JavaDoc;
41 import java.util.Vector JavaDoc;
42 import java.util.WeakHashMap JavaDoc;
43 import org.netbeans.api.debugger.jpda.JPDAClassType;
44 import org.netbeans.spi.debugger.ContextProvider;
45 import org.netbeans.api.debugger.jpda.JPDADebugger;
46 import org.netbeans.api.debugger.jpda.Variable;
47 import org.netbeans.spi.debugger.jpda.EditorContext.Operation;
48 import org.netbeans.spi.viewmodel.ModelEvent;
49 import org.netbeans.spi.viewmodel.TreeModel;
50 import org.netbeans.spi.viewmodel.ModelListener;
51 import org.netbeans.spi.viewmodel.UnknownTypeException;
52
53 import org.netbeans.modules.debugger.jpda.JPDADebuggerImpl;
54
55 import org.openide.util.RequestProcessor;
56
57
58 /**
59  * @author Jan Jancura
60  */

61 public class LocalsTreeModel implements TreeModel, PropertyChangeListener JavaDoc {
62
63     
64     private static boolean verbose =
65         (System.getProperty ("netbeans.debugger.viewrefresh") != null) &&
66         (System.getProperty ("netbeans.debugger.viewrefresh").indexOf ('l') >= 0);
67     
68     /** Nest array elements when array length is bigger then this. */
69     private static final int ARRAY_CHILDREN_NESTED_LENGTH = 100;
70     
71     
72     private JPDADebuggerImpl debugger;
73     private Listener JavaDoc listener;
74     private List JavaDoc<ModelListener> listeners = new ArrayList JavaDoc<ModelListener>();
75     //private Map cachedLocals = new WeakHashMap();
76
private Map JavaDoc<Value, ArrayChildrenNode> cachedArrayChildren = new WeakHashMap JavaDoc<Value, ArrayChildrenNode>();
77     
78     
79     public LocalsTreeModel (ContextProvider lookupProvider) {
80         debugger = (JPDADebuggerImpl) lookupProvider.
81             lookupFirst (null, JPDADebugger.class);
82     }
83     
84     public Object JavaDoc getRoot () {
85         return ROOT;
86     }
87     
88     public void propertyChange(PropertyChangeEvent JavaDoc evt) {
89         fireTableValueChangedChanged(evt.getSource(), null);
90     }
91     
92     public Object JavaDoc[] getChildren (Object JavaDoc o, int from, int to)
93     throws UnknownTypeException {
94         Object JavaDoc[] ch = getChildrenImpl(o, from, to);
95         for (int i = 0; i < ch.length; i++) {
96             if (ch[i] instanceof Customizer JavaDoc) {
97                 ((Customizer JavaDoc) ch[i]).addPropertyChangeListener(this);
98             }
99         }
100         return ch;
101     }
102     
103     public Object JavaDoc[] getChildrenImpl (Object JavaDoc o, int from, int to)
104     throws UnknownTypeException {
105         try {
106             if (o.equals (ROOT)) {
107                 Object JavaDoc[] os = getLocalVariables (from, to);
108                 return os;
109             } else
110             if (o instanceof AbstractVariable) { // ThisVariable & FieldVariable
111
AbstractVariable abstractVariable = (AbstractVariable) o;
112                 boolean isArray =
113                         abstractVariable.getInnerValue () instanceof ArrayReference;
114                 if (isArray) {
115                     to = abstractVariable.getFieldsCount ();
116                     // We need to reset it for arrays, to get the full array
117
}
118                 if (isArray && (to - from) > ARRAY_CHILDREN_NESTED_LENGTH) {
119                     ArrayChildrenNode achn =
120                             cachedArrayChildren.get(abstractVariable.getInnerValue ());
121                     if (achn == null) {
122                         achn = new ArrayChildrenNode(abstractVariable);
123                         cachedArrayChildren.put(abstractVariable.getInnerValue (), achn);
124                     } else {
125                         achn.update(abstractVariable);
126                     }
127                     return achn.getChildren();
128                 } else {
129                     return abstractVariable.getFields (from, Math.min(to, abstractVariable.getFieldsCount()));
130                 }
131             } else
132             if (o instanceof ArrayChildrenNode) {
133                 return ((ArrayChildrenNode) o).getChildren();
134             } else
135             if (o instanceof JPDAClassType) {
136                 JPDAClassType clazz = (JPDAClassType) o;
137                 List JavaDoc staticFields = clazz.staticFields();
138                 Object JavaDoc[] fields = new Object JavaDoc[1 + staticFields.size()];
139                 fields[0] = clazz.classObject();
140                 System.arraycopy(staticFields.toArray(), 0, fields, 1, staticFields.size());
141                 return fields;
142             } else
143             if ("lastOperations" == o) {
144                 CallStackFrameImpl frame = (CallStackFrameImpl) debugger.
145                     getCurrentCallStackFrame ();
146                 if (frame == null) {
147                     return new Object JavaDoc[] {};
148                 }
149                 List JavaDoc<Operation> operations = frame.getThread().getLastOperations();
150                 List JavaDoc<Variable> lastOperationValues = new ArrayList JavaDoc<Variable>(operations.size());
151                 for (int i = 0; i < operations.size(); i++) {
152                     Variable ret = operations.get(i).getReturnValue();
153                     if (ret != null) {
154                         lastOperationValues.add(ret);
155                     }
156                 }
157                 return lastOperationValues.toArray();
158             } else
159             throw new UnknownTypeException (o);
160         } catch (VMDisconnectedException ex) {
161             return new Object JavaDoc [0];
162         }
163     }
164     
165     /**
166      * Returns number of children for given node.
167      *
168      * @param node the parent node
169      * @throws UnknownTypeException if this TreeModel implementation is not
170      * able to resolve children for given node type
171      *
172      * @return true if node is leaf
173      */

174     public int getChildrenCount (Object JavaDoc node) throws UnknownTypeException {
175         try {
176             if (node.equals (ROOT)) {
177                 // Performance, see issue #59058.
178
return Integer.MAX_VALUE;
179                 /*
180                 CallStackFrameImpl frame = (CallStackFrameImpl) debugger.
181                     getCurrentCallStackFrame ();
182                 if (frame == null)
183                     return 1;
184                 StackFrame sf = frame.getStackFrame ();
185                 if (sf == null)
186                     return 1;
187                 try {
188                     int i = 0;
189                     List<Operation> operations = frame.getThread().getLastOperations();
190                     ReturnVariableImpl returnVariable;
191                     boolean haveLastOperations;
192                     if (operations != null && operations.size() > 0 && operations.get(0).getReturnValue() != null) {
193                         haveLastOperations = true;
194                         returnVariable = null;
195                     } else {
196                         returnVariable = ((JPDAThreadImpl) frame.getThread()).getReturnVariable();
197                         haveLastOperations = false;
198                     }
199                     if (haveLastOperations || returnVariable != null) {
200                         i++;
201                     }
202                     try {
203                         i += sf.visibleVariables ().size ();
204                     } catch (AbsentInformationException ex) {
205                         i++;
206                     }
207                     // This or Static
208                     i++;//if (sf.thisObject () != null) i++;
209                     return i;
210                 } catch (NativeMethodException ex) {
211                     return 1;//throw new NoInformationException ("native method");
212                 } catch (InternalException ex) {
213                     return 1;//throw new NoInformationException ("native method");
214                 } catch (InvalidStackFrameException ex) {
215                     return 1;//throw new NoInformationException ("thread is running");
216                 } catch (VMDisconnectedException ex) {
217                 }
218                 return 0;
219                  */

220             } else
221             if (node instanceof AbstractVariable) { // ThisVariable & FieldVariable
222
AbstractVariable abstractVariable = (AbstractVariable) node;
223                 if (abstractVariable.getInnerValue () instanceof
224                     ArrayReference
225                 ) {
226                     // Performance, see issue #59058.
227
return Integer.MAX_VALUE;
228                     //return Math.min (abstractVariable.getFieldsCount (), ARRAY_CHILDREN_NESTED_LENGTH);
229
}
230                 // Performance, see issue #59058.
231
return Integer.MAX_VALUE;
232                 //return abstractVariable.getFieldsCount ();
233
} else
234             if (node instanceof ArrayChildrenNode) {
235                 // Performance, see issue #59058.
236
return Integer.MAX_VALUE;
237                 //return ((ArrayChildrenNode) node).getChildren().length;
238
} else
239             if (node instanceof JPDAClassType) {
240                 // Performance, see issue #59058.
241
return Integer.MAX_VALUE;
242                 //JPDAClassType clazz = (JPDAClassType) node;
243
//return 1 + clazz.staticFields().size();
244
} else
245             if (node instanceof JPDAClassType) {
246                 JPDAClassType clazz = (JPDAClassType) node;
247                 return 1 + clazz.staticFields().size();
248             } else
249             if ("lastOperations" == node) { // NOI18N
250
CallStackFrameImpl frame = (CallStackFrameImpl) debugger.
251                     getCurrentCallStackFrame ();
252                 if (frame == null) {
253                     return 0;
254                 }
255                 List JavaDoc<Operation> operations = frame.getThread().getLastOperations();
256                 return operations.size();
257             } else
258             throw new UnknownTypeException (node);
259         } catch (VMDisconnectedException ex) {
260         }
261         return 0;
262     }
263     
264     public boolean isLeaf (Object JavaDoc o) throws UnknownTypeException {
265         if (o.equals (ROOT))
266             return false;
267         if (o instanceof AbstractVariable)
268             return !(((AbstractVariable) o).getInnerValue () instanceof ObjectReference);
269         if (o.toString().startsWith("SubArray")) {
270             return false;
271         }
272         if (o.equals ("NoInfo")) // NOI18N
273
return true;
274         if (o instanceof JPDAClassType) return false;
275         if (o == "lastOperations") return false;
276         throw new UnknownTypeException (o);
277     }
278
279
280     public void addModelListener (ModelListener l) {
281         synchronized (listeners) {
282             listeners.add (l);
283             if (listener == null)
284                 listener = new Listener JavaDoc (this, debugger);
285         }
286     }
287
288     public void removeModelListener (ModelListener l) {
289         synchronized (listeners) {
290             listeners.remove (l);
291             if (listeners.size () == 0) {
292                 listener.destroy ();
293                 listener = null;
294             }
295         }
296     }
297     
298     void fireTreeChanged () {
299         List JavaDoc<ModelListener> ls;
300         synchronized (listeners) {
301             ls = new ArrayList JavaDoc<ModelListener>(listeners);
302         }
303         int i, k = ls.size ();
304         for (i = 0; i < k; i++)
305             ls.get(i).modelChanged (
306                 new ModelEvent.TreeChanged (this)
307             );
308     }
309     
310     private void fireTableValueChangedChanged (Object JavaDoc node, String JavaDoc propertyName) {
311         List JavaDoc<ModelListener> ls;
312         synchronized (listeners) {
313             ls = new ArrayList JavaDoc<ModelListener>(listeners);
314         }
315         int i, k = ls.size ();
316         for (i = 0; i < k; i++)
317             ls.get(i).modelChanged (
318                 new ModelEvent.TableValueChanged (this, node, propertyName)
319             );
320     }
321
322     
323     // private methods .........................................................
324

325     private Object JavaDoc[] getLocalVariables (
326         int from,
327         int to
328     ) {
329         synchronized (debugger.LOCK) {
330             CallStackFrameImpl callStackFrame = (CallStackFrameImpl) debugger.
331                 getCurrentCallStackFrame ();
332             if (callStackFrame == null)
333                 return new String JavaDoc [] {"No current thread"};
334             StackFrame stackFrame = callStackFrame.getStackFrame ();
335             if (stackFrame == null)
336                 return new String JavaDoc [] {"No current thread"};
337             try {
338                 ObjectReference thisR = stackFrame.thisObject ();
339                 List JavaDoc<Operation> operations = callStackFrame.getThread().getLastOperations();
340                 ReturnVariableImpl returnVariable;
341                 boolean haveLastOperations;
342                 if (operations != null && operations.size() > 0 && operations.get(0).getReturnValue() != null) {
343                     haveLastOperations = true;
344                     returnVariable = null;
345                 } else {
346                     returnVariable = ((JPDAThreadImpl) callStackFrame.getThread()).getReturnVariable();
347                     haveLastOperations = false;
348                 }
349                 int retValShift = (haveLastOperations || returnVariable != null) ? 1 : 0;
350                 if (thisR == null) {
351                     ReferenceType classType = stackFrame.location().declaringType();
352                     Object JavaDoc[] avs = null;
353                     try {
354                         avs = getLocalVariables (
355                             callStackFrame,
356                             stackFrame,
357                             Math.max (from - retValShift - 1, 0),
358                             Math.max (to - retValShift - 1, 0)
359                         );
360                     } catch (AbsentInformationException ex) {
361                         avs = new String JavaDoc [] {"NoInfo"};
362                     }
363                     Object JavaDoc[] result = new Object JavaDoc [avs.length + retValShift + 1];
364                     if (from < 1 && retValShift > 0) {
365                         if (returnVariable != null) {
366                             result[0] = returnVariable;
367                         } else {
368                             result[0] = "lastOperations"; // NOI18N
369
}
370                     }
371                     if (from < 1 + retValShift) {
372                         //result [0] = new ThisVariable (debugger, classType.classObject(), "");
373
result[retValShift] = debugger.getClassType(classType);
374                     }
375                     System.arraycopy (avs, 0, result, 1 + retValShift, avs.length);
376                     return result;
377                 } else {
378                     Object JavaDoc[] avs = null;
379                     try {
380                         avs = getLocalVariables (
381                             callStackFrame,
382                             stackFrame,
383                             Math.max (from - retValShift - 1, 0),
384                             Math.max (to - retValShift - 1, 0)
385                         );
386                     } catch (AbsentInformationException ex) {
387                         avs = new Object JavaDoc[] {"NoInfo"};
388                     }
389                     Object JavaDoc[] result = new Object JavaDoc [avs.length + retValShift + 1];
390                     if (from < 1 && retValShift > 0) {
391                         if (returnVariable != null) {
392                             result[0] = returnVariable;
393                         } else {
394                             result[0] = "lastOperations"; // NOI18N
395
}
396                     }
397                     if (from < 1 + retValShift) {
398                         result[retValShift] = new ThisVariable (debugger, thisR, "");
399                     }
400                     System.arraycopy (avs, 0, result, 1 + retValShift, avs.length);
401                     return result;
402                 }
403             } catch (InternalException ex) {
404                 return new String JavaDoc [] {ex.getMessage ()};
405             }
406         } // synchronized
407
}
408     
409     org.netbeans.api.debugger.jpda.LocalVariable[] getLocalVariables (
410         final CallStackFrameImpl callStackFrame,
411         final StackFrame stackFrame,
412         int from,
413         int to
414     ) throws AbsentInformationException {
415         org.netbeans.api.debugger.jpda.LocalVariable[] locals = callStackFrame.getLocalVariables();
416         int n = locals.length;
417         to = Math.min(n, to);
418         from = Math.min(n, from);
419         if (from != 0 || to != n) {
420             org.netbeans.api.debugger.jpda.LocalVariable[] subLocals = new org.netbeans.api.debugger.jpda.LocalVariable[to - from];
421             for (int i = from; i < to; i++) {
422                 subLocals[i - from] = locals[i];
423             }
424             locals = subLocals;
425         }
426         return locals;
427         /*
428         try {
429             String className = stackFrame.location ().declaringType ().name ();
430             List l = stackFrame.visibleVariables ();
431             to = Math.min(l.size(), to);
432             from = Math.min(l.size(), from);
433             int i, k = to - from, j = from;
434             AbstractVariable[] locals = new AbstractVariable [k];
435             for (i = 0; i < k; i++) {
436                 LocalVariable lv = (LocalVariable) l.get (j++);
437                 locals [i] = getLocal (lv, callStackFrame, className);
438             }
439             return locals;
440         } catch (NativeMethodException ex) {
441             throw new AbsentInformationException ("native method");
442         } catch (InvalidStackFrameException ex) {
443             throw new AbsentInformationException ("thread is running");
444         } catch (VMDisconnectedException ex) {
445             return new AbstractVariable [0];
446         }
447          */

448     }
449     /*
450     private Local getLocal (LocalVariable lv, CallStackFrameImpl frame, String className) {
451         Value v = frame.getStackFrame ().getValue (lv);
452         Local local = (Local) cachedLocals.get(lv);
453         if (local != null) {
454             local.setInnerValue(v);
455             local.setFrame(frame);
456             local.setLocalVariable(lv);
457         } else {
458             if (v instanceof ObjectReference) {
459                 local = new ObjectLocalVariable (
460                     debugger,
461                     v,
462                     className,
463                     lv,
464                     JPDADebuggerImpl.getGenericSignature (lv),
465                     frame
466                 );
467             } else {
468                 local = new Local (debugger, v, className, lv, frame);
469             }
470             cachedLocals.put(lv, local);
471         }
472         return local;
473     }
474      */

475     
476     public Variable getVariable (Value v) {
477         if (v instanceof ObjectReference)
478             return new AbstractVariable (
479                 debugger,
480                 (ObjectReference) v,
481                 null
482             );
483         return new AbstractVariable (debugger, v, null);
484     }
485     
486     
487     JPDADebuggerImpl getDebugger () {
488         return debugger;
489     }
490     
491     
492     // innerclasses ............................................................
493

494     private static class Listener implements PropertyChangeListener JavaDoc {
495         
496         private JPDADebugger debugger;
497         private WeakReference JavaDoc<LocalsTreeModel> model;
498         
499         public Listener (
500             LocalsTreeModel tm,
501             JPDADebugger debugger
502         ) {
503             this.debugger = debugger;
504             model = new WeakReference JavaDoc<LocalsTreeModel>(tm);
505             debugger.addPropertyChangeListener (this);
506         }
507         
508         void destroy () {
509             debugger.removePropertyChangeListener (this);
510             if (task != null) {
511                 // cancel old task
512
task.cancel ();
513                 if (verbose)
514                     System.out.println("LTM cancel old task " + task);
515                 task = null;
516             }
517         }
518         
519         private LocalsTreeModel getModel () {
520             LocalsTreeModel tm = model.get ();
521             if (tm == null) {
522                 destroy ();
523             }
524             return tm;
525         }
526         
527         // currently waiting / running refresh task
528
// there is at most one
529
private RequestProcessor.Task task;
530         
531         public void propertyChange (PropertyChangeEvent JavaDoc e) {
532             if ( ( (e.getPropertyName () ==
533                      JPDADebugger.PROP_CURRENT_CALL_STACK_FRAME) ||
534                    //(e.getPropertyName () == debugger.PROP_CURRENT_THREAD) ||
535
(e.getPropertyName () == JPDADebugger.PROP_STATE)
536                  ) && (debugger.getState () == JPDADebugger.STATE_STOPPED)
537             ) {
538                 // IF state has been changed to STOPPED or
539
// IF current call stack frame has been changed & state is stoped
540
final LocalsTreeModel ltm = getModel ();
541                 if (ltm == null) return;
542                 if (task != null) {
543                     // cancel old task
544
task.cancel ();
545                     if (verbose)
546                         System.out.println("LTM cancel old task " + task);
547                     task = null;
548                 }
549                 task = RequestProcessor.getDefault ().post (new Runnable JavaDoc () {
550                     public void run () {
551                         if (debugger.getState () != JPDADebugger.STATE_STOPPED) {
552                             if (verbose)
553                                 System.out.println("LTM cancel started task " + task);
554                             return;
555                         }
556                         if (verbose)
557                             System.out.println("LTM do task " + task);
558                         ltm.fireTreeChanged ();
559                     }
560                 }, 500);
561                 if (verbose)
562                     System.out.println("LTM create task " + task);
563             } else
564             if ( (e.getPropertyName () == JPDADebugger.PROP_STATE) &&
565                  (debugger.getState () != JPDADebugger.STATE_STOPPED) &&
566                  (task != null)
567             ) {
568                 // debugger has been resumed
569
// =>> cancel task
570
task.cancel ();
571                 if (verbose)
572                     System.out.println("LTM cancel task " + task);
573                 task = null;
574             }
575         }
576     }
577     
578     /**
579      * The hierarchical representation of nested array elements.
580      * Used for arrays longer then {@link #ARRAY_CHILDREN_NESTED_LENGTH}.
581      */

582     private static final class ArrayChildrenNode {
583         
584         private AbstractVariable var;
585         private int from = 0;
586         private int length;
587         private int maxIndexLog;
588         
589         public ArrayChildrenNode(AbstractVariable var) {
590             this(var, 0, var.getFieldsCount(), -1);
591         }
592         
593         private ArrayChildrenNode(AbstractVariable var, int from, int length,
594                                   int maxIndex) {
595             this.var = var;
596             this.from = from;
597             this.length = length;
598             if (maxIndex < 0) {
599                 maxIndex = from + length - 1;
600             }
601             this.maxIndexLog = ArrayFieldVariable.log10(maxIndex);
602         }
603         
604         private static int pow(int a, int b) {
605             if (b == 0) return 1;
606             int p = a;
607             for (int i = 1; i < b; i++) {
608                 p *= a;
609             }
610             return p;
611         }
612         
613         public Object JavaDoc[] getChildren() {
614             if (length > ARRAY_CHILDREN_NESTED_LENGTH) {
615                 int depth = (int) Math.ceil(Math.log(length)/Math.log(ARRAY_CHILDREN_NESTED_LENGTH) - 1);
616                 int n = pow(ARRAY_CHILDREN_NESTED_LENGTH, depth);
617                 int numCh = (int) Math.ceil(length/((double) n));
618                 
619                 // We have 'numCh' children, each with 'n' sub-children (or possibly less for the last one)
620
Object JavaDoc[] ch = new Object JavaDoc[numCh];
621                 for (int i = 0; i < numCh; i++) {
622                     int chLength = n;
623                     if (i == (numCh - 1)) {
624                         chLength = length % n;
625                         if (chLength == 0) chLength = n;
626                     }
627                     ch[i] = new ArrayChildrenNode(var, from + i*n, chLength, from + length - 1);
628                 }
629                 return ch;
630             } else {
631                 return var.getFields(from, from + length);
632             }
633         }
634         
635         public void update(AbstractVariable var) {
636             this.var = var;
637         }
638         
639         /** Overriden equals so that the nodes are not re-created when not necessary. */
640         public boolean equals(Object JavaDoc obj) {
641             if (!(obj instanceof ArrayChildrenNode)) return false;
642             ArrayChildrenNode achn = (ArrayChildrenNode) obj;
643             return achn.var.equals(this.var) &&
644                    achn.from == this.from &&
645                    achn.length == this.length;
646         }
647         
648         public int hashCode() {
649             return var.hashCode() + from + length;
650         }
651         
652         public String JavaDoc toString() {
653             int num0 = maxIndexLog - ArrayFieldVariable.log10(from);
654             String JavaDoc froms;
655             if (num0 > 0) {
656                 froms = ArrayFieldVariable.zeros(2*num0) + from; // One space is roughly 1/2 of width of a number
657
} else {
658                 froms = Integer.toString(from);
659             }
660             int last = from + length - 1;
661             num0 = maxIndexLog - ArrayFieldVariable.log10(last);
662             String JavaDoc lasts;
663             if (num0 > 0) {
664                 lasts = ArrayFieldVariable.zeros(2*num0) + last; // One space is roughly 1/2 of width of a number
665
} else {
666                 lasts = Integer.toString(last);
667             }
668             return "SubArray"+froms+"-"+lasts; // NOI18N
669
}
670         
671     }
672 }
673
Popular Tags