OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [javax/] [swing/] [text/] [ZoneView.java] - Blame information for rev 772

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 772 jeremybenn
/* ZoneView.java -- An effective BoxView subclass
2
   Copyright (C) 2006 Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
 
39
package javax.swing.text;
40
 
41
import java.awt.Shape;
42
import java.util.ArrayList;
43
import java.util.LinkedList;
44
 
45
import javax.swing.event.DocumentEvent;
46
 
47
/**
48
 * A View implementation that delays loading of sub views until they are
49
 * needed for display or internal transformations. This can be used for
50
 * editors that need to handle large documents more effectivly than the
51
 * standard {@link BoxView}.
52
 *
53
 * @author Roman Kennke (kennke@aicas.com)
54
 *
55
 * @since 1.3
56
 */
57
public class ZoneView
58
  extends BoxView
59
{
60
 
61
  /**
62
   * The default zone view implementation. The specs suggest that this is
63
   * a subclass of AsyncBoxView, so do we.
64
   */
65
  static class Zone
66
    extends AsyncBoxView
67
  {
68
    /**
69
     * The start position for this zone.
70
     */
71
    private Position p0;
72
 
73
    /**
74
     * The end position for this zone.
75
     */
76
    private Position p1;
77
 
78
    /**
79
     * Creates a new Zone for the specified element, start and end positions.
80
     *
81
     * @param el the element
82
     * @param pos0 the start position
83
     * @param pos1 the end position
84
     * @param axis the major axis
85
     */
86
    Zone(Element el, Position pos0, Position pos1, int axis)
87
    {
88
      super(el, axis);
89
      p0 = pos0;
90
      p1 = pos1;
91
    }
92
 
93
    /**
94
     * Returns the start offset of the zone.
95
     *
96
     * @return the start offset of the zone
97
     */
98
    public int getStartOffset()
99
    {
100
      return p0.getOffset();
101
    }
102
 
103
    /**
104
     * Returns the end offset of the zone.
105
     *
106
     * @return the end offset of the zone
107
     */
108
    public int getEndOffset()
109
    {
110
      return p1.getOffset();
111
    }
112
  }
113
 
114
  /**
115
   * The maximumZoneSize.
116
   */
117
  private int maximumZoneSize;
118
 
119
  /**
120
   * The maximum number of loaded zones.
121
   */
122
  private int maxZonesLoaded;
123
 
124
  /**
125
   * A queue of loaded zones. When the number of loaded zones exceeds the
126
   * maximum number of zones, the oldest zone(s) get unloaded.
127
   */
128
  private LinkedList loadedZones;
129
 
130
  /**
131
   * Creates a new ZoneView for the specified element and axis.
132
   *
133
   * @param element the element for which to create a ZoneView
134
   * @param axis the major layout axis for the box
135
   */
136
  public ZoneView(Element element, int axis)
137
  {
138
    super(element, axis);
139
    maximumZoneSize = 8192;
140
    maxZonesLoaded = 3;
141
    loadedZones = new LinkedList();
142
  }
143
 
144
  /**
145
   * Sets the maximum zone size. Note that zones might still become larger
146
   * then the size specified when a singe child view is larger for itself,
147
   * because zones are formed on child view boundaries.
148
   *
149
   * @param size the maximum zone size to set
150
   *
151
   * @see #getMaximumZoneSize()
152
   */
153
  public void setMaximumZoneSize(int size)
154
  {
155
    maximumZoneSize = size;
156
  }
157
 
158
  /**
159
   * Returns the maximum zone size. Note that zones might still become larger
160
   * then the size specified when a singe child view is larger for itself,
161
   * because zones are formed on child view boundaries.
162
   *
163
   * @return the maximum zone size
164
   *
165
   * @see #setMaximumZoneSize(int)
166
   */
167
  public int getMaximumZoneSize()
168
  {
169
    return maximumZoneSize;
170
  }
171
 
172
  /**
173
   * Sets the maximum number of zones that are allowed to be loaded at the
174
   * same time. If the new number of allowed zones is smaller then the
175
   * previous settings, this unloads all zones the aren't allowed to be
176
   * loaded anymore.
177
   *
178
   * @param num the number of zones allowed to be loaded at the same time
179
   *
180
   * @throws IllegalArgumentException if <code>num &lt;= 0</code>
181
   *
182
   * @see #getMaxZonesLoaded()
183
   */
184
  public void setMaxZonesLoaded(int num)
185
  {
186
    if (num < 1)
187
      throw new IllegalArgumentException("Illegal number of zones");
188
    maxZonesLoaded = num;
189
    unloadOldestZones();
190
  }
191
 
192
  /**
193
   * Returns the number of zones that are allowed to be loaded.
194
   *
195
   * @return the number of zones that are allowed to be loaded
196
   *
197
   * @see #setMaxZonesLoaded(int)
198
   */
199
  public int getMaxZonesLoaded()
200
  {
201
    return maxZonesLoaded;
202
  }
203
 
204
  /**
205
   * Gets called after a zone has been loaded. This unloads the oldest zone(s)
206
   * when the maximum number of zones is reached.
207
   *
208
   * @param zone the zone that has been loaded
209
   */
210
  protected void zoneWasLoaded(View zone)
211
  {
212
    loadedZones.addLast(zone);
213
    unloadOldestZones();
214
  }
215
 
216
  /**
217
   * This unloads the specified zone. This is implemented to simply remove
218
   * all child views from that zone.
219
   *
220
   * @param zone the zone to be unloaded
221
   */
222
  protected void unloadZone(View zone)
223
  {
224
    zone.removeAll();
225
  }
226
 
227
  /**
228
   * Returns <code>true</code> when the specified zone is loaded,
229
   * <code>false</code> otherwise. The default implementation checks if
230
   * the zone view has child elements.
231
   *
232
   * @param zone the zone view to check
233
   *
234
   * @return <code>true</code> when the specified zone is loaded,
235
   *         <code>false</code> otherwise
236
   */
237
  protected boolean isZoneLoaded(View zone)
238
  {
239
    return zone.getViewCount() > 0;
240
  }
241
 
242
  /**
243
   * Creates a zone for the specified range. Subclasses can override this
244
   * to provide a custom implementation for the zones.
245
   *
246
   * @param p0 the start of the range
247
   * @param p1 the end of the range
248
   *
249
   * @return the zone
250
   */
251
  protected View createZone(int p0, int p1)
252
  {
253
    Document doc = getDocument();
254
    Position pos0 = null;
255
    Position pos1 = null;
256
    try
257
      {
258
        pos0 = doc.createPosition(p0);
259
        pos1 = doc.createPosition(p1);
260
      }
261
    catch (BadLocationException ex)
262
      {
263
        assert false : "Must not happen";
264
      }
265
    Zone zone = new Zone(getElement(), pos0, pos1, getAxis());
266
    return zone;
267
  }
268
 
269
  // --------------------------------------------------------------------------
270
  // CompositeView methods.
271
  // --------------------------------------------------------------------------
272
 
273
  /**
274
   * Overridden to not load all the child views. This methods creates
275
   * initial zones without actually loading them.
276
   *
277
   * @param vf not used
278
   */
279
  protected void loadChildren(ViewFactory vf)
280
  {
281
    int p0 = getStartOffset();
282
    int p1 = getEndOffset();
283
    append(createZone(p0, p1));
284
    checkZoneAt(p0);
285
  }
286
 
287
  /**
288
   * Returns the index of the child view at the document position
289
   * <code>pos</code>.
290
   *
291
   * This overrides the CompositeView implementation because the ZoneView does
292
   * not provide a one to one mapping from Elements to Views.
293
   *
294
   * @param pos the document position
295
   *
296
   * @return the index of the child view at the document position
297
   *         <code>pos</code>
298
   */
299
  protected int getViewIndexAtPosition(int pos)
300
  {
301
    int index = -1;
302
    boolean found = false;
303
    if (pos >= getStartOffset() && pos <= getEndOffset())
304
      {
305
        int upper = getViewCount() - 1;
306
        int lower = 0;
307
        index = (upper - lower) / 2 + lower;
308
        int bias = 0;
309
        do
310
          {
311
            View child = getView(index);
312
            int childStart = child.getStartOffset();
313
            int childEnd = child.getEndOffset();
314
            if (pos >= childStart && pos < childEnd)
315
              found = true;
316
            else if (pos < childStart)
317
              {
318
                upper = index;
319
                bias = -1;
320
              }
321
            else if (pos >= childEnd)
322
              {
323
                lower = index;
324
                bias = 1;
325
              }
326
            if (! found)
327
              {
328
                int newIndex = (upper - lower) / 2 + lower;
329
                if (newIndex == index)
330
                  index = newIndex + bias;
331
                else
332
                  index = newIndex;
333
              }
334
          } while (upper != lower && ! found);
335
      }
336
    // If no child view actually covers the specified offset, reset index to
337
    // -1.
338
    if (! found)
339
      index = -1;
340
    return index;
341
  }
342
 
343
  // --------------------------------------------------------------------------
344
  // View methods.
345
  // --------------------------------------------------------------------------
346
 
347
  public void insertUpdate(DocumentEvent e, Shape a, ViewFactory vf)
348
  {
349
    // TODO: Implement this.
350
  }
351
 
352
  public void removeUpdate(DocumentEvent e, Shape a, ViewFactory vf)
353
  {
354
    // TODO: Implement this.
355
  }
356
 
357
  protected boolean updateChildren(DocumentEvent.ElementChange ec,
358
                                   DocumentEvent e, ViewFactory vf)
359
  {
360
    // TODO: Implement this.
361
    return false;
362
  }
363
 
364
  // --------------------------------------------------------------------------
365
  // Internal helper methods.
366
  // --------------------------------------------------------------------------
367
 
368
  /**
369
   * A helper method to unload the oldest zones when there are more loaded
370
   * zones then allowed.
371
   */
372
  private void unloadOldestZones()
373
  {
374
    int maxZones = getMaxZonesLoaded();
375
    while (loadedZones.size() > maxZones)
376
      {
377
        View zone = (View) loadedZones.removeFirst();
378
        unloadZone(zone);
379
      }
380
  }
381
 
382
  /**
383
   * Checks if the zone view at position <code>pos</code> should be split
384
   * (its size is greater than maximumZoneSize) and tries to split it.
385
   *
386
   * @param pos the document position to check
387
   */
388
  private void checkZoneAt(int pos)
389
  {
390
    int viewIndex = getViewIndexAtPosition(pos); //, Position.Bias.Forward);
391
    View view = getView(viewIndex);
392
    int p0 = view.getStartOffset();
393
    int p1 = view.getEndOffset();
394
    if (p1 - p0 > maximumZoneSize)
395
      splitZone(viewIndex, p0, p1);
396
  }
397
 
398
  /**
399
   * Tries to break the view at the specified index and inside the specified
400
   * range into pieces that are acceptable with respect to the maximum zone
401
   * size.
402
   *
403
   * @param index the index of the view to split
404
   * @param p0 the start offset
405
   * @param p1 the end offset
406
   */
407
  private void splitZone(int index, int p0, int p1)
408
  {
409
    ArrayList newZones = new ArrayList();
410
    int p = p0;
411
    do
412
      {
413
        p0 = p;
414
        p = Math.min(getPreferredZoneEnd(p0), p1);
415
        newZones.add(createZone(p0, p));
416
      } while (p < p1);
417
    View[] newViews = new View[newZones.size()];
418
    newViews = (View[]) newZones.toArray(newViews);
419
    replace(index, 1, newViews);
420
  }
421
 
422
  /**
423
   * Calculates the positions at which a zone split is performed. This
424
   * tries to create zones sized close to half the maximum zone size.
425
   *
426
   * @param start the start offset
427
   *
428
   * @return the preferred end offset
429
   */
430
  private int getPreferredZoneEnd(int start)
431
  {
432
    Element el = getElement();
433
    int index = el.getElementIndex(start + (maximumZoneSize / 2));
434
    Element child = el.getElement(index);
435
    int p0 = child.getStartOffset();
436
    int p1 = child.getEndOffset();
437
    int end = p1;
438
    if (p0 - start > maximumZoneSize && p0 > start)
439
      end = p0;
440
    return end;
441
  }
442
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.