001package org.vishia.gral.base;
002
003import java.text.ParseException;
004import java.util.LinkedList;
005import java.util.List;
006import java.util.concurrent.atomic.AtomicInteger;
007
008import org.vishia.byteData.VariableAccessWithIdx;
009import org.vishia.byteData.VariableAccess_ifc;
010import org.vishia.byteData.VariableContainer_ifc;
011import org.vishia.gral.ifc.GralColor;
012import org.vishia.gral.ifc.GralFont;
013import org.vishia.gral.ifc.GralMngBuild_ifc;
014import org.vishia.gral.ifc.GralMng_ifc;
015import org.vishia.gral.ifc.GralRectangle;
016import org.vishia.gral.ifc.GralSetValue_ifc;
017import org.vishia.gral.ifc.GralUserAction;
018import org.vishia.gral.ifc.GralWidgetCfg_ifc;
019import org.vishia.gral.ifc.GralWidget_ifc;
020import org.vishia.gral.impl_ifc.GralWidgetImpl_ifc;
021import org.vishia.gral.widget.GralHorizontalSelector;
022import org.vishia.util.Assert;
023import org.vishia.util.Debugutil;
024import org.vishia.util.KeyCode;
025
026
027
028/**This class is the base class of representation of a graphical widget in the gral concept. 
029 * All widgets in the gral concept have this base data independent of the implementation graphic.
030 * The implementation graphic should have a wrapper class inherited from {@link ImplAccess} which 
031 * contains specials of the implementation and refers the widget of the implementation layer graphic, 
032 * for example a text field.
033 * <br><br> 
034 * Any widget is represented in the user's level by a derived instance of a {@link GralWidget}. 
035 * There are 2 strategies yet to create widgets in respect to the graphical implementation.
036 * Either the Widget is created independent of the graphic implementation first 
037 * and then taken as parameter for the graphic widget-creating method. In this case the GralWidget 
038 * contains nothing of the graphic implementation but has a reference to it.
039 * The second strategy yet is, the Widget is returned by the graphic-implementation widget-creating method
040 * as a instance which has {@link GralWidget} and its non-graphic specializations as super class
041 * and the graphic depending parts in the created instance.
042 * <br><br>
043 * The first form is more universal. Especially generic can be used for the class definition if necessary.
044 * It us used yet only (2013-06) for
045 * <ul> 
046 * <li>{@link org.vishia.gral.widget.GralHorizontalSelector#setToPanel(GralMngBuild_ifc)}
047 * <li>{@link GralTable#setToPanel(GralMngBuild_ifc)}.
048 * </ul>
049 * but it may be used more and more in the future. The <code>setToPanel(GralMng)</code> method
050 * invokes the graphic implementation specific derivation of the {@link GralMng}, which creates
051 * the implementation widgets. <br>
052 * For the UML presentation see {@link org.vishia.util.Docu_UML_simpleNotation}:
053 * <pre>
054 * 
055 *   GralHorizontalSelector< UserType > <-----<*>UserCanCreateIt_GraphicIndependently
056 *   - some special non-graphic data
057 *     |
058 *     |<------------------------------------------------------------------data---|
059 *     |                                                                          |
060 *     |&<--------&GraphicImplAccess<|---+                                        |   
061 *     |                                 |                                        |
062 *     +--|>GralWidget                   |                                        |
063 *     |     |                           |                                        |
064 *     |     |<>--->GralWidgImpl_ifc<|---+--SwtHorizontalSelector                 |
065 *     |     |                                 |                                  |      
066 *     |     |                                 |                                  |     
067 *                                             |<*>------------------------>swt.Canvas
068 *                                             |                                  |
069 *                                             |                                  |
070 *                                          -paintRoutine <-------paintListener---|
071 *                                          -mouseListener<-------mouseListener---|
072 *                                          -etc.                          
073 *                                      
074 * </pre>
075 * <br><br>
076 * The user creates an instance of {@link GralHorizontalSelector} in any thread maybe as composite, 
077 * it is independent of the graphic itself.
078 * Then the user builds its graphic appearance with invocation of {@link GralHorizontalSelector#setToPanel(GralMngBuild_ifc)}
079 * with the derived instance of {@link GralMng} as parameter. 
080 * <br><br>  
081 * The <code>GralWidget</code> knows the graphic implementation via the {@link GralWidgImpl_ifc} to invoke some methods
082 * for the graphical appearance. The interface is independent
083 * of the implementation itself. The implementor of this interface for this example 
084 * is the {@link org.vishia.gral.swt.SwtHorizontalSelector} implements this methods. 
085 * <br><br>
086 * The SwtHorizontalSelector refers the platform-specific widget Object (Swing: javax.swing.JComponent, 
087 * org.eclipse.swt.widgets.Control etc.), in this case a {@link org.eclipse.swt.widgets.Canvas}. 
088 * It contains the special paint routines, mouse handling etc. 
089 * <br><br>
090 * The platform-specific widget has a reference to the GralWidget, in this case the {@link GralHorizontalSelector}
091 * stored as Object-reference. This reference can be used in the paintRoutine, mouseListerner etc. to get
092 * information about the GralWidget.  
093 * <br><br> 
094 * The second form takes most of the characteristics as parameters for the creating method. 
095 * It needs inheritance.
096 * <pre>
097 *   GralButton <-------UserCanAssociate it but can't create the instance with constructor.
098 *       |
099 *       |-------------|>SwtButton
100 * </pre> 
101 * The instance is Graphic-Implementation-specific and it is created with this interface as factory:<br>
102 * {@link #addButton(String, GralUserAction, String)}.
103 * <br><br>
104 * The ObjectModelDiagram may shown the relations:<br>
105 * <img src="../../../../../img/Widget_gral.png"><br>
106 * In this graphic the relationship between this class and the graphical implementation layer widget
107 * is shown with the example 'text field' in SWT:
108 * <ul>
109 * <li>The class {@link GralTextField} is the derived class of this to represent a text field
110 *   in an implementation independent way.
111 * <li>The class {@link org.vishia.gral.swt.SwtTextFieldWrapper} is the implementor for the GralTextField
112 *   for SWT graphic. 
113 * <li>That implementor knows is SWT-specific and refers the SWT widget {@link org.eclipse.swt.widgets.Text}
114 *   It based on the SWT-specific {@link org.eclipse.swt.widgets.Widget}. 
115 * </ul>   
116 * <br>   
117 * The implementation layer widget should to be deal with this GralWidget because of some overridden
118 * methods of the implementation layer widget need that. The general contract is, 
119 * that the implementation layer widget refers this GralWidget in its commonly user data field.
120 * For SWT it is {@link org.eclipse.swt.widgets.Widget#setData(Object)} method.
121 * <br><br>
122 * The Widget knows its {@link GralPos} at its panel where it is placed. The panel knows all widgets
123 * which are placed there (widgetList).
124 * 
125 * 
126 * <br>
127 * <br>
128 * <b>Change a widget from application in any thread</b>:<br> 
129 * The user can invoke the methods of the widget to animate it in a GUI etc, for example {@link #setBackColor(GralColor, int)}
130 * or {@link #setValue(int, int, Object)}. This methods can be called in any thread. This concept is described with the
131 * method {@link #setText(CharSequence)}, appropriate for all set methods.
132 * 
133 * 
134 * <br>
135 * <br>
136 * <b>Concept of data binding</b><br>
137 * 2012-05-19
138 * <br>
139 * <img src="../../../../../img/WidgetVariable_gral.png"><br>
140 * A widget has 2 associations: {@link #variable} and {@link #variables} to a management class {@link VariableAccessWithIdx}
141 * which knows the user data via a commonly {@link VariableAccess_ifc}. The data can be existing in the 
142 * user space with this interface. That part of user software doesn't know the graphical view of the data.
143 * The graphical part of software calls any refresh of showing, it calls the method {@link #refreshFromVariable(VariableContainer_ifc)}
144 * for all visible widgets. With this the widget gets the data from user with the variable associations
145 * and prepares it for the proper appearance depending on the kind of widget, format String etc.
146 * <br><br>
147 * The association to the correct variable is given only with a String as argument of the {@link #setDataPath(String)}
148 * method. The variable is found with the second interface {@link VariableContainer_ifc} which should be known
149 * by the graphical part of software and which is one parameter of the {@link #refreshFromVariable(VariableContainer_ifc)} method.
150 * The conclusion between the String given variable name or path and the data can be supplied in any form
151 * in the users software, which knows the data.
152 * <br><br>
153 * The data can be coming from any remote device. In that kind there are two ways to get the actually values:
154 * <ol>
155 * <li>There is a cyclically communication. The remote device sends all data in a cycle maybe some 100 milliseconds.
156 *   Then the actual data are present. The superior control should be call the {@link #refreshFromVariable(VariableContainer_ifc)}-method
157 *   if the data are received yet or in any other proper cycle.
158 * <li>The data are requested from the remote device only if they are need either for displaying in widgets 
159 *   of for other reasons. This kind of data holding are proper especially if they are a lot of data, 
160 *   not all of them should be communicated any time.
161 * </ol>
162 * For the second approach a time of actuality and a time of requesting are used. The method {@link #requestNewValueForVariable(long)}
163 * can be used to force communication.     
164 * <br><br>
165 * <b>Strategy of changing the graphical content of a widget</b>:<br>
166 * See {@link GralWidget_ifc} 
167 * <br><br>
168 * <b>Strategy to create widgets and positioning</b>: see {@link GralMng.GralMngFocusListener}.  
169 *
170 * @author Hartmut Schorrig
171 *
172 */
173public class GralWidget implements GralWidget_ifc, GralSetValue_ifc, GetGralWidget_ifc
174{
175  
176  /**Version, history and license.
177   * <ul>
178   * <li>2016-09-30 Hartmut bugfix: {@link #setFocus()} has set the default focus of the primaryWindow if the focus of a window was set.
179   * <li>2016-09-30 Hartmut New idea, concept: {@link ImplAccess#wdgimpl}: That refers an implementation of a WidgetHelper class of the implementation layer
180   *   which knows the widget. Via this aggregation some action with the implementation widget can be do which are defined
181   *   in the {@link GralWidgetImpl_ifc}. See {@link org.vishia.gral.swt.SwtWidgetHelper}.
182   * <li>2016-09-18 Hartmut chg: {@link #getActionChangeStrict(org.vishia.gral.ifc.GralWidget_ifc.ActionChangeWhen, boolean)} documented, 
183   *   changed: returns not null if strict and when==null and a common action is given. Earlier: Returns null in that case. 
184   * <li>2016-09-02 Hartmut chg: {@link GralWidget#GralWidget(String, String, char)} with a position String is now deprecated. 
185   *   Instead the {@link GralWidget#GralWidget(String, char)} which was deprecated till now is the favor again, but with a combination
186   *   of "@pos=name" as first argument. That can be used for all derived widgets!. Therewith it is more simple to complete the widgets 
187   *   with the capability of usage of a position String. Without "@...=" it is the old behavior of the constructor. 
188   *   Note that the position can be given with {@link GralMng#setPosition(GralPos, float, float, float, float, int, char)} etc. too,
189   *   with numeric values which may be calculated, instead a constant text. 
190   * <li>2016-08-31 Hartmut new: {@link #isGraphicDisposed()} especially used for GralWindow-dispose detection. 
191   * <li>2016-07-20 Hartmut chg: invocation of registerWidget one time after its position is known. Either it is in the ctor of GralWidget 
192   *   or it is in the ctor of {@link GralWidget.ImplAccess} if the position was assigned later in the graphic thread.
193   * <li>2016-07-20 Hartmut chg: instead setToPanel now {@link #createImplWidget_Gthread()}. It is a better name. 
194   * <li>2016-07-03 Hartmut chg: {@link #createImplWidget_Gthread()}: If the _wdgImpl is initialized already, this method does nothing. Before: Exception
195   * <li>2016-07-03 Hartmut refact: actionChange: Now the {@link GralWidget_ifc.ActionChange} describes the action class and arguments.
196   *   {@link ConfigData#actionChange1} refers the only one change action, or {@link ConfigData#actionChangeSelect} contains more as one change action.
197   *   {@link #specifyActionChange(String, GralUserAction, String[], org.vishia.gral.ifc.GralWidget_ifc.ActionChangeWhen...)} sets the only one or special actions,
198   *   {@link #getActionChange(org.vishia.gral.ifc.GralWidget_ifc.ActionChangeWhen)} selects a proper one. 
199   *   All derived widgets and implementation are adapted to the new system. The user interface is nearly identical.
200   * <li>2016-07-03 Hartmut chg: it is not derived from {@link GralWidgImpl_ifc} any more. It was the old concept: An implementing widgets was derived from the GralWidget. 
201   *   The new concept is: An implementing widget is derived from its derived class of {@link GralWidget.ImplAccess}. Therefore only that base class implements the GralWidgetImpl_ifc.
202   * <li>2016-07-03 Hartmut chg: handling of visible: A GralWidget is invisible by default. {@link #setVisible(boolean)} should be invoked on creation.
203   *   It is possible that widgets are switched. All widgets of a non-visible tab of a tabbed panel are set to invisible, especially {@link #bVisibleState} = false.
204   *   The {@link #isVisible()} is checked to decide whether a widget should be updated in the inspector. Only visible widgets should be updated.
205   *   The {@link GralWidgImpl_ifc#setVisibleGThread(boolean)} is implemented to all known widgets for the implementation layer in the kind of {@link #setFocusGThread()}.
206   *   See documentation on the methods.   
207   * <li>2015-09-20 Hartmut chg: some final methods now non final, because they have to be overridden for large widgets.
208   * <li>2015-09-20 Hartmut chg: gardening for {@link DynamicData#getChanged()}, now private attribute {@link DynamicData#whatIsChanged}
209   * <li>2015-09-20 Hartmut new: {@link #setActionMouse(GralMouseWidgetAction_ifc, int)} was a private thing in {@link org.vishia.gral.swt.SwtGralMouseListener.MouseListenerGralAction}
210   *   for widget implementation's mouse handling. Now as user define-able property of any widget, especially use-able for text fields. 
211   * <li>2015-09-12 Hartmut new: {@link #getData()}, {@link #setData(Object)} was existent as {@link GralWidget#setContentInfo(Object)},
212   *   now explicit property of any widget. {@link GralWidget#setContentInfo(Object)} was an older approach, not in interface, now deprecated.
213   * <li>2015-06-21 Hartmut bugfix: {@link #setFocus(int, int)} had hanged because while-loop on same window panel for a parent. 
214   * <li>2015-01-27 Hartmut new: {@link DynamicData#bTouchedField}, {@link ImplAccess##setTouched()} especially for a text field
215   *   if any editing key was received. Then the GUI-operator may mark a text or make an input etc. The setting of the text
216   *   from a cyclically thread should be prevented then to prevent disturb the GUI-operation. If the focus was lost then this bit
217   *   is reseted. It is an important feature for GUI-handling which was missed up to now. 
218   *   Yet only used for {@link GralTextField#setText(CharSequence, int)}. It may prevent repaint for universally usage for all widgets.
219   * <li>2015-01-27 Hartmut new: method {@link #getVariable(VariableContainer_ifc)} instead {@link #getVariableFromContentInfo(VariableContainer_ifc)}.
220   *   The last one method is used in an application but it does not run well for all requirements. The code of {@link #getVariable(VariableContainer_ifc)}
221   *   is copied from the well tested {@link #refreshFromVariable(VariableContainer_ifc)} as own routine and then used in a new application.    
222   * <li>2014-01-15 Hartmut new: {@link #getCmd(int)} with options.
223   * <li>2014-01-03 Hartmut new: {@link #isInFocus()} 
224   * <li>2013-12-21 Hartmut chg: {@link #repaint()} invokes redraw immediately if it is in graphic thread.
225   *   It invokes {@link #repaint(int, int)} with the {@link #repaintDelay} if it is not in graphic thread.
226   *   It does nothing if the implementation layer widget is not created yet. It means it can invoked
227   *   without parameter in any case.
228   * <li>2013-12-21 Hartmut chg: {@link ImplAccess#setDragEnable(int)} and setDropEnable moved from the core class.
229   *   It is adapt after change {@link GralTextField}. 
230   * <li>2013-12-21 Hartmut new: {@link #setToPanel(GralMngBuild_ifc)} is final now and invokes 
231   *   {@link GralMngBuild_ifc#createImplWidget_Gthread(GralWidget)}. That method handles all widget types. 
232   * <li>2013-11-11 Hartmut new: {@link #refreshFromVariable(VariableContainer_ifc, long, GralColor, GralColor)}
233   *   which shows old values grayed. 
234   * <li>2013-11-11 Hartmut chg: {@link #setFocus()} searches the {@link GralTabbedPanel} where the widget is
235   *   member of and invokes its {@link GralTabbedPanel#selectTab(String)}. It is not correct that the graphic
236   *   implementation layer does that itself. 
237   * <li>2013-06-29 Hartmut new: {@link #setToPanel(GralMngBuild_ifc)} as common method.
238   * <li>2013-06-16 Hartmut new {@link #_wdgImpl}. This instance was present in the past but removed. The concept is re-activated
239   *   because a graphic-implementation-independent GralWidget instance can have any generic types
240   *   and can be created as composite (with final type name = new Type(...)). 
241   *   See comments of class {@link GralMngBuild_ifc}.
242   * <li>2013-03-13 Hartmut new {@link #getContentIdent()}, {@link #setContentIdent(long)}
243   * <li>2013-03-13 Hartmut new {@link #bShouldInitialize}
244   * <li>2012-09-24 Hartmut chg: {@link #getName()} now returns {@link #sDataPath} or {@link #sCmd} if the other info are null.
245   * <li>2012-09-24 Hartmut chg: {@link #refreshFromVariable(VariableContainer_ifc)} for long and double values.
246   * <li>2012-09-17 Hartmut new {@link ConfigData} and {@link #cfg}, used yet only for {@link ConfigData#showParam}.
247   * <li>2012-09-17 Hartmut chg whatIsChanged#whatIsChanged} moved from {@link GralTextField}. The concept is valid for all widgets
248   *   in cohesion with the concept of the whatIsChanged}.
249   * <li>2012-09-17 Hartmut chg {@link #setActionShow(GralUserAction, String[])} now with parameters.  
250   *   
251   * <li>2012-08-21 Hartmut new {@link DynamicData} and {@link #dyda} for all non-static widget properties, the dynamic data
252   *   are that data which are used for all widget types in runtime. TODO: store the configuration data (all other) in an
253   *   inner class CfgData or in a common class cfgdata see {@link org.vishia.gral.cfg.GralCfgData}.
254   * <li>2012-08-21 The method {@link #setBackColor(GralColor, int)}, {@link #setLineColor(GralColor, int)} and {@link #setTextColor(GralColor)}
255   *  are declared in the {@link GralWidget_ifc} yet and implemented here using {@link #dyda}.  
256   * <li>2012-07-29 Hartmut chg: {@link #setFocus()} and {@link #setFocus(int, int)} can be called in any thread yet.
257   * <li>2012-04-25 Hartmut some enhancements
258   * <li>2012-04-07 Hartmut chg: {@link #refreshFromVariable(VariableContainer_ifc)} regards int16, int8
259   * <li>2012-04-01 Hartmut new: {@link #refreshFromVariable(VariableContainer_ifc)}. A GralWidget is binded now
260   *   more to a variable via the new {@link VariableAccessWithIdx} and then to any {@link VariableAccess_ifc}.
261   *   It is possible to refresh the visible information from the variable.
262   * <li>2012-01-04 Hartmut new: {@link #repaintDelay}, use it.  
263   * <li>2012-03-31 Hartmut new: {@link #isVisible()} and {@link ImplAccess#setVisibleState(boolean)}.
264   *   renamed: {@link #implMethodWidget_} instead old: 'gralWidgetMethod'.
265   * <li>2012-03-08 Hartmut chg: {@link #repaintRequ} firstly remove the request from queue before execution,
266   *   a new request after that time will be added newly therefore, then execute it.
267   * <li>2012-02-22 Hartmut new: catch on {@link #repaintGthread()} and continue the calling level
268   *   because elsewhere the repaint order isn't removed from the {@link org.vishia.gral.base.GralGraphicThread#addDispatchOrder(GralGraphicTimeOrder)}-queue.
269   * <li>2012-02-22 Hartmut new: implements {@link GralSetValue_ifc} now.
270   * <li>2012-01-16 Hartmut new Concept {@link #repaint()}, can be invoked in any thread. With delay possible. 
271   *   All inherit widgets have to be implement  {@link #repaintGthread()}.
272   * <li>2011-12-27 Hartmut new {@link #setHtmlHelp(String)}. For context sensitive help.
273   * <li>2011-11-18 Hartmut bugfix: {@link #setFocusGThread()} had called {@link GralMng#setFocus(GralWidget)} and vice versa.
274   *   Instead it should be a abstract method here and implemented in all Widgets. See {@link org.vishia.gral.swt.SwtWidgetHelper#setFocusOfTabSwt(org.eclipse.swt.widgets.Control)}.
275   * <li>2011-10-15 Hartmut chg: This class is now abstract. It is the super class for all wrapper implementations.
276   *   The wrapper implements special interfaces for the kind of widgets. It is more simple for usage, less instances to know.
277   *   A GralWidget is able to test with instanceof whether it is a special widget. The element widget is removed because the reference
278   *   to the implementation widget will be present in the derived classes.
279   * <li>2011-10-01 Hartmut new: method {@link #setFocusGThread()}. It wrappes the {@link GralMng_ifc#setFocus(GralWidget)}.
280   * <li>2011-09-18 Hartmut chg: rename from WidgetDescriptor to GralWidget. It is the representation of a Widget in the graphic adapter
281   *     inclusive some additional capabilities in comparison to basic graphic widgets, like {@link #sFormat} etc.
282   * <li>2011-09-11 Hartmut chg: rename itsPanel to {@link #itsMng}. The original approach was, that the PanelManager manages only one panel
283   *     then one window. Now the GralPanelMng manages all panels of one application. It is instantiated only one time.
284   *     Therefore this association isn't the associated panel where the widget is member of. 
285   * <li>2011-09-08 Hartmut new: method {@link #setLineColor(GralColor, int)}.
286   *     Background: Any widget have a background. Most of widgets have lines. The color of them 
287   *     should be able to animate if user data are changed.        
288   * <li>2011-09-04 Hartmut new: method {@link #setBackColor(GralColor, int)}.        
289   * <li>2011-08-14 Hartmut chg: {@link #widget} is now type of {@link GralWidget_ifc} and not Object.
290   *    Generally it is the reference to the implementing code of the widget. The implementing code 
291   *    may based on a graphic base widget (SWT: Control) and implements the {@link GralWidget_ifc}, 
292   *    or it references the graphic base widget instance. The class {@link SwtWidgetSimpleWrapper} 
293   *    is able to wrap simple graphical base widget instances.
294   * <li>2011-08-13 Hartmut new: WidgetDescriptor now contains the position of the widget. 
295   *     It is used for resizing of large widgets.
296   *     A large widget is a widget, which lengthens over the panel and it is changed in size with panel size change. 
297   *     A typical example is a text-area-widget.
298   * <li>2011-06-20 Hartmut new: method {@link #gralMng()} It is the panel manager!
299   * <li>2011-05-26 Hartmut new: separate action in {@link #actionChanging} and {@link #actionShow}.
300   *     The actionChanging was the old action. It was called from the listener of the widgets of the underlying graphic
301   *     if any changing is done on the widget (mouse click etc). But the actionShow is necessary too 
302   *     to prepare values to animate widgets without knowledge of the special kind of widget. The application
303   *     should call only the actionShow, all specifics should be done in the action.
304   * <li>2011-05-22 Hartmut new: The Widget knows its {@link #itsCfgElement} now if it is present.
305   *   It is possible to configurate widgets with the GralDesigner up to now.
306   * <li>2011-05-14 Hartmut chg: The WidgetDescriptor is now non-generic. 
307   *   Older Concept: Store the GUI implementation widget type as generic type there.
308   *   But now a widget is stored as Object and it is casted in the implementation. It is more simple 
309   *   because the type is only used and the casting is only necessary in the implementation level.       
310   * <li>2011-06-00 Hartmut created
311   * </ul>
312   * 
313   * <b>Copyright/Copyleft</b>:<br>
314   * For this source the LGPL Lesser General Public License,
315   * published by the Free Software Foundation is valid.
316   * It means:
317   * <ol>
318   * <li> You can use this source without any restriction for any desired purpose.
319   * <li> You can redistribute copies of this source to everybody.
320   * <li> Every user of this source, also the user of redistribute copies
321   *    with or without payment, must accept this license for further using.
322   * <li> But the LPGL is not appropriate for a whole software product,
323   *    if this source is only a part of them. It means, the user
324   *    must publish this part of source,
325   *    but doesn't need to publish the whole source of the own product.
326   * <li> You can study and modify (improve) this source
327   *    for own using or for redistribution, but you have to license the
328   *    modified sources likewise under this LGPL Lesser General Public License.
329   *    You mustn't delete this Copyright/Copyleft inscription in this source file.
330   * </ol>
331   * If you intent to use this source without publishing its usage, you can get
332   * a second license subscribing a special contract with the author. 
333   * 
334   * @author Hartmut Schorrig = hartmut.schorrig@vishia.de
335   */
336  public static final String sVersion = "2016-09-02";
337
338  
339  /**The widget manager from where the widget is organized. Most of methods need the information
340   * stored in the panel manager. This reference is used to set values to other widgets. */
341  protected GralMng itsMng;
342  
343  /**The position of the widget. It may be null if the widget should not be resized. */
344  private GralPos _wdgPos;
345
346
347  /**The implementation specific widget. The instance is derived from the graphic implementation-specific
348   * super class of all widgets such as {@link org.eclipse.swt.widgets.Control} or {@link java.awt.Component}. 
349   * The user can check and cast this instance if some special operations may be need graphic-implementation-dependent.
350   * It is recommended that implementation specific features should not used if they are not necessary
351   * and the application should be held graphic implementation independent.
352   * <br><br>
353   * This reference is null if the GralWidgets extends the Graphic specific implementation widget.
354   * It should be used in the future (2013-06).
355   */
356  public ImplAccess _wdgImpl;
357
358
359  protected GralMngBuild_ifc buildMng;
360  
361  /**Association to the configuration element from where this widget was built. 
362   * If the widget is moved or its properties are changed in the 'design mode' of the GUI,
363   * this aggregate data are adjusted and re-written to a file. The configuration elemenet
364   * contains all data which are necessary to build the appearance of the GUI.
365   * <br>
366   * If this aggregation is null, the widget can't be changed in the design mode of the GUI.
367   * It is created directly without configuration data. 
368   */
369  private GralWidgetCfg_ifc itsCfgElement;
370
371
372
373  protected static class ActionChangeSelect
374  {
375    ActionChange onAnyChangeContent;
376    ActionChange onEnter;
377    ActionChange onCtrlEnter;
378    ActionChange onFocusGained;
379    ActionChange onChangeAndFocusLost;
380    ActionChange onMouse1Dn;
381    ActionChange onMouse1Up;
382    ActionChange onMouse1UpOutside;
383    ActionChange onMouse2Up;
384    ActionChange onMouse1Double;
385    ActionChange onMouseWheel;
386    ActionChange onDrop;
387    ActionChange onDrag;
388    
389  }
390
391
392
393
394
395
396  
397  /**This class holds common configuration data for widgets.
398   */
399  public final static class ConfigData
400  {
401    /**Action method for showing. */
402    protected GralUserAction actionShow;
403
404    /**Textual description of the showing method. */
405    private String sShowMethod;
406
407    private String[] sShowParam;
408    
409    
410    /**Either this or {@link #actionChangeSelect} is set. */
411    protected ActionChange actionChange1;
412    
413    protected ActionChangeWhen[] actionChange1When;
414    
415    /**Either this or {@link #actionChange} is set. */
416    protected ActionChangeSelect actionChangeSelect;
417
418    /**Action method on activating, changing or release the widget-focus. */
419    //public GralUserAction actionChanging;
420    
421    /**Parameter to the change action. */
422    //public String[] sActionChangeArgs;
423    
424
425    protected GralUserAction actionDrag;
426
427    protected GralUserAction actionDrop;
428
429    /**This action will be called if the widget gets the focus. */
430    protected GralUserAction actionFocused;
431
432    /**Parameter which are used from a {@link GralWidget#setActionShow(GralUserAction, String[])} method.
433     * The parameter are converted from a String given form.
434     */
435    public Object[] showParam;
436    
437        /**A standard action for a specific widget for example button, which is executed
438     * independently and additional to the user action. */
439    public GralMouseWidgetAction_ifc mouseWidgetAction;
440    
441    
442    /**Bits see {@link GralMouseWidgetAction_ifc#mUser1down} etc. */
443    public int mMouseToActionChange;
444    
445
446  }
447  
448  /**Reference to the common configuration data for widgets. */
449  public ConfigData cfg = new ConfigData();
450  
451  /**Name of the widget in the panel. */
452  public String name;
453  
454    
455  
456  
457  /**Panel where the widget is member of. */
458  //public final GralPanelContent itsPanel;
459  
460  /**The graphical widget. It is untyped because it depends on the underlying graphic system. 
461   * It may be a wrapper class arround a graphical widget too. 
462   * This element is used for setting operations, which depends from the graphic system
463   * and the type of the widget. It is only used in the graphic-system-special implementation.
464   * */
465  //protected GralWidget_ifc widget;
466  
467  /**numeric info what to do (kind of widget). 
468   * <ul>
469   * <li>B: a Button: has a color, has an action method.
470   * <li>c: curve view
471   * <li>C: traCk of curve view
472   * <li>D: a LED
473   * <li>xxx E: an edit field, 1 line
474   * <li>xxx e: an edit area
475   * <li>F: input file selection field
476   * <li>f: GralFileSelector
477   * <li>h; HTML text  box (browser)
478   * <li>I: a line
479   * <li>i: an image
480   * <li>k: a tree node
481   * <li>K: a tree leafe
482   * <li>l: a list or table
483   * <li>L: a list or table line
484   * <li>M: a Menu entry
485   * <li>n: a Horizontal Selector
486   * <li>r: a rectangle area 
487   * <li>P: a plot or canvas area 
488   * <li>R: a rectangle line 
489   * <li>S: a text field to show
490   * <li>s: a text area.
491   * <li>T: a text input field
492   * <li>t: a text input area.
493   * <li>U: a graphical value representation (bar etc)
494   * <li>V: a graphical value enter representation (slider etc)
495   * <li>w: A window.
496   * <li>@: A Tabbed Panel
497   * <li>$: Any Panel (composite)
498   * <li>+: A canvas panel
499   * <li>*: A type (not a widget, common information) See {@link org.vishia.gral.cfg.GralCfgData#new_Type()}
500   * </ul>
501   * */
502  public final char whatIs;
503  
504  public String sToolTip;
505  
506  /**Textual informations about content. It may be a data path or adequate. */
507  private String sDataPath;
508  
509  /**If not null, it is the right-mouse-button menu for this widget. */
510  protected GralMenu contextMenu;
511  
512  
513  /**An index associated to the data. */
514  private int dataIx;
515  
516
517  /**Textual info about representation format. 
518   * See usage in {@link GralTextField}.
519   * */
520  protected String sFormat;
521  
522  /**Numeric informations about the content. */
523  //int[] indices;
524  
525  /**One variable which is associated with this widget. This reference may be null.
526   * Alternatively {@link #variables} may be set.
527   * See {@link #getVariableFromContentInfo(VariableContainer_ifc)}.
528   * See {@link #setValue(float)}, {@link #setValue(String)}.
529   * See {@link #indices} to use an array- or bit-variable.
530   */
531  private VariableAccess_ifc variable;
532  
533  /**More as one variable which are associated with this widget. This reference may be null.
534   * Alternatively {@link #variable} may be set.
535   * See {@link #getVariableFromContentInfo(VariableContainer_ifc)}.
536   * See {@link #setValue(float)}, {@link #setValue(String)}.
537   * See {@link #indices} to use an array- or bit-variable.
538   */
539  private List<VariableAccess_ifc> variables;
540  
541  
542  /**Any widget can have a command String, which can be quest for example in an action. 
543   * The widget can be identified by its {@link #getCmd()} independent of its name. */
544  public String sCmd;
545  
546  
547  /**The relative path to a html help label (maybe an URL, or file, or file with label). */
548  protected String htmlHelp;
549  
550  /**Any special info, may be set from any user class. It should help to present the content. 
551   * This info can be set and changed after registration. */
552  private Object oContentInfo;
553  
554  
555  
556  
557  /**Set true if its shell, tab card etc is be activated. Set false if it is deactivated.
558   * It is an estimation whether this widget is be shown yet. 
559   */
560  protected boolean bVisibleState = true;
561  
562  
563  /**Set to true on {@link #setEditable(boolean)}. 
564   * With that designation the cyclically refresh of the text field can be prevented. 
565   * */
566  protected boolean bEditable;
567  
568  
569  /**Set on focus gained, false on focus lost. */
570  protected boolean bHasFocus;
571  
572  /**If this bit is true on an edit field, it should be initialized.
573   * 
574   */
575  protected boolean bShouldInitialize = true;
576  
577  
578  /**Standard delay to repaint if {@link #repaint()} is called without arguments. 
579   * It delays a few time because an additional process can be occure in a short time, and only one repaint should be invoked.
580   * The repaintDelayMax limits a shifting to the future. See {@link org.vishia.event.EventTimeout}, that is used.
581   * 
582   */
583  protected int repaintDelay = 30, repaintDelayMax = 100;
584
585  /**The time when the bVisible state was changed. */
586  long lastTimeSetVisible = 0;
587  
588  protected long dateUser;
589  
590  /**This inner class holds the dynamic data of a widget.
591   * This data are existent for any widget independent of its type.
592   * It can be used in a specific way depending on the widget type.
593   */
594  public final static class DynamicData {
595    
596    /**32 bit what is changed, see {@link GralWidget#chgColorText} etc. 
597     * TODO should be protected. */
598    private AtomicInteger whatIsChanged = new AtomicInteger(); 
599    
600    /**Sets what is changed, Bits defined in {@link GralWidget.ImplAccess#chgColorBack} etc.
601     * @param mask one bit or some bits. ImplAccess.chgXYZ
602     */
603    public void setChanged(int mask){
604      int catastrophicalCount = 1000;
605      boolean bOk;
606      do {
607        int act =whatIsChanged.get();
608        int newValue = act | mask;
609        bOk = whatIsChanged.compareAndSet(act, newValue);
610      } while(!bOk && --catastrophicalCount >= 0);
611    }
612    
613    
614    /**Returns the bits what is changed.
615     * All bits which were evaluated should be acknowledged via {@link #acknChanged(int)}
616     * @return
617     */
618    public int getChanged(){ return whatIsChanged.get(); }
619    
620    /**Resets what is changed, Bits defined in {@link GralWidget.ImplAccess#chgColorBack} etc.
621     * This routine should be called in the paint routine whenever the change was succeeded.
622     * @param mask one bit or some bits. ImplAccess.chgXYZ
623     */
624    public void acknChanged(int mask){
625      int catastrophicalCount = 1000;
626      boolean bOk;
627      do {
628        int act =whatIsChanged.get();
629        int newValue = act & ~mask;
630        bOk = whatIsChanged.compareAndSet(act, newValue);
631      } while(!bOk && --catastrophicalCount >= 0);
632    }
633    
634    
635    /**Three colors for background, line and text should be convert to the platforms color and used in the paint routine. 
636     * If this elements are null, the standard color should be used. */
637    public GralColor backColor = GralColor.getColor("wh"), backColorNoFocus = GralColor.getColor("lgr")
638      , lineColor = GralColor.getColor("bk"), textColor = GralColor.getColor("bk");
639
640    /**It depends of the pixel size. Therefore set after setToPanel, if GralMng is known. */
641    public GralFont textFont;
642    
643    /**A text to display. */
644    public String displayedText;
645    
646    /**Any specific value. */
647    public Object[] oValues;
648    
649    public float fValue, minValue, maxValue;
650    
651    /**If a long or int value is given, it is stored here. */
652    public long lValue;
653    
654    public Object visibleInfo;
655    
656    public Object userData;
657    
658    public float[] fValues;
659
660    /**Set to true from any listener of the implementation level if the cursor in the widget is moved or such GUI handling.
661     * Then the content won't be overridden by {@link #setText(CharSequence)} furthermore till the focus is left.
662     */
663    protected boolean bTouchedField;
664
665    /**Set to true from any listener of the implementation level if the data of the widget was changed from GUI handling.
666     * If the data are changed from any Gral method invocation, this bit should not set to true.
667     * For example a key listener changes the content of a text edit field, then this bit should be set.
668     * This bit should be cleared if the GUI-content of the widget is synchronized with the widget data cells. 
669     * Note that the GUI-content of a widget can be changed only in the GUI thread, whereby the content of the 
670     * {@link #dyda} can be read and write in any threat. This bit helps to synchronize. */
671    protected boolean bTextChanged;
672  }
673  
674  
675  protected final DynamicData dyda = new DynamicData();
676  
677  
678  //protected GralWidget(char whatIs)
679  //{ this.whatIs = whatIs;
680  //}
681
682  /**Creates a widget.
683   * @param posString If null then the widget is not positioned. !=null then a position string.
684   *   The position is taken relative to the {@link GralMng#pos}, the {@link GralMng#pos} is changed
685   *   see {@link GralPos#setPosition(CharSequence, GralPos)}
686   * @param sName If posString is null and sName has the form "@pos = name" then this is a combination from name and pos.
687   *   The name should be unified to indent a widget by its name. 
688   * @param whatIs
689   * @throws ParseException 
690   * @deprecated since 2016-09: The idea is: Use always one String for "@pos=name".
691   */
692  @Deprecated public GralWidget(String pos, String name, char whatIs){ 
693    this(pos !=null ? ( (pos.startsWith("@") ? "" : "@") + pos + "=" + name) : name, whatIs);
694  }
695
696  
697  
698  /**Creates a widget.
699   * @param sName has the form "@pos = name" then this is a combination from position string and name.
700   *   The name should be unified to indent a widget by its name.
701   *   Syntax of pos: see {@link GralPos#setPosition(CharSequence, GralPos)}. It is the same syntax as in textual config scripts. 
702   * @param whatIs See {@link #whatIs}
703   */
704  public GralWidget(String sPosName, char whatIs){ 
705    int posName;
706    String posString1;
707    if(sPosName !=null && sPosName.startsWith("@") && (posName= sPosName.indexOf('='))>0) {
708      posString1 = sPosName.substring(0, posName).trim();
709      this.name = sPosName.substring(posName+1).trim();
710    } else {
711      this.name = sPosName;
712      posString1 = null;
713    }
714    //this.widget = null;
715    this.whatIs = whatIs;
716    //bVisibleState = whatIs != 'w';  //true for all widgets, false for another Windows. 
717    bVisibleState = false;  //kkkk initially false for all widgets, it will be set true on set focus. For tabbed panels it should be false for the inactive panel. 
718    this.itsCfgElement = null;
719    itsMng = GralMng.get();
720    assert(itsMng !=null);  //should be created firstly in the application, since 2015-01-18
721    if(posString1 !=null) {
722      try{
723        if(whatIs == 'w') {
724          //a window: don't change the GralMng.pos, create a new one.
725          GralPos pos = new GralPos();
726          pos.panel = itsMng.getPrimaryWindow();
727          this._wdgPos = pos.setNextPos(posString1);
728        } else {
729          //a normal widget on a panel
730          this._wdgPos = itsMng.pos().pos.setNextPos(posString1);
731        }
732        registerWidget();
733      } catch(ParseException exc) {
734        throw new IllegalArgumentException("GralWidget - position is syntactical faulty; " + posString1);
735      }
736    } //else: don't set the pos, it is done later 
737  }
738  
739  
740  void registerWidget() {
741    if(this._wdgPos.panel == this) {
742      //don't register the panel itself!
743    } else if(_wdgPos.panel !=null){
744      this._wdgPos.panel.addWidget(this, _wdgPos.toResize());
745    } else {
746      this._wdgPos.panel = itsMng.getCurrentPanel();
747      System.out.println("GralWidget.GralWidget - pos without panel");
748    }
749  }
750  
751  
752  @Deprecated public GralWidget(String sName, char whatIs, GralMng mng)
753  { this(sName, whatIs);
754    itsMng = GralMng.get();
755    assert(itsMng !=null);  //should be created firstly in the application, since 2015-01-18
756    if(mng !=null){
757      assert(this.itsMng == mng);
758      //sets the mng and the pos of Window in that cases
759      //where the mng is present on ctor. (not in new form)
760      //setPanelMng(mng);   
761      /*
762      if(mng.posUsed){
763        mng.pos.setNextPosition();
764        mng.posUsed = false;
765      }
766      this.pos = mng.getPositionInPanel();  //Note: makes a clone because the pos in panel is reused. 
767      */
768    }
769  }
770  
771  
772  
773  /**Standard implementation of  @see org.vishia.gral.ifc.GralWidget_ifc#setToPanel()
774   * Only large widgets (contains more as one GralWidget) should override this method.
775   * If the _wdgImpl is initialized already, this method does nothing. It is possible to invoke this for all existing widgets
776   * of a panel, only new widgets are initialized with them. 
777   * @before 2016-07 it has thrown an exception on repeated invocation.
778   */
779  @Override public void createImplWidget_Gthread() throws IllegalStateException {
780    if(_wdgImpl ==null){ // throw new IllegalStateException("setToPanel faulty call - GralTable;");
781      GralMng mngg = GralMng.get();  //The implementation should be instantiated already!
782      if(dyda.textFont == null) { //maybe set with knowledge of the GralMng before.
783        dyda.textFont = mngg.propertiesGui.getTextFont(mngg.pos().pos.height());
784        dyda.setChanged(ImplAccess.chgFont);
785      }
786      mngg.createImplWidget_Gthread(this);
787    }
788  }
789
790  
791  
792  /**
793   * @see org.vishia.gral.ifc.GralWidget_ifc#setToPanel(org.vishia.gral.ifc.GralMngBuild_ifc)
794   * @deprecated use {@link #createImplWidget_Gthread()}
795   */
796  @Override @Deprecated public final void setToPanel(GralMngBuild_ifc mngUnused) throws IllegalStateException { createImplWidget_Gthread(); }
797
798  
799  public GralPos pos(){ return _wdgPos; } 
800  
801  
802  
803  public void chgPos(GralPos newPos){
804    dyda.setChanged(ImplAccess.chgPos);
805    _wdgPos = newPos;
806  }
807  
808  /**Returns this.
809   * @see org.vishia.gral.base.GetGralWidget_ifc#getGralWidget()
810   */
811  @Override public GralWidget getGralWidget(){ return this; }
812  
813  
814  /**Default implementation:Most of widgets may have only one implementation widget. This returns null.
815   * @see org.vishia.gral.ifc.GralWidget_ifc#getWidgetMultiImplementations()
816   */
817  //public Object[] getWidgetMultiImplementations(){ return null; }
818
819  
820  
821  public void setPrimaryWidgetOfPanel(){
822    _wdgPos.panel.setPrimaryWidget(this);
823  }
824
825  
826  @Override public String getName(){ 
827    if(name !=null) return name;
828    else if(sDataPath !=null) return sDataPath;
829    else if(sCmd !=null) return sCmd;
830    else return toString();
831  }
832  
833  /**Sets the graphical widget. It is a wrapper around the widget of the graphic implementation base.
834   * This method shouldn't invoke by an user's application. It is only invoked by the gral itself. 
835   * @param widget The wrapper.
836   */
837  //public void setGraphicWidgetWrapper(GralWidget_ifc widget){ this.widget = widget; }
838  
839  /**Gets the graphical widget. The difference between this class and the graphical widget is:
840   * This class contains unified description data to any kind of widget, where the graphical widget
841   * is a special or simple wrapper around the implementation of the widget in the graphical implementation base.
842   * 
843   * @return The gral graphical widget. Note: The type can be instanceof some derived interfaces of the gral.
844   * @deprecated
845   */
846  //@Deprecated
847  //public GralWidget_ifc getGraphicWidgetWrapper(){ return this; }
848  
849  
850  /**Sets a application specific info. 
851   * It should help to present user data which are associated to this widget. 
852   * This info can be set and changed anytime. 
853   * @deprecated use {@link #setData(Object)}
854   * */
855  public void setContentInfo(Object content){  oContentInfo = content;}
856  
857  /**Gets the application specific info. See {@link #setContentInfo(Object)}. 
858   * @deprecated use {@link #getData()}
859   */
860  public Object getContentInfo(){ return oContentInfo; }
861  
862 
863  
864  /**Sets a application specific data. 
865   * It should help to present user data which are associated to this widget. 
866   * This info can be set and changed anytime. */
867  public void setData(Object data){  oContentInfo = data;}
868  
869  /**Gets the application specific info. See {@link #setContentInfo(Object)}. */
870  public Object getData(){ return oContentInfo; }
871  
872 
873  
874  @Override public void setEditable(boolean editable){
875    if(bEditable != editable) {
876      bEditable = editable;
877      dyda.setChanged(ImplAccess.chgEditable); 
878      repaint(repaintDelay, repaintDelayMax);
879    }
880  }
881
882  @Override public boolean isEditable(){ return bEditable; }
883  
884
885  @Override public boolean isNotEditableOrShouldInitialize(){ return !bEditable || bShouldInitialize; }
886  
887  /**Sets the data path. It is a String in application context.
888   * @param sDataPath
889   */
890  @Override public void setDataPath(String sDataPath){  
891    this.sDataPath = sDataPath;
892    variable = null;
893    variables = null;
894  }
895  
896  /**Changes the data path
897   * @param sDataPath the new one
898   * @return the last one.
899   */
900  public String getDataPath(String sDataPath)
901  {  String sDataPathLast = this.sDataPath;
902    this.sDataPath = sDataPath;
903    return sDataPathLast;
904  }
905  
906  /**Any widget can have a command String, which can be quest for example in an action. 
907   * The widget can be identified by this method independent of its name. See {@link #setCmd(String)}. */
908  public String getCmd(){ return sCmd; }
909  
910  
911  /**Get the command string from the {@link #setCmd(String)} with choice of an option.
912   * The command string should have the form "base[Option1|Option2|Option3]End" 
913   * whereby base and end can be empty. if option is <0 an IndexOutOfBoundsException is thrown.
914   * If option is >= the given number of options, the option part is replaced by "??".
915   * That may be more helpfull to detect errors. 
916   * @param option number >=0
917   * @return "baseOptionEnd"
918   */
919  public String getCmd(int option){
920    int pos1 = sCmd.indexOf('[');
921    int pos2 = sCmd.indexOf(']', pos1+1);
922    if(pos1 >=0 && pos2 > pos1){
923      String sBase = sCmd.substring(0, pos1);
924      String sEnd = sCmd.substring(pos2+1);  //maybe ""
925      String[] sOptions = sCmd.substring(pos1+1, pos2).split("\\|");
926      if(option >= sOptions.length){ return sBase + "??" + sEnd; }
927      else{ return sBase + sOptions[option] + sEnd; }
928    } else {
929      return sCmd;
930    }
931  }
932  
933  /**Any widget can have a command String, which can be quest for example in an action. 
934   * The widget can be identified by its {@link #getCmd()} independent of its name which can be set on runtime with this method. */
935  @Override public void setCmd(String cmd){ sCmd = cmd; }
936  
937  
938  /**Gets the data path. It is a String in application context.
939   */
940  @Override public String getDataPath(){ return sDataPath; }
941  
942  /**Sets the action in application context for processing of user handling for the widget.
943   * Handling means, pressing button, user inputs of text fields
944   * The method {@link GralUserAction#exec(int, GralWidget_ifc, Object...)} will be called with following key codes:
945   * <ul>
946   * <li>{@link KeyCode#focusGained}, {@link KeyCode#focusLost} on enter and leave a text field.
947   * <li>{@link KeyCode#mouse1Down} etc, any mouse events on any widget.
948   * <li>{@link KeyCode#valueChanged} if the content of a text field is changed.
949   * <li>Some more TODO, set breakpoint in the routine.
950   * </ul> 
951   * @param action any instance. Its action method is invoked depending of the type of widget
952   *        usual if the user takes an action on screen, press button etc.
953   *        
954   */
955  @Deprecated public void setActionChange(GralUserAction action){ specifyActionChange(null, action, null); } //cfg.actionChanging = action; }
956  
957  
958  private static ActionChangeWhen[] whenAll = 
959  { ActionChangeWhen.onAnyChgContent
960  , ActionChangeWhen.onFocusGained
961  , ActionChangeWhen.onChangeAndFocusLost
962  , ActionChangeWhen.onCtrlEnter
963  , ActionChangeWhen.onDrag
964  , ActionChangeWhen.onDrop
965  , ActionChangeWhen.onEnter
966  , ActionChangeWhen.onMouse1Double
967  , ActionChangeWhen.onMouse1Dn
968  , ActionChangeWhen.onMouse1Up
969  , ActionChangeWhen.onMouse1UpOutside
970  , ActionChangeWhen.onMouse2Up
971  , ActionChangeWhen.onMouseWheel
972  };
973
974  
975  /**Sets the action to invoke after changing or touching the widget.
976   * @param sAction maybe null, String for visualization, especially menu entry for context menu.
977   * @param action The action. null admissible to remove the existing action. 
978   * @param args possible arguments for the action or null
979   * @param when List of type of action, maybe empty, then the given action is set for all conditions.
980   *   Especially <code>setActionChange(null, null, null) removes all actions.
981   */
982  public void specifyActionChange(String sAction, GralUserAction action, String[] args, ActionChangeWhen... when){ 
983    ActionChange action1 = action == null ? null : new ActionChange(sAction, action, args);
984    
985    if(when.length==0){
986      cfg.actionChange1 = action1;
987      cfg.actionChangeSelect = null;
988      cfg.actionChange1When = null;
989    } else if(cfg.actionChange1 == null && cfg.actionChangeSelect == null) {
990      //first invocation, only one action but for special operations (when)
991      cfg.actionChange1 = action1;
992      cfg.actionChangeSelect = null;
993      cfg.actionChange1When = when;
994    } else {
995      if(cfg.actionChangeSelect == null) { cfg.actionChangeSelect = new ActionChangeSelect(); }
996      if(cfg.actionChange1 !=null) { //given
997        ActionChangeWhen[] whenGiven = cfg.actionChange1When == null ? whenAll : cfg.actionChange1When;
998        for(ActionChangeWhen when1: whenGiven) {
999          specifyActionChangeWhen(cfg.actionChange1, when1);
1000        }
1001        cfg.actionChange1 = null;
1002      }
1003      for(ActionChangeWhen when1: when) {
1004        specifyActionChangeWhen(action1, when1);
1005      }
1006    }
1007  }
1008  
1009  
1010  private void specifyActionChangeWhen(ActionChange action, ActionChangeWhen when)
1011  {
1012    switch(when){
1013    case onAnyChgContent: cfg.actionChangeSelect.onAnyChangeContent = action; break;
1014    case onCtrlEnter: cfg.actionChangeSelect.onCtrlEnter = action; break;
1015    case onFocusGained: cfg.actionChangeSelect.onFocusGained = action; break;
1016    case onChangeAndFocusLost: cfg.actionChangeSelect.onChangeAndFocusLost = action; break;
1017    case onDrag: cfg.actionChangeSelect.onDrag = action; break;
1018    case onDrop:cfg.actionChangeSelect.onDrop = action;  break;
1019    case onEnter: cfg.actionChangeSelect.onEnter = action; break;
1020    case onMouse1Double: cfg.actionChangeSelect.onMouse1Double = action; break;
1021    case onMouse1Dn: cfg.actionChangeSelect.onMouse1Dn = action; break;
1022    case onMouse1Up: cfg.actionChangeSelect.onMouse1Up = action; break;
1023    case onMouse1UpOutside: cfg.actionChangeSelect.onMouse1UpOutside = action; break;
1024    case onMouse2Up: cfg.actionChangeSelect.onMouse2Up = action; break;
1025    case onMouseWheel: cfg.actionChangeSelect.onMouseWheel = action; break;
1026    default: throw new IllegalArgumentException("not all when-conditions");
1027    }
1028  }
1029  
1030  
1031  
1032  public void specifyContextMenu(GralMenu menu) {
1033    if(_wdgImpl !=null && _wdgImpl.wdgimpl !=null) { _wdgImpl.wdgimpl.specifyContextMenu(menu); }
1034    else { } //TODO set to instanciation data
1035  
1036  }
1037  
1038  
1039  
1040  
1041  /**Gets the action to execute on changing a widget.
1042   * If only one action is given with <code>setActionChange(String, action, args) without a specified when then this action is returned in any case,
1043   * especially if when == null. If specific actions were set, this action is returned, or null.
1044   * @param when type of action, if null then returns the only one given action or null if only specific actions are given
1045   * @return null if the action is not set.
1046   */
1047  @Override public ActionChange getActionChange(ActionChangeWhen when) {
1048    return getActionChangeStrict(when, false);
1049  }
1050  
1051  
1052  /**Gets the action to execute on changing a widget.
1053   * If only one action is given with <code>setActionChange(String, action, args) without a specified when then this action is returned in any case,
1054   * especially if when == null. If specific actions were set, this action is returned, or null.
1055   * @param when type of action, if null then returns the only one given action or null if only specific actions are given
1056   * @param strict if true then a common action without when-designation is not returned if when is not null. 
1057   * @return null if the action is not set.
1058   */
1059  public ActionChange getActionChangeStrict(ActionChangeWhen when, boolean strict) {
1060    if(cfg.actionChange1 !=null) {
1061      if(cfg.actionChange1When == null){ 
1062        return strict && when !=null 
1063          ? null                //specific action required and strict: returns null though a common action is given.
1064          : cfg.actionChange1;  //no specific action required or set, or no specifia action set and not strict: returns the only one action.
1065      } else {
1066        for(ActionChangeWhen when1:cfg.actionChange1When){
1067          if(when1 == when) return cfg.actionChange1;
1068        }
1069        //not found:
1070        return null;
1071      }
1072    } else {
1073      //actionChangeSelect is given:
1074      if(when == null || cfg.actionChangeSelect == null) return null;
1075      switch(when){
1076      case onAnyChgContent: return cfg.actionChangeSelect.onAnyChangeContent;
1077      case onCtrlEnter: return cfg.actionChangeSelect.onCtrlEnter;
1078      case onFocusGained: return cfg.actionChangeSelect.onFocusGained;
1079      case onChangeAndFocusLost: return cfg.actionChangeSelect.onChangeAndFocusLost;
1080      case onDrag: return cfg.actionChangeSelect.onDrag;
1081      case onDrop: return cfg.actionChangeSelect.onDrop;
1082      case onEnter: return cfg.actionChangeSelect.onEnter;
1083      case onMouse1Double: return cfg.actionChangeSelect.onMouse1Double;
1084      case onMouse1Dn: return cfg.actionChangeSelect.onMouse1Dn;
1085      case onMouse1Up: return cfg.actionChangeSelect.onMouse1Up;
1086      case onMouse1UpOutside: return  cfg.actionChangeSelect.onMouse1UpOutside;
1087      case onMouse2Up: return cfg.actionChangeSelect.onMouse2Up;
1088      case onMouseWheel: return cfg.actionChangeSelect.onMouseWheel;
1089      default: throw new IllegalArgumentException("not all when-conditions");
1090      }
1091    }
1092  }
1093  
1094  
1095  
1096  
1097  
1098  
1099  /**Sets the action for mouse operation. Either it is a special mouse handler or the {@link #setActionChange(GralUserAction)}
1100   * is used with {@link KeyCode#mouse1Down} etc. key code. 
1101   * It works with all widgets which uses {@link org.vishia.gral.swt.SwtGralMouseListener.MouseListenerGralAction} respectively the adequate implementation mouse listener.
1102   * By contract of Gral, all widgets should add the mouse listener. Therefore no further special action is necessary to activate the requested mouse behavior. 
1103   * Note: If you set an abbreviate mouse handler for Button etc. where the mouse is an essential functionality
1104   *   that functionality is disturbed. An extra handler should base on that special mouse handler, for example
1105   *   {@link GralButton.MouseActionButton} and should invoke that actions calling super.mouse1Down(...) etc.
1106   *   For that widgets usual the {@link #setActionChange(GralUserAction)} is called also, that may be sufficient. 
1107   * @param mouseWidgetAction null possible, elsewhere the mouse operation callback instance.
1108   * @param mUser One or more of the bits {@link GralMouseWidgetAction_ifc#mUser1down} etc. 
1109   *   If given the {@link #setActionChange(GralUserAction)} is invoked with that operation instead the given (or usually not given) mouseWidgetAction.
1110   */
1111  public void setActionMouse(GralMouseWidgetAction_ifc mouseWidgetAction, int mUser){
1112    cfg.mouseWidgetAction = mouseWidgetAction;
1113    cfg.mMouseToActionChange = mUser;
1114  }
1115  
1116  
1117  
1118  
1119  /**Gets the action for change the widget. */
1120  //public GralUserAction getActionChange(){ return cfg.actionChanging; }
1121  
1122  
1123  /**Sets the action in application context which is invoked for applying user data to show in the widget.
1124   * <br><br>
1125   * The invocation of the action should be organized in the user context, maybe cyclically for all widgets
1126   * of visible windows  or if any data are received. 
1127   * <br><br>
1128   * In the action the user should read any data from its application
1129   * and invoke {@link #setValue(int, int, Object, Object)} after data preparation to display the value.
1130   * Because the {@link GralWidget} is given as parameter, the implementation can use the information
1131   * for example {@link #sDataPath} or {@link #sFormat}. The implementation of the action can be done
1132   * in the users context in a specialized form, or some standard actions can be used. 
1133   * See notes of {@link #getActionShow()}.
1134   * <br><br>
1135   * To get the action in a script context (GuiCfgBuilder) some actions can be registered 
1136   * using {@link org.vishia.gral.ifc.GralMngBuild_ifc#registerUserAction(String, GralUserAction)}. They are gotten by name
1137   * invoking {@link org.vishia.gral.ifc.GralMngBuild_ifc#getRegisteredUserAction(String)} 
1138   * in the {@link org.vishia.gral.cfg.GralCfgBuilder}.
1139   * 
1140   * @param action The action instance.
1141   * @param param maybe param for the show method.
1142   */
1143  public void setActionShow(GralUserAction action, String[] param){ cfg.actionShow = action; cfg.sShowParam = param; }
1144  
1145  /**Gets the action to show the widget. This method is helpfully to invoke showing after receiving data
1146   * in the users context. Invoke {@link GralUserAction#userActionGui(String, GralWidget, Object...)}
1147   * with this WidgetDescriptor and additional user data. The implementation of that method
1148   * may be done in the users context but in another module or the implementation may be given in any 
1149   * library superordinated to this graphic adapter library but subordinated in respect to the explicit application.
1150   * The usage of a show method given in the implementation of {@link GralUserAction} helps to separate
1151   * the invocation of showing and the decision what and how is to show.
1152   */
1153  public GralUserAction getActionShow(){ return cfg.actionShow; }
1154  
1155  public void setActionFocused(GralUserAction action){ cfg.actionFocused = action; }
1156
1157  public GralUserAction getActionFocused(){ return cfg.actionFocused; }
1158  
1159  
1160  public String getsToolTip()
1161  {
1162    return sToolTip;
1163  }
1164
1165
1166  public void setToolTip(String sToolTip)
1167  {
1168    this.sToolTip = sToolTip;
1169  }
1170
1171  
1172  /**Sets the action to receive a drop event and initializes the drop feature of the widget.
1173   * For drag file the 'drag get action' method will be offered in the params[0] a String[][] reference. 
1174   * This String reference array has to be filled with the absolute path of the file using String[0][0]. 
1175   * After that callback invocation a drag file object will be created therewith internally.
1176   *  
1177   * @param action The drag file get action.
1178   * @param dropType one of {@link org.vishia.util.KeyCode#dropFiles} or ..dropText
1179   */
1180  public void setDragEnable(GralUserAction action, int dragType)
1181  {
1182    cfg.actionDrag = action;
1183    if(_wdgImpl !=null) _wdgImpl.setDragEnable(dragType);  // call implementation specific drop handling. 
1184  }
1185
1186  public GralUserAction getActionDrag(){ return cfg.actionDrag; }
1187  
1188  
1189  /**Sets the action to receive a drop event and initializes the drop feature of the widget.
1190   * @param action The action will be called
1191   * @param dropType one of {@link org.vishia.util.KeyCode#dropFiles} or ..dropText
1192   */
1193  public void setDropEnable(GralUserAction action, int dropType)
1194  {
1195    cfg.actionDrop = action;
1196    if(_wdgImpl !=null) _wdgImpl.setDropEnable(dropType);  // call implementation specific drop handling. 
1197  }
1198
1199  public GralUserAction getActionDrop(){ return cfg.actionDrop; }
1200  
1201  
1202  public String getShowMethod()
1203  {
1204    return cfg.sShowMethod;
1205  }
1206
1207  
1208  public int getDataIx(){ return dataIx; }
1209
1210  public void setDataIx(int dataIx){ this.dataIx = dataIx; }
1211
1212  
1213  /**Returns the parameter of the show method.
1214   * The parameters for the show-method are given as "showMethod(param, param, ...)"
1215   * while calling {@link #setActionShow(GralUserAction, String[])}. They are split in extra Strings,
1216   * this  
1217   * @return
1218   */
1219  public String[] getShowParam(){ return cfg.sShowParam; }
1220  
1221  /**Clear the parameter if they are over-taken already.
1222  */
1223  public void clearShowParam(){ cfg.sShowParam = null; }
1224
1225
1226  public String getFormat()
1227  {
1228    return sFormat;
1229  }
1230
1231
1232  public void setFormat(String sFormat)
1233  {
1234    this.sFormat = sFormat;
1235  }
1236
1237  
1238  /**Gets the context menu to add a menu item. If this widget hasn't a gral context menu, then 
1239   * the context menu is created by calling {@link GralMng#addContextMenu(GralWidget)}.
1240   * If the widget has a context menu already, it is stored in the reference {@link #contextMenu}.
1241   * @return the context menu root for this widget.
1242   */
1243  public GralMenu getContextMenu(){
1244    if(contextMenu == null){
1245      contextMenu = itsMng.createContextMenu(this);   //delegation, the widget mng knows the implementation platform.
1246    }
1247    return contextMenu;
1248  }
1249  
1250  
1251  public void setHtmlHelp(String url){ htmlHelp = url; }
1252  
1253  public String getHtmlHelp(){ return htmlHelp; }
1254  
1255  
1256  
1257  
1258  /**Sets the GralMng.
1259   * @deprecated it should be set by the MethodsCalledbackFromImplementation ctor. 
1260   */
1261  @Deprecated
1262  public void setPanelMng(GralMng mng)
1263  { this.itsMng = mng; 
1264    if(this._wdgPos !=null) 
1265      throw new IllegalStateException("GralWidget - setPos() is set already.");
1266    this._wdgPos = mng.getPosCheckNext();
1267    this.registerWidget();  //always clone it from the central pos 
1268
1269  }
1270  
1271  
1272  
1273  /**Gets the info to access the values for this widget in the users context.
1274   * If this method is called the first time for the widget after start the application, the access info
1275   * is searched in the container calling {@link VariableContainer_ifc#getVariable(String, int[])}
1276   * with the stored textual info {@link #setDataPath(String)} and {@link #setDataIx(int)}.
1277   * This operation may need a little bit of calculation time, which were to expensive if a lot of widgets
1278   * should be provided with user values. Therefore the returned {@link VariableAccess_ifc} instance is stored
1279   * in the {@link #oContentInfo} of the widget and returned on the further calls.
1280   * <br>
1281   * The returned {@link VariableAccess_ifc} should be allow the fast access to users values.
1282   *  
1283   * @param container The container where all {@link VariableAccess_ifc} should be found.
1284   * @return The access to a user variable in the user's context, null if the data path is empty.
1285   */
1286  @Deprecated public VariableAccess_ifc getVariableFromContentInfo(VariableContainer_ifc container)
1287  {
1288    //DBbyteMap.Variable variable;
1289    VariableAccess_ifc variable;
1290    Object oContentInfo = this.getContentInfo();
1291    if(oContentInfo == null){
1292      //first usage:
1293      String sPath1 = this.getDataPath();
1294      if(sPath1 !=null && (sPath1 = sPath1.trim()).length()>0){
1295        String sPath = itsMng.getReplacerAlias().replaceDataPathPrefix(sPath1);
1296        variable = container.getVariable(sPath1);
1297        this.setContentInfo(variable);
1298      } else {
1299        variable = null;
1300      }
1301    } else if(oContentInfo instanceof VariableAccessWithIdx){
1302      variable = (VariableAccessWithIdx)oContentInfo;
1303    } else {
1304      variable = null;  //other info in widget, not a variable.
1305    }
1306    return variable; 
1307  }
1308  
1309
1310  
1311  public VariableAccess_ifc getVariable(VariableContainer_ifc container) {
1312    
1313    if(variable ==null && variables == null && sDataPath !=null && !sDataPath.startsWith("#")){ //no variable known, get it.
1314      if(sDataPath.contains(",")){
1315        String[] sDataPaths = sDataPath.split(",");
1316        variables = new LinkedList<VariableAccess_ifc>();
1317        for(String sPath1: sDataPaths){
1318          if(sPath1.contains("["))
1319            stop();
1320          String sPath2 = sPath1.trim();
1321          String sPath = itsMng.getReplacerAlias().replaceDataPathPrefix(sPath2);
1322          VariableAccess_ifc variable1 = container.getVariable(sPath);
1323          if(variable1 !=null){
1324            variables.add(variable1);
1325          }
1326        }
1327      } else {
1328        if(sDataPath.contains("["))
1329          stop();
1330        String sPath2 = sDataPath.trim();
1331        String sPath = itsMng.getReplacerAlias().replaceDataPathPrefix(sPath2);
1332        variable = container.getVariable(sPath);
1333      }
1334    }
1335    if(variable !=null) return variable;
1336    if(variables !=null && variables.size() >0) return variables.get(0);
1337    else return null;
1338  }
1339  
1340  
1341  @Override public void refreshFromVariable(VariableContainer_ifc container){
1342    refreshFromVariable(container, -1, null, null);
1343  }
1344
1345  
1346  
1347  
1348  
1349  
1350  /**Refreshes the graphical content with the content of the variables.
1351   * First time if a variables is not associated the variable is searched in the container
1352   * by the given {@link #setDataPath(String)}. The next times the variable is used independent of
1353   * the reference to the container and independent of the data path. If {@link #setDataPath(String)}
1354   * was called again, the variables are searched in the container newly.
1355   * <br><br>
1356   * If the data path contains ',' as separator, more as one variable is associated.
1357   * 
1358   * @param container contains variables able to search by string.
1359   */
1360  @Override public void refreshFromVariable(VariableContainer_ifc container
1361      , long timeLatest, GralColor colorRefreshed, GralColor colorOld
1362  ){    
1363    if(sDataPath !=null && sDataPath.startsWith("intern"))
1364      stop();
1365    if(this instanceof GralLed)
1366      stop();
1367    //
1368    if(dyda.bTouchedField) return; //do not modify if it is actually touching.
1369    //check and search the variable(s):
1370    //
1371    getVariable(container);
1372    //
1373    //
1374    //
1375    if(cfg.actionShow !=null){
1376      //The users method to influence how the widget is presented in view:
1377      if(!cfg.actionShow.exec(0, this, variable !=null ? variable : variables)){
1378        System.err.println("GralWidget fault actionShow in " + name + "; returns false; sShowMethod = " + cfg.sShowMethod);
1379      }
1380    } else {
1381      //standard behavior to show: call setValue or setText which may overridden by the widget type.
1382      if(variable !=null){
1383        if(sDataPath !=null && sDataPath.contains("#dEB:activeDamping.i1intg"))
1384          Assert.stop();
1385        if(colorRefreshed !=null && colorOld !=null){
1386          long timeVariable = variable.getLastRefreshTime();
1387          long timediff = timeVariable - timeLatest;
1388          boolean bOld = timeVariable == 0 || timediff < 0;
1389          if(bOld ){
1390            setBackColor(colorOld, 0);
1391          } else {
1392            setBackColor(colorRefreshed, 0);
1393          }
1394        }
1395        char cType = variable.getType();
1396        String sValue = null;
1397        switch(cType){
1398          case 'Z': case 'S': case 'B':
1399          case 'I': setLongValue(variable.getInt()); break;
1400          case 'L': setLongValue(variable.getLong()); break;
1401          case 'F': setValue(variable.getFloat()); break;
1402          case 'D': 
1403            Object[] value = new Double[1]; 
1404            value[0] = new Double(variable.getDouble()); 
1405            setValue(value);
1406            break;
1407          case 's': setText(variable.getString()); break;
1408          default:  sValue = "?" + cType; //variable.getInt());  //at least request newly if type is faulty
1409          }
1410          if(sValue !=null){ //if the value is given as sValue-string - if null it may be set already
1411            //if(bOld){ setText("? " + sValue); }
1412            //else 
1413            { setText(sValue); }
1414          }
1415      } else if(variables !=null){
1416        if(variables.size() == 0){ variables = null; }
1417        else {
1418          Object[] values = new Object[variables.size()];
1419          int ixVal = -1;
1420          for(VariableAccess_ifc variable1: variables){
1421            char cType = variable1.getType();
1422            switch(cType){
1423              case 'Z': case 'S': case 'B':
1424                case 'I': values[++ixVal] = variable1.getInt(); break;
1425              case 'L': setValue(variable.getFloat()); break;
1426              case 'F': values[++ixVal] = variable1.getFloat(); break;
1427              case 's': values[++ixVal] = variable1.getString(); break;
1428              default:  setText("?" + cType); //variable.getInt());  //at least request newly
1429            } //switch
1430            
1431          }
1432          setValue(values);
1433        }
1434      } else if(sDataPath !=null){
1435        setText("?? " + sDataPath); //called on fault variable path.
1436        setBackColor(colorOld, 0);
1437      }
1438    }
1439    
1440  }
1441  
1442  
1443  
1444  /**Requests new values for all variables which are associated to this widget. This method is usefull
1445   * if the variables are filled by a communication with any remote device and that filling
1446   * should be requested for the current visible variables.
1447   */
1448  public void requestNewValueForVariable(long timeRequested){
1449    if(variable !=null){ variable.requestValue(timeRequested); }
1450    else if(variables !=null){
1451      for(VariableAccess_ifc variable1: variables){
1452        variable1.requestValue(timeRequested);
1453      }
1454    }
1455  }
1456  
1457  
1458  
1459  /**Gets the current value of the content of the widget in the given context.
1460   * @param mng The context.
1461   * @return The value in String representation, null if the widget has no possibility of input.
1462   */
1463  public String getValue()
1464  { return itsMng.getValueFromWidget(this);
1465  }
1466  
1467  
1468  
1469  @Override public boolean isVisible(){
1470    return bVisibleState;
1471  }
1472
1473  
1474  @Override public boolean isInFocus(){
1475    return bHasFocus;
1476  }
1477
1478
1479  @Override public boolean isGraphicDisposed(){
1480    return lastTimeSetVisible !=0 && _wdgImpl ==null;
1481  }
1482
1483
1484
1485  
1486  /**Sets the widget visible or not. It is the default implementation for all simple widgets:
1487   * Sets {@link ImplAccess#chgVisible} or {@link ImplAccess#chgInvisible} in {@link DynamicData#setChanged(int)}
1488   * and invokes {@link #repaint()} with the {@link #repaintDelay} and {@link #repaintDelayMax}
1489   * @param visible
1490   * @return the old state.
1491   */
1492  @Override public boolean setVisible(boolean visible){
1493    if(this instanceof GralTable)
1494      System.out.println("GralTable set " + (visible? "visible: " : "invisible: ") + this.name);
1495    if(this instanceof GralWindow)
1496      Debugutil.stop();
1497    if(_wdgImpl == null) {
1498      bVisibleState = true;  //without graphic yet now
1499    } else {
1500      if(itsMng.currThreadIsGraphic()) {
1501        _wdgImpl.setVisibleGThread(visible);   //sets the implementation widget visible.
1502      } else {
1503        dyda.setChanged(visible ? ImplAccess.chgVisible : ImplAccess.chgInvisible);
1504        repaint();
1505      }
1506    }
1507    return bVisibleState;
1508  }
1509  
1510
1511  
1512  
1513  //@Override 
1514  public GralRectangle XXXgetPixelPositionSize(){
1515    if(_wdgImpl !=null) return _wdgImpl.getPixelPositionSize();
1516    else throw new IllegalArgumentException("GralWidget - does not know its implementation widget; ");
1517  }
1518  
1519  
1520  @Override public boolean isChanged(boolean setUnchanged){ 
1521    boolean bChanged = dyda.bTextChanged;
1522    if(setUnchanged){ 
1523      dyda.bTextChanged = false; 
1524    }
1525    return bChanged; 
1526  }
1527  
1528
1529  
1530  /**Sets the current value of the content of the widget in the given context.
1531   * @param cmd see {@link GralMng_ifc#cmdSet} etc. It is possible to set the color etc.
1532   * @param ident Any number to specify set, maybe 0
1533   * @param value The value in the necessary representation.
1534   */
1535  public void setValue(int cmd, int ident, Object visibleInfo)
1536  { dyda.visibleInfo = visibleInfo;
1537    dyda.setChanged(ImplAccess.chgVisibleInfo);
1538    repaint(repaintDelay, repaintDelayMax);
1539    //itsMng.setInfo(this, cmd, ident, visibleInfo, null);
1540  }
1541  
1542  
1543  @Override public void setBackColor(GralColor color, int ix){ 
1544    if(dyda.backColor == null || color.notUsed() || !dyda.backColor.equals(color)){
1545      dyda.backColor = color; 
1546      dyda.setChanged(ImplAccess.chgColorBack); 
1547      repaint(repaintDelay, repaintDelayMax);
1548    }
1549  }
1550  
1551  @Override public GralColor getBackColor(int ix){ 
1552    return dyda.backColor; 
1553  }
1554  
1555  @Override public void setLineColor(GralColor color, int ix){ 
1556    if(dyda.lineColor == null || !dyda.lineColor.equals(color)){
1557      dyda.lineColor = color; 
1558      dyda.setChanged(ImplAccess.chgColorLine); 
1559      repaint(repaintDelay, repaintDelayMax);
1560    }
1561  }
1562  
1563  @Override public void setTextColor(GralColor color){ 
1564    if(dyda.textColor == null || !dyda.textColor.equals(color)){
1565      dyda.textColor = color; 
1566      dyda.setChanged(ImplAccess.chgColorText); 
1567      repaint(repaintDelay, repaintDelayMax);
1568    }
1569  }
1570  
1571  
1572  
1573  /**Sets the current value of the content of the widget in the given context.
1574   * @param cmd see {@link GralMng_ifc#cmdSet} etc. It is possible to set the color etc.
1575   * @param ident Any number to specify set, maybe 0
1576   * @param value The value in the necessary representation.
1577   */
1578  public void setValue(int cmd, int ident, Object visibleInfo, Object userData)
1579  { dyda.visibleInfo = visibleInfo;
1580    dyda.userData = userData;
1581    repaint(repaintDelay, repaintDelayMax);
1582    //itsMng.setInfo(this, cmd, ident, visibleInfo, userData);
1583  }
1584  
1585  /**Sets a value to show.
1586   * @param value
1587   * This routine may be overridden by some specialized widgets.
1588   */
1589  @Override public void setValue(float value){
1590    dyda.fValue = value;
1591    repaint(repaintDelay, repaintDelayMax);
1592    //itsMng.setInfo(this, GralMng_ifc.cmdSet, 0, value, null);
1593  }
1594  
1595  
1596  /**Sets a value to show.
1597   * @param value
1598   * This routine may be overridden by some specialized widgets.
1599   */
1600  @Override public void setLongValue(long value){
1601    dyda.fValue = value; //may be shorten in acceleration
1602    dyda.lValue = value;
1603    repaint(repaintDelay, repaintDelayMax);
1604    //itsMng.setInfo(this, GralMng_ifc.cmdSet, 0, value, null);
1605  }
1606  
1607  
1608  
1609  /**Gets the float attribute value of this widget. Returns 0.0 if a float value is never used.
1610   */
1611  public float getFloatValue(){ return dyda.fValue; }
1612  
1613  
1614  /**Gets the float attribute value of this widget. Returns 0.0 if a float value is never used.
1615   */
1616  public float getLongValue(){ return dyda.lValue; }
1617  
1618  
1619  /**Sets some value to show any content.
1620   * @param value
1621   * This routine may be overridden by some specialized widgets.
1622   */
1623  @Override public void setValue(Object[] value){
1624    dyda.oValues = value;
1625    repaint(repaintDelay, repaintDelayMax);
1626    //itsMng.setInfo(this, GralMng_ifc.cmdSet, 0, value, null);
1627  }
1628  
1629  
1630  
1631  @Override public void setText(CharSequence text){
1632    dyda.displayedText = text.toString(); 
1633    dyda.setChanged(ImplAccess.chgText);
1634    repaint(repaintDelay, repaintDelayMax);
1635    //System.err.println(Assert.stackInfo("GralWidget - non overridden setText called; Widget = " + name + "; text=" + text, 5));
1636  }
1637  
1638  /**Get the text of this widget. It can be invoked in any thread. 
1639   * If it is a edit able text field, it returns the current text after focus lost 
1640   * or pressing any control key.
1641   * @return The current text.
1642   */
1643  public String getText(){ return dyda.displayedText == null? "" : dyda.displayedText; }
1644  
1645  
1646  /**Sets the border of the value range for showing. 
1647   * If it is a ValueBar, for exmaple, it is the value for 0% and 100%
1648   * This routine is empty per default, should be overridden if it is necessary.
1649   * @param minValue
1650   * @param maxValue
1651   */
1652  @Override public void setMinMax(float minValue, float maxValue){
1653    dyda.minValue = minValue;
1654    dyda.maxValue = maxValue;
1655    repaint(repaintDelay, repaintDelayMax);
1656    //
1657  }
1658
1659  
1660  @Override public long setContentIdent(long date){ long last = dateUser; dateUser = date; return last; }
1661  
1662  @Override public long getContentIdent(){ return dateUser; }
1663
1664  
1665  
1666  
1667  public void setCfgElement(GralWidgetCfg_ifc cfge)
1668  { this.itsCfgElement = cfge;
1669  }
1670  
1671  
1672  public GralWidgetCfg_ifc getCfgElement()
1673  { return itsCfgElement;
1674  }
1675  
1676  
1677  /**Standard implementation. Override only if necessary for sepcial handling.
1678   * @see org.vishia.gral.ifc.GralWidget_ifc#setFocus()
1679   */
1680  public void setFocus(){ setFocus(0,0); }
1681
1682  
1683  
1684  /**Sets the focus to this widget. This method is possible to call in any thread.
1685   * If it is called in the graphic thread and the delay = 0, then it is executed immediately.
1686   * Elsewhere the request is stored in the graphic thread execution queue and invoked later.
1687   * If the widget is inside a tab of a tabbed panel, the tab is designated as currently therewith.
1688   * That is done in the calling thread because it is a thread safe operation.
1689   * 
1690   * @param delay Delay in ms for invoking the focus request 
1691   * @param latest 
1692   */
1693  public void setFocus(int delay, int latest){
1694    if(delay >0 || !itsMng.currThreadIsGraphic() || _wdgImpl == null) {
1695      dyda.setChanged(ImplAccess.chgFocus | ImplAccess.chgVisible);
1696      repaint(delay, latest);
1697    } else {
1698      //action in the graphic thread.
1699      if(!bHasFocus) {
1700        GralWidget child = this;
1701        if(! (child instanceof GralWindow)) {
1702          GralPanelContent parent = _wdgPos.panel;
1703          int catastrophicalCount = 100;
1704          //set the visible state and the focus of the parents.
1705          while(parent !=null && parent.pos() !=null  //a panel is knwon, it has a parent inside its pos() 
1706              && !parent.bHasFocus
1707              && parent._wdgImpl !=null
1708              && --catastrophicalCount >=0){
1709            parent._wdgImpl.setFocusGThread();
1710            parent.setVisibleStateWidget(true);
1711            if(parent instanceof GralTabbedPanel) {
1712              //TabbedPanel: The tab where the widget is member of have to be set as active one.
1713              GralTabbedPanel panelTabbed = (GralTabbedPanel)parent;
1714              assert(child instanceof GralPanelContent);
1715              panelTabbed.selectTab(child.name);
1716              //String name = panel1.getName();
1717              //panelTabbed.selectTab(name);  //why with name, use GralPanel inside GralTabbedPanel immediately!
1718            }
1719            if(parent instanceof GralWindow) {       //This is not the window itself
1720              parent = null;
1721            } else {
1722              child = parent;
1723              parent = parent.pos().panel; //
1724            }
1725          }
1726        }
1727        _wdgImpl.setFocusGThread();  //sets the focus to the
1728        bVisibleState = true;
1729      } 
1730      GralWidget parent = this;
1731      GralWidget child;
1732      GralPanelContent panel;
1733      while(parent instanceof GralPanelContent
1734        && (child = (panel = (GralPanelContent)parent).primaryWidget) !=null
1735        && child._wdgImpl !=null
1736        && !child.bHasFocus
1737        ) {
1738        child.setFocus();
1739        child._wdgImpl.setFocusGThread();
1740        child.bVisibleState = true;
1741        child._wdgImpl.repaintGthread();
1742        List<GralWidget> listWidg = panel.getWidgetList();
1743        
1744        if(!(panel instanceof GralTabbedPanel)) { //don't show all childs of all tabs!
1745          for(GralWidget widgChild : listWidg) {
1746            widgChild._wdgImpl.setVisibleGThread(true);
1747            widgChild.bVisibleState = true;
1748          }
1749        }
1750        parent = child;  //loop if more as one GralPanelContent
1751      }
1752    }
1753  }
1754  
1755  
1756  
1757  
1758  /**Gets the working interface of the manager. 
1759   * It can be used to set and get values from other widgets symbolic identified by its name.
1760   * Note: It is possible too to store the {@link GralWidget} of specific widgets
1761   * to get and set values and properties of this widgets non-symbolic.
1762   * @return The manager.
1763   */
1764  @Override public GralMng gralMng(){ return itsMng; }
1765  
1766  
1767  /**Gets the panel where the widget is member of. 
1768   * @return The panel.
1769   */
1770  public GralPanelContent getItsPanel(){ return _wdgPos.panel; }
1771  
1772  
1773  /* (non-Javadoc)
1774   * @see org.vishia.gral.ifc.GralWidget_ifc#repaint()
1775   */
1776  @Override public void repaint(){ 
1777    //without arguments: latest with repaintDelayMax.
1778    repaint(this.repaintDelay, this.repaintDelayMax);
1779    /*chg 2015-06-25 it is twice and not complete. An order was delayed in the future always.
1780    if(itsMng !=null){ //NOTE: set of changes is possible before setToPanel was called. 
1781      if(itsMng.currThreadIsGraphic()){
1782        repaintGthread();     //do it immediately if no thread switch is necessary.
1783      } else {
1784        repaintRequ.activateAt(System.currentTimeMillis() + repaintDelay);  //TODO repaintDelayMax
1785      }
1786    }
1787    */
1788  }
1789  
1790  
1791  /**The Implementation of repaint calls {@link #repaintGthread()} if it is the graphic thread and the delay is 0.
1792   * Elsewhere the {@link #repaintRequ} is added as request to the graphic thread. 
1793   * @see org.vishia.gral.ifc.GralWidget_ifc#repaint(int, int)
1794   */
1795  @Override public void repaint(int delay, int latest){
1796    if(itsMng !=null){ //NOTE: set of changes is possible before setToPanel was called. 
1797      if(delay == 0 && itsMng.currThreadIsGraphic() && _wdgImpl !=null){
1798        _wdgImpl.repaintGthread();
1799      } else {
1800        long time = System.currentTimeMillis();
1801        repaintRequ.activateAt(time + delay, time + latest);
1802      }
1803    }
1804  }
1805  
1806  
1807  
1808  /**Removes the widget from the lists in its panel and from the graphical representation.
1809   * It calls the protected {@link #removeWidgetImplementation()} which is implemented in the adaption.
1810   */
1811  @Override public boolean remove()
1812  {
1813    if(_wdgImpl !=null) _wdgImpl.removeWidgetImplementation();
1814    if(_wdgPos.panel !=null) {
1815      _wdgPos.panel.removeWidget(this);
1816    }
1817    itsMng.deregisterWidgetName(this);
1818    return true;
1819  }
1820  
1821  
1822  
1823  /**Especially for test and debug, short info about widget.
1824   * @see java.lang.Object#toString()
1825   */
1826  @Override public String toString()
1827  { StringBuilder u = new StringBuilder(240);
1828    u.append(whatIs).append(":").append(name).append(": ").append(sDataPath);
1829    if(_wdgPos !=null && _wdgPos.panel !=null){
1830      u.append(" @").append(_wdgPos.panel.name);
1831    } else {
1832      u.append(" @?");
1833    }
1834    if(variable !=null){
1835      String vString = variable.toString();
1836      u.append(" var=").append(vString);
1837    }
1838    //u.append('\n');
1839    return u.toString();
1840  }
1841
1842  
1843  /**Methods which should be called back by events of the implementation layer.
1844   * This class is used only for the implementation level of the graphic. It is not intent to use
1845   * by any application. It is public because the implementation level should accesses it.
1846   */
1847  public abstract static class ImplAccess implements GralWidgImpl_ifc {
1848    
1849    /**What is changed in the dynamic data, see {@link GralWidget.DynamicData#whatIsChanged}. */  
1850    public static final int chgText = 1, chgColorBack=2, chgColorText=4, chgFont = 8, chgColorLine = 0x10;
1851    
1852    public static final int chgEditable = 0x20;
1853    
1854    public static final int chgVisibleInfo = 0x10000, chgObjects = 0x20000, chgFloat = 0x40000, chgIntg = 0x80000;
1855    
1856    public static final int chgFocus = 0x10000000; 
1857    
1858    public static final int chgPos = 0x20000000, chgVisible = 0x40000000, chgInvisible = 0x80000000;
1859    
1860    /**This is only documentation. These bits are used specialized in derived classes.*/
1861    public static final int chgBitsDerived = 0x0ff0ff00;
1862
1863    public final GralWidget widgg;
1864    
1865    
1866    /**Aggregation to the widget implementation which resolves the required implementation methods. */
1867    protected GralWidgetImpl_ifc wdgimpl;
1868    
1869    /**Bounds of the implementation widget in its container. null if not used. */
1870    public GralRectangle pixBounds;
1871    
1872    @Deprecated protected ImplAccess(GralWidget widgg, GralMng mng){
1873      this(widgg);
1874    }
1875    
1876    
1877    /**Constructs the base of the graphic implemantion widget wrapper (SWT, AWT).
1878     * Stores the reference to the GralWidget in this.{@link #widgg}
1879     * Stores the reference to the graphic implementation widget in {@link GralWidget#_wdgImpl}
1880     * Initializes the pos() from the given {@link GralMng#pos} if it is not given by construction. 
1881     * @param widgg The associated derived class of GralWidget.
1882     */
1883    protected ImplAccess(GralWidget widgg){
1884      this.widgg = widgg;
1885      widgg._wdgImpl = this; 
1886
1887      if(widgg._wdgPos ==null) {
1888        widgg._wdgPos = widgg.itsMng.getPosCheckNext();
1889        widgg.registerWidget(); //yet now because before the panel was unknown
1890      }
1891      widgg.lastTimeSetVisible = System.currentTimeMillis();
1892    }
1893    
1894    
1895    
1896    
1897    /**This method is not intent to call by user. It may be called from all widget implementation 
1898     * if the focus of the widget is gained. Use {@link #setFocus()} to set a widget in the focus.
1899     * 
1900     * It sets the html help for the widget and notifies the widgets in focus for the GralWidgetMng. 
1901     * Don't override this method in the graphic implementation!
1902     * It should be overridden only in a Gral widget inheritance only if necessary.
1903     */
1904    public void XXXfocusGained(){
1905      //System.out.println(Assert.stackInfo("GralWidget - Debuginfo; focusgained", 1, 10));
1906      if(widgg.htmlHelp !=null){
1907        widgg.itsMng.setHtmlHelp(widgg.htmlHelp);
1908      }
1909      if(widgg.cfg.actionFocused !=null){ widgg.cfg.actionFocused.exec(KeyCode.focusGained, widgg); }
1910      //notify GralWidgetMng about focused widget.
1911      widgg.itsMng.notifyFocus(widgg);
1912    }
1913    
1914    /**Sets the state of the widget whether it seams to be visible.
1915     * This method should not be invoked by the application. It is 
1916     * @param visible
1917     */
1918    public void setVisibleState(boolean visible){
1919      widgg.setVisibleState(visible);
1920    }
1921
1922    /**Access method to GralWidget's method. */
1923    protected GralUserAction actionShow(){ return widgg.cfg.actionShow; }
1924    
1925    /**Access method to GralWidget's method. */
1926    //protected GralUserAction actionChanging(){ return widgg.cfg.actionChanging; }
1927    
1928    
1929    /**Access method to {@link GralWidget#dyda}. */
1930    protected GralWidget.DynamicData dyda(){ return widgg.dyda; }
1931    
1932    //public void setWidgetImpl(GralWidgImpl_ifc widg, GralMng mng){ widgg.wdgImpl = widg; widgg.itsMng = mng; }
1933
1934    /**Notify that the text is changed in {@link GralWidget.DynamicData#bTextChanged} */
1935    protected void setTextChanged(){ widgg.dyda.bTextChanged = true; }
1936    
1937    /**Invoked on touching a widget. */
1938    //protected void setTouched(){ widgg.dyda.bTouchedField = true; }
1939    
1940    
1941    /**Implementation routine to set receiving a drag event and initializes the drag feature of the widget.
1942     * A overridden routine should be implemented for the implementation graphic layer widget.
1943     * This routine is invoked when it isn't overridden, it throws an exception because the drag feature
1944     * isn't supported for the implementation.
1945     * @param dragType one of {@link org.vishia.util.KeyCode#dragFiles} or ..dragText
1946     */
1947    protected void setDragEnable(int dragType)
1948    { //default implementation: causes an exception. The type must override it.
1949      throw new IllegalArgumentException("drag not supported for this widget type");
1950    }
1951    
1952    /**Implementation routine to set receiving a drop event and initializes the drop feature of the widget.
1953     * @param dropType one of {@link org.vishia.util.KeyCode#dropFiles} or ..dropText
1954     */
1955    protected void setDropEnable(int dropType)
1956    { //default implementation: causes an exception. The type must override it.
1957      throw new IllegalArgumentException("drop not supported for this widget type");
1958    }
1959    
1960
1961    
1962    /**Gets the bits what is changed in the widget's data. The bits are all definitions
1963     * starting with chg in this class. {@link #chgText} etc.
1964     * @return
1965     */
1966    public int getChanged(){ return widgg.dyda.whatIsChanged.get(); }
1967    
1968    public void acknChanged(int mask){ widgg.dyda.acknChanged(mask); }
1969    
1970    
1971    protected ActionChange getActionChange(ActionChangeWhen when){ return widgg.getActionChange(when); }
1972    
1973    public static GralWidget gralWidgetFromImplData(Object data){
1974      if(data instanceof GralWidget) return (GralWidget)data;
1975      else if(data instanceof GralWidget.ImplAccess) {
1976        return ((GralWidget.ImplAccess)data).widgg;
1977      } else return null;
1978    }
1979    
1980    
1981    /**This routine does not change the focus state in the implementation widget,
1982     * it denotes only that the GralWidget has the focus or not.
1983     * The method is static because it gets the widgg instance. 
1984     * Note that it is not member of GralWidget itself because the application 
1985     * should not invoke it (which may be possible on a public GralWidget-method).
1986     * @param widgg the GralWidget instance
1987     * @param focus true on focus gained, false on focus lost.
1988     */
1989    public static void setFocused(GralWidget widgg, boolean focus){
1990      widgg.bHasFocus = focus;
1991      if(focus == false) { widgg.dyda.bTouchedField = false; }
1992    }
1993  }
1994  
1995  /**Not intent to get from user: The instance which's methods can be called from an event method of the implementation of the GralWidget. 
1996   * Note: This Method is public only because the implementation in another package need to use it.
1997   * It should not be used by any application. */
1998  //public MethodsCalledbackFromImplementation implMethodWidget_ = new MethodsCalledbackFromImplementation();
1999  
2000  
2001  /**Returns the instance which extends the {@link ImplAccess} of this widget.
2002   * @return null if the widget has not an implementation yet.
2003   */
2004  public ImplAccess getImpl(){ return _wdgImpl; }
2005  
2006  
2007  /**This time order calls the {@link #repaintGthread()} in the graphical thread.
2008   * It is used with delay and wind up whenever {@link #repaint(int, int)} with an delay is called.
2009   * If its executeOrder() runs, it is dequeued from timer queue in the {@link GralGraphicThread} 
2010   * till the next request of {@link #repaint(int, int)} or {@link #repaint()}.
2011   */
2012  private final GralGraphicTimeOrder repaintRequ = new GralGraphicTimeOrder("GralWidget.repaintRequ"){
2013    @Override public void executeOrder() {
2014      if(_wdgImpl !=null) { _wdgImpl.repaintGthread(); }//Note: exception thrown in GralGraphicThread
2015    }
2016    @Override public String toString(){ return name + ":" + GralWidget.this.name; }
2017  };
2018  
2019  
2020  /**Sets the state of the widget whether it seams to be visible.
2021   * This method should not be invoked by the application. It is 
2022   * @param visible
2023   */
2024  final public void setVisibleStateWidget(boolean visible){
2025    bVisibleState = visible;
2026    String name = _wdgPos.panel == null ? "main window" : _wdgPos.panel.name;
2027    System.out.println((visible? "GralWidget set visible: " : "GralWidget set invisible: @") + name + ":" + toString());
2028    lastTimeSetVisible = System.currentTimeMillis();
2029  }
2030
2031
2032  public void setVisibleState(boolean visible){
2033    setVisibleStateWidget(visible);
2034  }
2035
2036
2037  void stop(){
2038    
2039  }
2040
2041
2042  @Override @Deprecated
2043  public GralColor setBackgroundColor(GralColor color)
2044  { 
2045    // TODO Auto-generated method stub
2046    return null;
2047  }
2048
2049
2050  @Override
2051  public void setBoundsPixel(int x, int y, int dx, int dy)
2052  { if(_wdgImpl !=null) _wdgImpl.setBoundsPixel(x, y, dx, dy);
2053  }
2054
2055
2056  @Override
2057  public GralColor setForegroundColor(GralColor color)
2058  { // TODO Auto-generated method stub
2059    return null;
2060  }
2061
2062
2063  //@Override
2064  public Object XXXgetWidgetImplementation()
2065  { if(_wdgImpl !=null) return _wdgImpl.getWidgetImplementation();
2066    else return null;
2067  }
2068
2069
2070  //@Override
2071  public void XXXremoveWidgetImplementation()
2072  { if(_wdgImpl !=null) _wdgImpl.removeWidgetImplementation();
2073  }
2074
2075
2076  //@Override
2077  public void XXXrepaintGthread()
2078  {
2079    if(_wdgImpl !=null) _wdgImpl.repaintGthread();
2080  }
2081
2082
2083  //@Override
2084  public boolean XXXsetFocusGThread()
2085  { boolean ret;
2086    try{
2087      if(_wdgImpl !=null) {
2088        ret = _wdgImpl.setFocusGThread();
2089        bVisibleState = true;  //may be set via the _wdgImpl too, but set additional if not done in _wdgImpl.setFocusGThread()
2090      }
2091      else ret = false;
2092    } catch(Exception exc){
2093      System.err.println("GralWidget - setFocusGThread fails");
2094      ret = false;
2095    }
2096    return ret;
2097  }
2098  
2099  
2100  /**Sets the implementation widget visible or not.
2101   * @see org.vishia.gral.base.GralWidgImpl_ifc#setVisibleGThread(boolean)
2102   */
2103  //@Override 
2104  public void XXXsetVisibleGThread(boolean bVisible){ 
2105    try{
2106      if(_wdgImpl !=null){ 
2107        setVisibleState(bVisible);  
2108        _wdgImpl.setVisibleGThread(bVisible); 
2109      }
2110    } catch(Exception exc){
2111      System.err.println("GralWidget - setFocusGThread fails");
2112    }
2113  }
2114  
2115}
2116