View Javadoc

1   package fr.ove.openmath.jome.ctrlview.bidim;
2   
3   import java.awt.*;
4   import java.util.*;
5   import fr.ove.openmath.jome.ctrlview.bidim.*;
6   import fr.ove.openmath.jome.model.*;
7   
8   /***
9   * A layout manager that lays components horizontally and inserts between
10  * them, the display of the operator that the layout manager lays.
11  *
12  * @author © 1999 DIRAT Laurent
13  * @version 2.0  13/12/1999
14  */
15  public abstract class InfixOperatorLayout extends HorizontalLayout implements OperatorDisplayCreator {    
16      /***
17      * Do we need to insert an operator display ?
18      */
19      protected boolean insertOperatorDisplay = true;
20      
21      /***
22      * The number of the components already present before an other insertion
23      * or removal. This is necessary to keep in mind this, in order to know if 
24      * we must parse the list of components to check if we have to insert symbol
25      * display or not.
26      */
27      protected int prevNbComponent = 0;
28      
29      /***
30      * Inserts a display of the operator symbol that the display
31      * laid by the instance represents.
32      */
33      protected void insertOperatorDisplay() {
34          Display current, next, displayOperator;
35          FormulaTreeStructure fatherFts = (FormulaTreeStructure) displayToLay.getListener();
36          FormulaTreeStructure fts;
37          int nbComponent = displayToLay.getComponentCount();
38          
39          // On parcourre tous les components prÈsents dans le display.
40          for (int i = 1; i < nbComponent; i++) {
41              // la rÈfÈrence sur le component courant
42              current = (Display) displayToLay.getComponent(i - 1);
43              // la rÈfÈrence sur le suivant
44              next = (Display) displayToLay.getComponent(i);
45              
46              // Si le courant est un display d'opÈrateur alors on continue
47              if (current.isSymbolOperatorDisplay())
48                  continue;
49                  
50              // Si le suivant n'est pas un display d'opÈrateur alors 2 cas
51              if (!next.isSymbolOperatorDisplay()) {
52                  // On ajoute un display d'opÈrateur.
53                  displayOperator = createOperatorDisplay();
54                  displayToLay.add(displayOperator, displayOperator, i);
55                  
56                  // On met un listener ? l'opÈrateur.
57                  // En fait, il n'y en a pas besoin, dans le sens o? il n'y a pas spÈcifiquement de fts qui
58                  // Ècoute le comportement de ce display. NÈanmoins, il s'avËre nÈcessaire qu'il en ait
59                  // un, par exemple lors de l'iconification, car c'est le display qui reÁoit la demande
60                  // d'iconification qui envoie l'ÈvÈnement correspondant ? la FTS. Or si ce display n'a pas
61                  // d'Ècouteur, alors pb. Par cohÈrence, l'Ècouteur du display d'opÈrateur, est le fts qui
62                  // reprÈsente cette opÈration. Par contre, la fts en question, n'Ècoute pas le display
63                  // d'opÈrateur.
64                  displayOperator.addControlListener(fatherFts);
65                  i++;
66                  nbComponent++;
67              }
68          }
69          
70          // Mise ? jour des rangs des displays
71          displayToLay.adjustRank();
72          // Mise ? jour du nombre de components prÈsents dans le display.
73          prevNbComponent = displayToLay.getComponentCount();
74          // On n'a plus besoin d'insÈrer des displays d'opÈrateur.
75          insertOperatorDisplay = false;
76          // On fait en sorte que la mise ? niveau des displays (opÈrateurs) soit faite.
77          displayToLay.setUpdateLevel(true);
78          // On a rajoutÈ un display, on demande le recalcul de tous les ancÍtres
79          // de l'instance.
80          displayToLay.computeAncestorsAttributes();
81      }
82      
83      /***
84      * Computes the size of the display according to its children size (if any),
85      * and its different attributes.
86      * @return the size of the display.
87      */
88      public Dimension computeAttributes() {
89          // On regarde si le nombre de component dans le display a changÈ depuis
90          // la derniËre fois. Si oui, il faut contrÙler s'il ne faut pas ajouter
91          // des display d'opÈrateur.
92          if (insertOperatorDisplay || (prevNbComponent != displayToLay.getComponentCount()))
93              insertOperatorDisplay();
94              
95          return super.computeAttributes();
96      }
97          
98      /***
99      * The display needs to be rebuilt. We do this.
100     */
101     public void rebuildDisplay() {
102         Display tmp;
103         int nbDisplay = ((FormulaTreeStructure) displayToLay.getListener()).getNbChildren();
104         Display listDisplay[] = new Display[nbDisplay];
105         
106         int count = displayToLay.getComponentCount();
107         for (int i = 0; i < count; i++) {
108             tmp = (Display) displayToLay.getComponent(i);
109             if (!tmp.isSymbolOperatorDisplay()) {
110                 // A voir !!!!!
111                 // Mais il semblerai que bon, sinon ? la (re)construction du display il se base
112                 // sur des anciennes valeurs, et donc pas terrible niveau affichage.
113                 tmp.setLocation(0, 0);
114                 listDisplay[((FormulaTreeStructure) tmp.getListener()).getRank()] = tmp;
115             }
116         }
117         
118         // ATTENTION : ici, on enlËve les displays fils de display, mais on ne les enlËve pas de la liste
119         // des listeners de la fts qu'il sont en train d'Ècouter. Exception faite pour les displays d'opÈrateur.
120         displayToLay.removeAllDisplays();
121                 
122         for (int i = 0; i < nbDisplay; i++)
123             displayToLay.add(listDisplay[i]);
124             
125         // On a reconstruit le display, il faut maintenant insÈrer les displays d'opÈrateur.
126         insertOperatorDisplay = true;
127         
128         // La taille des displays est probablement diffÈrente de ceux qui Ètaient
129         // prÈcÈdemment. On demande alors le recalcul des display ancÍtres.
130         displayToLay.computeAncestorsAttributes();
131     }
132 }