Xcos: remove block default values
[scilab.git] / scilab / modules / xcos / src / java / org / scilab / modules / xcos / block / AfficheBlock.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2009 - DIGITEO - Bruno JOFRET
4  *
5  * This file must be used under the terms of the CeCILL.
6  * This source file is licensed as described in the file COPYING, which
7  * you should have received as part of this distribution.  The terms
8  * are also available at
9  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12 package org.scilab.modules.xcos.block;
13
14 import java.awt.event.ActionEvent;
15 import java.awt.event.ActionListener;
16 import java.io.Serializable;
17 import java.util.Collections;
18 import java.util.HashMap;
19 import java.util.Map;
20
21 import javax.swing.Timer;
22
23 import org.apache.commons.logging.LogFactory;
24 import org.scilab.modules.graph.utils.ScilabExported;
25 import org.scilab.modules.types.scilabTypes.ScilabDouble;
26 import org.scilab.modules.types.scilabTypes.ScilabList;
27 import org.scilab.modules.types.scilabTypes.ScilabType;
28
29 import com.mxgraph.view.mxCellState;
30 import com.mxgraph.view.mxGraphView;
31
32 /**
33  * Implement the AFFICH_m block
34  */
35 public final class AfficheBlock extends BasicBlock {
36
37         /**
38          * Default refresh rate used on the simulation to update block.
39          */
40         private static final int DEFAULT_TIMER_RATE = 200;
41
42         private static final long serialVersionUID = 6874403612919831380L;
43
44         /**
45          * Map any id to an affiche block instance.
46          * 
47          * This property is linked to the affich2.cpp native implementation
48          */
49         private static final Map<Integer, AfficheBlock> INSTANCES = Collections
50                         .synchronizedMap(new HashMap<Integer, AfficheBlock>());
51         
52         /**
53          * Update the value of the associated block
54          */
55         private static class UpdateValueListener implements ActionListener, Serializable {
56                 private AfficheBlock block;
57                 private String[][] data;
58                 
59                 /**
60                  * Default constructor 
61                  * @param block the current block
62                  */
63                 public UpdateValueListener(AfficheBlock block) {
64                         this.block = block;
65                 }
66                 
67                 /**
68                  * @param data the data to set
69                  */
70                 public synchronized void setData(String[][] data) {
71                         this.data = data;
72                 }
73                 
74                 /**
75                  * Calculate an print the new String value.
76                  * 
77                  * @param e the current event
78                  * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
79                  */
80                 @Override
81                 public synchronized void actionPerformed(ActionEvent e) {
82                         if (block.getParentDiagram() == null) {
83                                 return;
84                         }
85                         
86                         /*
87                          * Construct a String representation of the values.
88                          */
89                         final StringBuilder blockResult = new StringBuilder();
90                         final int iRows = data.length;
91                         final int iCols = data.length;
92
93                         for (int i = 0; i < iRows; i++) {
94                                 for (int j = 0; j < iCols; j++) {
95                                         if (iCols != 0) {
96                                                 blockResult.append("  ");
97                                         }
98
99                                         blockResult.append(data[i][j]);
100                                 }
101                                 blockResult.append(System.getProperty("line.separator"));
102                         }
103                         
104                         /*
105                          * Update and refresh the values
106                          */
107                         block.setValue(blockResult.toString());
108                         
109                         final mxGraphView view = block.getParentDiagram().getView();
110                         final mxCellState parentState = view.getState(block.getParent());
111                         
112                         view.validateBounds(parentState, block);
113                         block.getParentDiagram().repaint(view.validatePoints(parentState, block));
114                         
115                         if (LogFactory.getLog(UpdateValueListener.class).isTraceEnabled()) {
116                                 LogFactory.getLog(UpdateValueListener.class).trace(blockResult.toString());
117                         }
118                 }               
119         }
120         
121         private final Timer printTimer;  
122         private final UpdateValueListener updateAction;
123         
124         /** Default constructor */
125         public AfficheBlock() {
126                 super();
127                 
128                 updateAction = new UpdateValueListener(this);
129                 printTimer = new Timer(DEFAULT_TIMER_RATE, updateAction);
130                 printTimer.setRepeats(false);
131         }
132         
133         /**
134          * Set the default values
135          * @see org.scilab.modules.xcos.block.BasicBlock#setDefaultValues()
136          */
137         @Override
138         protected void setDefaultValues() {
139                 super.setDefaultValues();
140                 
141                 setValue("0.0");
142         }
143
144         /**
145          * Assign a value to an AfficheBlock instance
146          * 
147          * @param uid
148          *            the block id
149          * @param value
150          *            the value to set.
151          */
152         @ScilabExported(module = "scicos_blocks", filename = "Blocks.giws.xml")
153         public static void setValue(final int uid, final String[][] value) {
154                 if (value.length == 0 || value[0].length == 0) {
155                         throw new IllegalArgumentException(
156                                         "value is not a non-empty String matrix (String[][])");
157                 }
158                 
159                 final AfficheBlock block = INSTANCES.get(uid);
160                 
161                 block.updateAction.setData(value);
162                 if (!block.printTimer.isRunning()) {
163                         block.printTimer.start();
164                 }
165         }
166
167         /**
168          * @return the instance UID.
169          */
170         @Deprecated
171         public synchronized int getHashCode() {
172                 return hashCode();
173         }
174         
175         /**
176          * @return The scilab formated object parameters
177          */
178         @Override
179         public ScilabType getObjectsParameters() {
180                 int id = hashCode();
181
182                 /*
183                  * As hashCode() may return an already existing id, we need to change it
184                  * in this case.
185                  * 
186                  * see http://java.sun.com/javase/6/docs/api/java/lang/Object.html#hashCode()
187                  */
188                 while (INSTANCES.containsKey(id) && INSTANCES.get(id) != this) {
189                          id++;
190                 }
191                 
192                 INSTANCES.put(id, this);
193                 
194                 ScilabList list = new ScilabList();
195                 list.add(new ScilabDouble(id));
196                 return list;
197         }
198         
199         /**
200          * Remove the instance from the INSTANCES map.
201          * 
202          * @throws Throwable when unable to do so.
203          * @see java.lang.Object#finalize()
204          */
205         @Override
206         protected void finalize() throws Throwable {
207                 INSTANCES.remove(hashCode());
208                 super.finalize();
209         }
210         
211         /**
212          * @return a clone of the block
213          * @throws CloneNotSupportedException on error
214          * @see com.mxgraph.model.mxCell#clone()
215          */
216         @Override
217         public Object clone() throws CloneNotSupportedException {
218                 AfficheBlock clone = (AfficheBlock) super.clone();
219                 
220                 // reassociate the update action data
221                 clone.updateAction.block = clone;
222                 
223                 return clone;
224         }
225
226 }