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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 772 jeremybenn
/* ComponentView.java --
2
   Copyright (C) 2002, 2004, 2005 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
package javax.swing.text;
39
 
40
import java.awt.Component;
41
import java.awt.Container;
42
import java.awt.Dimension;
43
import java.awt.Graphics;
44
import java.awt.Rectangle;
45
import java.awt.Shape;
46
 
47
import javax.swing.SwingUtilities;
48
 
49
/**
50
 * A {@link View} implementation that is able to render arbitrary
51
 * {@link Component}s. This uses the attribute
52
 * {@link StyleConstants#ComponentAttribute} to determine the
53
 * <code>Component</code> that should be rendered. This <code>Component</code>
54
 * becomes a direct child of the <code>JTextComponent</code> that contains
55
 * this <code>ComponentView</code>, so this view must not be shared between
56
 * multiple <code>JTextComponent</code>s.
57
 *
58
 * @author Roman Kennke (kennke@aicas.com)
59
 * @author original author unknown
60
 */
61
public class ComponentView extends View
62
{
63
 
64
  /**
65
   * A special container that sits between the component and the hosting
66
   * container. This is used to propagate invalidate requests and cache
67
   * the component's layout sizes.
68
   */
69
  private class Interceptor
70
    extends Container
71
  {
72
    Dimension min;
73
    Dimension pref;
74
    Dimension max;
75
    float alignX;
76
    float alignY;
77
 
78
    /**
79
     * Creates a new instance that hosts the specified component.
80
     */
81
    Interceptor(Component c)
82
    {
83
      setLayout(null);
84
      add(c);
85
      cacheComponentSizes();
86
    }
87
 
88
    /**
89
     * Intercepts the normal invalidate call and propagates the invalidate
90
     * request up using the View's preferenceChanged().
91
     */
92
    public void invalidate()
93
    {
94
      super.invalidate();
95
      if (getParent() != null)
96
        preferenceChanged(null, true, true);
97
    }
98
 
99
    /**
100
     * This is overridden to simply cache the layout sizes.
101
     */
102
    public void doLayout()
103
    {
104
      cacheComponentSizes();
105
    }
106
 
107
    /**
108
     * Overridden to also reshape the component itself.
109
     */
110
    public void reshape(int x, int y, int w, int h)
111
    {
112
      super.reshape(x, y, w, h);
113
      if (getComponentCount() > 0)
114
        getComponent(0).setSize(w, h);
115
      cacheComponentSizes();
116
    }
117
 
118
    /**
119
     * Overridden to also show the component.
120
     */
121
    public void show()
122
    {
123
      super.show();
124
      if (getComponentCount() > 0)
125
        getComponent(0).setVisible(true);
126
    }
127
 
128
    /**
129
     * Overridden to also hide the component.
130
     */
131
    public void hide()
132
    {
133
      super.hide();
134
      if (getComponentCount() > 0)
135
        getComponent(0).setVisible(false);
136
    }
137
 
138
    /**
139
     * Overridden to return the cached value.
140
     */
141
    public Dimension getMinimumSize()
142
    {
143
      maybeValidate();
144
      return min;
145
    }
146
 
147
    /**
148
     * Overridden to return the cached value.
149
     */
150
    public Dimension getPreferredSize()
151
    {
152
      maybeValidate();
153
      return pref;
154
    }
155
 
156
    /**
157
     * Overridden to return the cached value.
158
     */
159
    public Dimension getMaximumSize()
160
    {
161
      maybeValidate();
162
      return max;
163
    }
164
 
165
    /**
166
     * Overridden to return the cached value.
167
     */
168
    public float getAlignmentX()
169
    {
170
      maybeValidate();
171
      return alignX;
172
    }
173
 
174
    /**
175
     * Overridden to return the cached value.
176
     */
177
    public float getAlignmentY()
178
    {
179
      maybeValidate();
180
      return alignY;
181
    }
182
 
183
    /**
184
     * Validates the container only when necessary.
185
     */
186
    private void maybeValidate()
187
    {
188
      if (! isValid())
189
        validate();
190
    }
191
 
192
    /**
193
     * Fetches the component layout sizes into the cache.
194
     */
195
    private void cacheComponentSizes()
196
    {
197
      if (getComponentCount() > 0)
198
        {
199
          Component c = getComponent(0);
200
          min = c.getMinimumSize();
201
          pref = c.getPreferredSize();
202
          max = c.getMaximumSize();
203
          alignX = c.getAlignmentX();
204
          alignY = c.getAlignmentY();
205
        }
206
    }
207
  }
208
 
209
  /**
210
   * The component that is displayed by this view.
211
   */
212
  private Component comp;
213
 
214
  /**
215
   * The intercepting container.
216
   */
217
  private Interceptor interceptor;
218
 
219
  /**
220
   * Creates a new instance of <code>ComponentView</code> for the specified
221
   * <code>Element</code>.
222
   *
223
   * @param elem the element that this <code>View</code> is rendering
224
   */
225
  public ComponentView(Element elem)
226
  {
227
    super(elem);
228
  }
229
 
230
  /**
231
   * Creates the <code>Component</code> that this <code>View</code> is
232
   * rendering. The <code>Component</code> is determined using
233
   * the {@link StyleConstants#ComponentAttribute} of the associated
234
   * <code>Element</code>.
235
   *
236
   * @return the component that is rendered
237
   */
238
  protected Component createComponent()
239
  {
240
    return StyleConstants.getComponent(getElement().getAttributes());
241
  }
242
 
243
  /**
244
   * Returns the alignment of this <code>View</code> along the specified axis.
245
   *
246
   * @param axis either {@link View#X_AXIS} or {@link View#Y_AXIS}
247
   *
248
   * @return the alignment of this <code>View</code> along the specified axis
249
   */
250
  public float getAlignment(int axis)
251
  {
252
    float align = 0.0F;
253
    // I'd rather throw an IllegalArgumentException for illegal axis,
254
    // but the Harmony testsuite indicates fallback to super behaviour.
255
    if (interceptor != null && (axis == X_AXIS || axis == Y_AXIS))
256
      {
257
        if (axis == X_AXIS)
258
          align = interceptor.getAlignmentX();
259
        else if (axis == Y_AXIS)
260
          align = interceptor.getAlignmentY();
261
        else
262
          assert false : "Must not reach here";
263
      }
264
    else
265
      align = super.getAlignment(axis);
266
    return align;
267
  }
268
 
269
  /**
270
   * Returns the <code>Component</code> that is rendered by this
271
   * <code>ComponentView</code>.
272
   *
273
   * @return the <code>Component</code> that is rendered by this
274
   *         <code>ComponentView</code>
275
   */
276
  public final Component getComponent()
277
  {
278
    return comp;
279
  }
280
 
281
  /**
282
   * Returns the maximum span of this <code>View</code> along the specified
283
   * axis.
284
   *
285
   * This will return {@link Component#getMaximumSize()} for the specified
286
   * axis.
287
   *
288
   * @return the maximum span of this <code>View</code> along the specified
289
   *         axis
290
   */
291
  public float getMaximumSpan(int axis)
292
  {
293
    if (axis != X_AXIS && axis != Y_AXIS)
294
      throw new IllegalArgumentException("Illegal axis");
295
    float span = 0;
296
    if (interceptor != null)
297
      {
298
        if (axis == X_AXIS)
299
          span = interceptor.getMaximumSize().width;
300
        else if (axis == Y_AXIS)
301
          span = interceptor.getMaximumSize().height;
302
        else
303
          assert false : "Must not reach here";
304
      }
305
    return span;
306
  }
307
 
308
  public float getMinimumSpan(int axis)
309
  {
310
    if (axis != X_AXIS && axis != Y_AXIS)
311
      throw new IllegalArgumentException("Illegal axis");
312
    float span = 0;
313
    if (interceptor != null)
314
      {
315
        if (axis == X_AXIS)
316
          span = interceptor.getMinimumSize().width;
317
        else if (axis == Y_AXIS)
318
          span = interceptor.getMinimumSize().height;
319
        else
320
          assert false : "Must not reach here";
321
      }
322
    return span;
323
  }
324
 
325
  public float getPreferredSpan(int axis)
326
  {
327
    if (axis != X_AXIS && axis != Y_AXIS)
328
      throw new IllegalArgumentException("Illegal axis");
329
    float span = 0;
330
    if (interceptor != null)
331
      {
332
        if (axis == X_AXIS)
333
          span = interceptor.getPreferredSize().width;
334
        else if (axis == Y_AXIS)
335
          span = interceptor.getPreferredSize().height;
336
        else
337
          assert false : "Must not reach here";
338
      }
339
    return span;
340
  }
341
 
342
  public Shape modelToView(int pos, Shape a, Position.Bias b)
343
    throws BadLocationException
344
  {
345
    int p0 = getStartOffset();
346
    int p1 = getEndOffset();
347
    if (pos >= p0 && pos <= p1)
348
      {
349
        Rectangle viewRect = a.getBounds();
350
        if (pos == p1)
351
          viewRect.x += viewRect.width;
352
        viewRect.width = 0;
353
        return viewRect;
354
      }
355
    else
356
      throw new BadLocationException("Illegal position", pos);
357
  }
358
 
359
  /**
360
   * The real painting behavour is performed by normal component painting,
361
   * triggered by the text component that hosts this view. This method does
362
   * not paint by itself. However, it sets the size of the component according
363
   * to the allocation that is passed here.
364
   *
365
   * @param g the graphics context
366
   * @param a the allocation of the child
367
   */
368
  public void paint(Graphics g, Shape a)
369
  {
370
    if (interceptor != null)
371
      {
372
        Rectangle r = a instanceof Rectangle ? (Rectangle) a : a.getBounds();
373
        interceptor.setBounds(r.x, r.y, r.width, r.height);
374
      }
375
  }
376
 
377
  /**
378
   * This sets up the component when the view is added to its parent, or
379
   * cleans up the view when it is removed from its parent.
380
   *
381
   * When this view is added to a parent view, the component of this view
382
   * is added to the container that hosts this view. When <code>p</code> is
383
   * <code>null</code>, then the view is removed from it's parent and we have
384
   * to also remove the component from it's parent container.
385
   *
386
   * @param p the parent view or <code>null</code> if this view is removed
387
   *        from it's parent
388
   */
389
  public void setParent(final View p)
390
  {
391
    super.setParent(p);
392
    if (SwingUtilities.isEventDispatchThread())
393
      setParentImpl();
394
    else
395
      SwingUtilities.invokeLater
396
      (new Runnable()
397
       {
398
         public void run()
399
         {
400
           Document doc = getDocument();
401
           try
402
             {
403
               if (doc instanceof AbstractDocument)
404
                 ((AbstractDocument) doc).readLock();
405
               setParentImpl();
406
               Container host = getContainer();
407
               if (host != null)
408
                 {
409
                   preferenceChanged(null, true, true);
410
                   host.repaint();
411
                 }
412
             }
413
           finally
414
             {
415
               if (doc instanceof AbstractDocument)
416
                 ((AbstractDocument) doc).readUnlock();
417
             }
418
         }
419
       });
420
  }
421
 
422
  /**
423
   * The implementation of {@link #setParent}. This is package private to
424
   * avoid a synthetic accessor method.
425
   */
426
  void setParentImpl()
427
  {
428
    View p = getParent();
429
    if (p != null)
430
      {
431
        Container c = getContainer();
432
        if (c != null)
433
          {
434
            if (interceptor == null)
435
              {
436
                // Create component and put it inside the interceptor.
437
                Component created = createComponent();
438
                if (created != null)
439
                  {
440
                    comp = created;
441
                    interceptor = new Interceptor(comp);
442
                  }
443
              }
444
            if (interceptor != null)
445
              {
446
                // Add the interceptor to the hosting container.
447
                if (interceptor.getParent() == null)
448
                  c.add(interceptor, this);
449
              }
450
          }
451
      }
452
    else
453
      {
454
        if (interceptor != null)
455
          {
456
            Container parent = interceptor.getParent();
457
            if (parent != null)
458
              parent.remove(interceptor);
459
          }
460
      }
461
  }
462
 
463
  /**
464
   * Maps coordinates from the <code>View</code>'s space into a position
465
   * in the document model.
466
   *
467
   * @param x the x coordinate in the view space
468
   * @param y the y coordinate in the view space
469
   * @param a the allocation of this <code>View</code>
470
   * @param b the bias to use
471
   *
472
   * @return the position in the document that corresponds to the screen
473
   *         coordinates <code>x, y</code>
474
   */
475
  public int viewToModel(float x, float y, Shape a, Position.Bias[] b)
476
  {
477
    int pos;
478
    // I'd rather do the following. The harmony testsuite indicates
479
    // that a simple cast is performed.
480
    //Rectangle r = a instanceof Rectangle ? (Rectangle) a : a.getBounds();
481
    Rectangle r = (Rectangle) a;
482
    if (x < r.x + r.width / 2)
483
      {
484
        b[0] = Position.Bias.Forward;
485
        pos = getStartOffset();
486
      }
487
    else
488
      {
489
        b[0] = Position.Bias.Backward;
490
        pos = getEndOffset();
491
      }
492
    return pos;
493
  }
494
}

powered by: WebSVN 2.1.0

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