    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