Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/fudaa/ebli/calque/BCalque.java


1   /*
2    * @file         BCalque.java
3    * @creation     1998-08-25
4    * @modification $Date: 2003/01/30 10:56:50 $
5    * @license      GNU General Public License 2
6    * @copyright    (c)1998-2001 CETMEF 2 bd Gambetta F-60231 Compiegne
7    * @mail         devel@fudaa.org
8    */
9   
10  package org.fudaa.ebli.calque;
11  
12  import java.awt.Color;
13  import java.awt.Component;
14  import java.awt.Container;
15  import java.awt.Graphics;
16  import java.awt.event.MouseListener;
17  import java.awt.event.MouseMotionListener;
18  import java.lang.reflect.Method;
19  import java.util.Arrays;
20  
21  import javax.swing.Icon;
22  import javax.swing.JMenuItem;
23  
24  import org.fudaa.ebli.geometrie.GrBoite;
25  import org.fudaa.ebli.geometrie.GrMorphisme;
26  import org.fudaa.ebli.repere.AbstractCalque;
27  
28  /**
29   * Une classe de base pour tous les calques. Elle gere les transformations
30   * du repere et l'organisation des calques en une hierarchie arborescente.
31   * Un calque peut etre de trois sortes:
32   * <UL>
33   * <LI>un groupe de calques:
34   * structurant, regroupant plusieurs calques ou familles de calques,
35   * <LI>un calque d'affichage:
36   * calque representant des donnees a l'ecran,
37   * <LI>un calque d'interaction:
38   * gerant les evenements exterieurs et generalement associe a un calque
39   * d'affichage (ex: BCalqueDessin et BCalqueDessinInteraction).
40   * </UL>
41   *
42   * @version      $Id: BCalque.java,v 1.1 2003/01/30 10:56:50 deniger Exp $
43   * @author       Guillaume Desnoix , Axel von Arnim
44   */
45  public abstract class BCalque 
46          extends AbstractCalque implements Icon
47  {
48  
49    String[] enabledActions_;
50    
51    /**
52     * Constructeur.
53     * Le constructeur initialise les transformations versEcran et versReel
54     * avec la transformation  identite. versEcran transforme les coordonnees reelles en coordonnees
55     * ecran et versReel fait l'inverse. versEcran sert a l'affichage des objets
56     * et versReel a la gestion de la souris dans le repere reel.
57     */
58    protected BCalque()
59    {
60      super();
61  
62  //    ajustement_ = false;
63      destructible_ = true;
64      versEcran_ = GrMorphisme.identite();
65      versReel_ = GrMorphisme.identite();
66  
67      setOpaque(false);
68      setLayout(new CalqueLayout());
69      setRequestFocusEnabled(false);
70      setDoubleBuffered(false);
71    }
72  
73    // Icon
74  
75    /**
76     * la largeur de l'icone correspondant (vue de l'arbre)
77     * @return 24
78     */
79    public int getIconWidth()
80    {
81      return 24;
82    }
83    
84    /**
85     * la hauteur de l'icone correspondant (vue de l'arbre)
86     * @return 24
87     */
88    public int getIconHeight()
89    {
90      return 24;
91    }
92  
93    /**
94     * Dessin de l'icone.
95     * @param _c composant dont l'icone peut utiliser des proprietes
96     * (couleur, ...). Ce parametre est le calque lui-meme. Il est ignore ici.
97     * @param _g le graphics sur lequel dessiner l'icone
98     * @param _x lieu cible de l'icone (x)
99     * @param _y lieu cible de l'icone (y)
100    */
101   public void paintIcon(Component _c, Graphics _g, int _x, int _y)
102   {
103     int w = getIconWidth();
104     int h = getIconHeight();
105 
106     _g.setColor(Color.white);
107     _g.fillRect(_x + 1, _y + 1, w - 1, h - 1);
108 
109     _g.setColor(isVisible() ? Color.black : Color.lightGray);
110     _g.drawRect(_x, _y, w, h);
111   }
112 
113   // Informations
114 
115   /**
116    * Chaine affichee dans l'arbre des calques.
117    */
118   private String title_;
119   public String getTitle()
120   {
121     return title_;
122   }
123   public void setTitle(String _title)
124   {
125     title_ = _title;
126   }
127 
128   public String toString()
129   {
130     String r = getTitle();
131     if ((r == null) || r.equals(""))
132       r = getName();
133     if ((r == null) || r.equals(""))
134       r = super.toString();
135     return r;
136   }
137 
138   /**
139    * Permet de renvoyer des menus spécifiques pour ce calque. Ces item seront 
140    * ajoutes a la fin du menu obtenu lors du clic avec le bouton droit dans
141    * l'arbre calque.
142    * @return null par defaut.
143    */
144   public JMenuItem[] getSpecificMenuItems()
145   {
146     return null;
147   }
148 
149   /**
150    * Methode de la classe Container surchargee. Elle est appelee lors
151    * de l'ajout d'un nouveau sous-calque. Elle initialise les transformations
152    * versEcran et versReel aux valeurs du calque hote.
153    * @param _comp calque a ajouter
154    * @param _constraints contraintes de layout
155    * @param _index indice dans la liste de calques
156    * @see java.awt.Container#add(java.awt.Component)
157    */
158   protected void addImpl(Component _comp, Object _constraints, int _index)
159   {
160     if (_comp instanceof BCalque)
161     {
162       BCalque calque = (BCalque) _comp;
163       calque.setVersEcran(getVersEcran());
164       calque.setVersReel(getVersReel());
165     }
166     super.addImpl(_comp, _constraints, _index);
167   }
168 
169   /**
170    * Renvoie les calques fils de ce calque.
171    * @return les calques fils
172    * @see #getTousCalques()
173    */
174   public BCalque[] getCalques()
175   {
176     int i, n;
177     Component[] c = getComponents();
178 
179     n = 0;
180     for (i = 0; i < c.length; i++)
181       if (c[i] instanceof BCalque)
182         n++;
183 
184     BCalque[] r = new BCalque[n];
185 
186     n = 0;
187     for (i = 0; i < c.length; i++)
188       if (c[i] instanceof BCalque)
189       {
190         r[n] = (BCalque) c[i];
191         n++;
192       }
193 
194     return r;
195   }
196 
197   /**
198    * Renvoie tous les sous-calques de ce calque.
199    * parcourt toute l'arborescence des sous-calques jusqu'aux feuilles.
200    * @return les sous-calques
201    * @see #getCalques()
202    */
203   public BCalque[] getTousCalques()
204   {
205     int i, j, n;
206     BCalque[] c = getCalques();
207 
208     n = 1;
209     for (i = 0; i < c.length; i++)
210       n += c[i].getTousCalques().length;
211 
212     BCalque[] r = new BCalque[n];
213 
214     r[0] = this;
215     n = 1;
216     for (i = 0; i < c.length; i++)
217     {
218       BCalque[] sc = c[i].getTousCalques();
219       for (j = 0; j < sc.length; j++)
220       {
221         r[n] = sc[j];
222         n++;
223       }
224     }
225 
226     return r;
227   }
228 
229   /**
230    * Renvoie le premier sous-calque de ce calque de nom donné.
231    *
232    * @param _name Nom du sous calque.
233    * @return Le sous calque de nom donné. <i>null</i> si aucun sous calque ne
234    *         porte ce nom.
235    * @deprecated
236    */
237   public BCalque getCalque(String _name)
238   {
239     return getCalqueParNom(_name);
240   }
241 
242   /**
243    * Renvoie le premier sous-calque de ce calque de nom donné.
244    *
245    * @param _name Nom du sous calque.
246    * @return Le sous calque de nom donné. <i>null</i> si aucun sous calque ne
247    *         porte ce nom.
248    */
249   public BCalque getCalqueParNom(String _name)
250   {
251     if (_name == null)
252       return null;
253 
254     BCalque[] cqs = getTousCalques();
255 
256     for (int i = 0; i < cqs.length; i++)
257       if (_name.equals(cqs[i].getName()))
258         return cqs[i];
259 
260     return null;
261   }
262 
263   /**
264    * Renvoie le premier sous-calque de ce calque de nom donné.
265    *
266    * @param _title Le titre du sous calque.
267    * @return Le sous calque de titre donné. <i>null</i> si aucun sous calque ne
268    *         porte ce titre.
269    */
270   public BCalque getCalqueParTitre(String _title)
271   {
272     if (_title == null)
273       return null;
274 
275     BCalque[] cqs = getTousCalques();
276 
277     for (int i = 0; i < cqs.length; i++)
278       if (_title.equals(cqs[i].getTitle()))
279         return cqs[i];
280 
281     return null;
282   }
283 
284   // Organisation
285 
286   /**
287    * Place ce calque en tete de la liste des calques fils du pere.
288    * Equivalent a pere.enPremier(this)
289    * @see #enPremier(BCalque)
290    */
291   public void enPremier()
292   {
293     Container p = getParent();
294     if (p instanceof BCalque)
295        ((BCalque) p).enPremier(this);
296   }
297 
298   /**
299    * Place le calque specifie en tete de la liste des fils.
300    * @see #enPremier()
301    */
302   public void enPremier(BCalque _c)
303   {
304     add(_c, 0);
305     _c.revalidate();
306   }
307 
308   /**
309    * Place ce calque en fin de la liste des calques fils du pere.
310    * Equivalent a pere.enDernier(this)
311    * @see #enDernier(BCalque)
312    */
313   public void enDernier()
314   {
315     Container p = getParent();
316     if (p instanceof BCalque)
317        ((BCalque) p).enDernier(this);
318   }
319 
320   /**
321    * Place le calque specifie en fin de la liste des fils.
322    * @see #enDernier()
323    */
324   public void enDernier(BCalque _c)
325   {
326     add(_c);
327     _c.revalidate();
328   }
329 
330   /**
331    * Detruit ce calque.
332    * Equivalent a pere.detruire(this)
333    * @see #detruire(BCalque)
334    */
335   public void detruire()
336   {
337     Container p = getParent();
338     if (p instanceof BCalque)
339        ((BCalque) p).detruire(this);
340   }
341 
342   /**
343    * Detruit le calque specifie de la liste des fils.
344    * @see #detruire()
345    */
346   public void detruire(BCalque _c)
347   {
348     if (_c.isDestructible())
349     {
350       BCalque[] cq = _c.getCalques();
351 
352       for (int i = 0; i < cq.length; i++)
353         _c.detruire(cq[i]);
354 
355       Container p = this;
356       while ((p != null) && !(p instanceof BVueCalque))
357         p = p.getParent();
358 
359       if (p != null)
360       {
361         if (_c instanceof MouseListener)
362            ((BVueCalque) p).removeMouseListener((MouseListener) _c);
363         if (_c instanceof MouseMotionListener)
364           ((BVueCalque) p).removeMouseMotionListener((MouseMotionListener) _c);
365       }
366 
367       remove(_c);
368       revalidate();
369     }
370   }
371 
372   public void paint(Graphics g)
373   {
374     // Paint (HACK: forcer le clip a cause d'un bug de 1.2 (?))
375     // System.err.println(getName()+": g.getClipBounds()="+g.getClipBounds());
376     if (g.getClipBounds() == null)
377       g.setClip(0, 0, getWidth(), getHeight());
378     super.paint(g);
379   }
380 
381   public void paintComponent(Graphics g)
382   {
383     // surchargee dans chaque calque
384   }
385 
386   public final boolean isValidateRoot()
387   {
388     return false;
389   }
390 
391   /**
392    * Reaffichage complet du calque, plus rapide.
393    */
394   public final void quick_repaint()
395   {
396     Graphics g = getGraphics();
397     if (g != null)
398       update(g);
399     repaint(1000);
400   }
401 
402   public void repaint()
403   {
404     if (isValidateRoot())
405       super.repaint();
406     else if (getParent() != null)
407       getParent().repaint();
408   }
409 
410   /**
411    * repaint apres un delai.
412    * @param _tm delai en millisecondes
413    */
414   public void repaint(long _tm)
415   {
416     if (isValidateRoot())
417       super.repaint(_tm);
418     else if (getParent() != null)
419       getParent().repaint(_tm);
420   }
421 
422   // Proprietes
423 
424   private boolean rapide_;
425 
426   /**
427    * Accesseur de la propriete ajustement. Elle est envoyee par les
428    * beans de controle de repere comme BTransformationGlissiere
429    * pour preciser que l'evenement repere associe est intermediaire.
430    * Ceci permet de passer en mode rapide pour l'affichage des calques
431    * lors des rafales d'evenements repere.
432    */
433   public boolean isRapide()
434   {
435     return rapide_;
436   }
437 
438   /**
439    * Affectation de la propriete ajustement.
440    * Cette affectation est appliquee aux calques fils.
441    */
442   public void setRapide(boolean _v)
443   {
444     if (rapide_ != _v)
445     {
446       boolean vp = rapide_;
447       rapide_ = _v;
448 
449       BCalque[] c = getCalques();
450       for (int i = 0; i < c.length; i++)
451         c[i].setRapide(_v);
452 
453       firePropertyChange("ajustement", vp, rapide_);
454     }
455   }
456   
457 
458   private boolean destructible_;
459 
460   /**
461    * Indique si un calque peut etre detruit par l'utilisateur.
462    * Faux par defaut.
463    * @return vrai si destructible
464    */
465   public boolean isDestructible()
466   {
467     boolean r = destructible_;
468     BCalque[] c = getCalques();
469 
470     for (int i = 0; i < c.length; i++)
471       r &= c[i].isDestructible();
472 
473     return r;
474   }
475 
476   public void setDestructible(boolean _v)
477   {
478     if (destructible_ != _v)
479     {
480       boolean vp = destructible_;
481       destructible_ = _v;
482       firePropertyChange("destructible", vp, destructible_);
483     }
484   }
485 
486   /**
487    * Renvoie le domaine (l'etendue) du contenu du calque.
488    * null si non significatif.
489    * @return domaine en coordonnees reelles
490    */
491   public GrBoite getDomaine()
492   {
493     GrBoite r = null;
494 
495     if (isVisible())
496     {
497       BCalque[] c = getCalques();
498       for (int i = 0; i < c.length; i++)
499       {
500         GrBoite d = c[i].getDomaine();
501         if (d != null)
502         {
503           if (r == null)
504             r = (GrBoite) d.clone();
505           else
506             r = r.union(d);
507         }
508       }
509     }
510 
511     return r;
512   }
513 
514   private GrMorphisme versEcran_;
515 
516   /**
517    * Accesseur de la propriete versEcran. Elle est la matrice de
518    * transformation a appliquer lors de l'affichage du calque.
519    */
520   public GrMorphisme getVersEcran()
521   {
522     return versEcran_;
523   }
524 
525   /**
526    * Affectation de la propriete versEcran.
527    * Cette affectation est appliquee aux calques fils.
528    */
529   public void setVersEcran(GrMorphisme _v)
530   {
531     if (versEcran_ != _v)
532     {
533       GrMorphisme vp = versEcran_;
534       versEcran_ = _v;
535 
536       BCalque[] c = getCalques();
537       for (int i = 0; i < c.length; i++)
538         c[i].setVersEcran(_v);
539 
540       firePropertyChange("versEcran", vp, versEcran_);
541     }
542   }
543 
544   private GrMorphisme versReel_;
545 
546   /**
547    * Accesseur de la propriete versReel. Elle est la matrice
548    * de transformation a appliquer lors de la lecture d'un evenement
549    * souris par exemple.
550    */
551   public GrMorphisme getVersReel()
552   {
553     return versReel_;
554   }
555 
556   /**
557    * Affectation de la propriete versReel.
558    * Cette affectation est appliquee aux calques fils.
559    */
560   public void setVersReel(GrMorphisme _v)
561   {
562     if (versReel_ != _v)
563     {
564       GrMorphisme vp = versReel_;
565       versReel_ = _v;
566 
567       BCalque[] c = getCalques();
568       for (int i = 0; i < c.length; i++)
569         c[i].setVersReel(_v);
570 
571       firePropertyChange("versReel", vp, versReel_);
572     }
573   }
574 
575   /**
576    * Affectation generique de propriete.
577    * @param _name nom de la propriete a modifier
578    * @param _value nouvelle valeur
579    */
580   public void setProperty(String _name, Object _value)
581   {
582     try
583     {
584       String n =
585         "set" + _name.substring(0, 1).toUpperCase() + _name.substring(1);
586       Class z = _value.getClass();
587 
588       // System.err.println("$$$ N="+n);
589 
590       try
591       {
592         z = (Class) (z.getField("TYPE").get(z));
593       }
594       catch (Exception ey)
595       {
596       }
597 
598       Class[] c = null;
599       Method m = null;
600 
601       do
602       {
603         // System.err.println("$$$ Z="+z);
604         c = new Class[] { z };
605         try
606         {
607           m = getClass().getMethod(n, c);
608         }
609         catch (Exception ey)
610         {
611           m = null;
612         }
613 
614         // System.err.println("$$$ M="+m);
615 
616         z = z.getSuperclass();
617       }
618       while ((m == null) && (z != null));
619 
620       Object[] o = new Object[] { _value };
621 
622       // System.err.println("$$$ O="+o);
623 
624       m.invoke(this, o);
625     }
626     catch (Exception ex)
627     {
628       if (!_name.equals("ancestor"))
629         System.err.println(
630           "Propriété "
631             + _name
632             + " non disponible en écriture dans "
633             + getClass().getName()
634             + ".");
635     }
636   }
637 
638   /**
639    * Accesseur generique de propriete.
640    * @param _name nom de la propriete a lire
641    * @return valeur de la propriete
642    */
643   public Object getProperty(String _name)
644   {
645     Object r = null;
646 
647     try
648     {
649       String n =
650         "get" + _name.substring(0, 1).toUpperCase() + _name.substring(1);
651       Class[] c = new Class[0];
652       Method m = getClass().getMethod(n, c);
653       Object[] o = new Object[0];
654       r = m.invoke(this, o);
655     }
656     catch (Exception ex)
657     {
658       if (!_name.equals("ancestor"))
659         System.err.println(
660           "Propriété "
661             + _name
662             + " non disponible en lecture dans "
663             + getClass().getName()
664             + ".");
665     }
666 
667     return r;
668   }
669   
670   /**
671    * Renvoie les actions a activer pour ce calque.
672    * Cette methode est utilisee, par exemple, par la <code>ZEbliFilleCalque</code>.
673    * Si la valeur <code>null</code> est renvoyee, toutes les actions seront desactivees.
674    * @return String[] les actions a activer. Par defaut renvoie <code>null</code>.
675    */
676   public String[] getEnabledActions()
677   {
678     return enabledActions_;
679   }
680 
681   /**
682    * Affecte et trie le tableau des actions a activer.
683    * @param enabledSpecificTools les nouvelles actions.
684    */
685   public void setEnabledActions(String[] enabledSpecificTools)
686   {
687     Arrays.sort(enabledSpecificTools);
688     enabledActions_ = enabledSpecificTools;
689   }
690 
691 }