001package org.vishia.gral.example;
002
003import java.io.IOException;
004
005import org.vishia.gral.awt.AwtFactory;
006import org.vishia.gral.base.GralButton;
007import org.vishia.gral.base.GralGraphicTimeOrder;
008import org.vishia.gral.base.GralPos;
009import org.vishia.gral.base.GralTextBox;
010import org.vishia.gral.base.GralTextField;
011import org.vishia.gral.base.GralWidget;
012import org.vishia.gral.base.GralMng;
013import org.vishia.gral.base.GralWindow;
014import org.vishia.gral.ifc.GralColor;
015import org.vishia.gral.ifc.GralFactory;
016import org.vishia.gral.ifc.GralUserAction;
017import org.vishia.gral.swt.SwtFactory;
018import org.vishia.msgDispatch.LogMessage;
019import org.vishia.msgDispatch.LogMessageStream;
020import org.vishia.util.KeyCode;
021
022/**This class contains a simple example with a switching button, an input text field and a output
023 * text field. When the button is pressed, the text of the input field will be read and an output will be written.
024 * @author Hartmut Schorrig
025 *
026 */
027public class ExampleSimpleButton
028{
029  
030  /**Version, history and license.
031   * <ul>
032   * <li>2011-06-00 Hartmut created
033   * </ul>
034   * 
035   * <b>Copyright/Copyleft</b>:<br>
036   * For this source the LGPL Lesser General Public License,
037   * published by the Free Software Foundation is valid.
038   * It means:
039   * <ol>
040   * <li> You can use this source without any restriction for any desired purpose.
041   * <li> You can redistribute copies of this source to everybody.
042   * <li> Every user of this source, also the user of redistribute copies
043   *    with or without payment, must accept this license for further using.
044   * <li> But the LPGL is not appropriate for a whole software product,
045   *    if this source is only a part of them. It means, the user
046   *    must publish this part of source,
047   *    but doesn't need to publish the whole source of the own product.
048   * <li> You can study and modify (improve) this source
049   *    for own using or for redistribution, but you have to license the
050   *    modified sources likewise under this LGPL Lesser General Public License.
051   *    You mustn't delete this Copyright/Copyleft inscription in this source file.
052   * </ol>
053   * If you intent to use this source without publishing its usage, you can get
054   * a second license subscribing a special contract with the author. 
055   * 
056   * @author Hartmut Schorrig = hartmut.schorrig@vishia.de
057   */
058  public static final int version = 20120303;
059
060  /**Instance of inner class contains the graphical elements.
061   * 
062   */
063  protected final GuiElements gui;
064  
065  /**Instance to initialize the graphic. */
066  private GralGraphicTimeOrder initGuiCode;
067  
068  ExampleSimpleButton(GralMng gralMng)
069  {
070    //this.initGuiCode = new InitGuiCode();
071    gui = new GuiElements(gralMng);
072    
073  }
074  
075  protected void setInitGuiCode(GralGraphicTimeOrder initGuiCode)
076  {
077    this.initGuiCode = initGuiCode;
078  }
079  
080  
081  /**Initializes the graphical user interface.
082   * 
083   */
084  void initGui()
085  {
086    //The code to initialize the GUI appearance should be run in the graphic thread.
087    //Therefore the code snippet which contains the functionality to set the graphic is applied to the graphic thread.
088    //It is defined in this application class locally.
089    gui.gralMng.gralDevice.addDispatchOrder(initGuiCode);
090    initGuiCode.awaitExecution(1, 0);  //waits for finishing
091    
092  }
093  
094  
095  /**Main execute method for any other actions than the graphical actions. 
096   * The application may do some things beside.
097   */
098  void execute()
099  {
100    //Now do nothing because all actions are done in the graphic thread.
101    //A more complex application can handle some actions in its main thread simultaneously and independent of the graphic thread.
102    //
103    while(gui.gralMng.gralDevice.isRunning()){
104      try{ Thread.sleep(100); } catch(InterruptedException exc){}
105    }
106    
107  }
108  
109  
110  
111  
112  
113  /**Code snippet for the action while the button is pressed. This snippet will be executed
114   * if the left mouse key is released on the button. If the left mouse is pressed and then
115   * the mouse cursor is removed from the button while it is pressed, the action is not executed.
116   * This is important if a touch screen is used and the accuracy of target seeking of the finger
117   * is not sufficient, the action can be aborted. If the mouse is pressed respectively the button 
118   * is sought, the button changes its appearance, it is marked. 
119   * That actions are done by the gral implementation independing of the implementation layer.
120   */
121  private final GralUserAction actionButtonCode = new GralUserAction()
122  { 
123    int ctKeyStroke = 0;
124    
125    @Override
126    public boolean userActionGui(int actionCode, GralWidget widgd, Object... params)
127    { if(KeyCode.isControlFunctionMouseUpOrMenu(actionCode)){
128        String textOfField = gui.widgInput.getText();
129        try{ gui.widgOutput.append("Button " + (++ctKeyStroke) + " time, text=" + textOfField + "\n");
130        } catch(IOException exc){}
131      }
132      return true;  
133    } 
134  };
135  
136  
137  
138  
139  protected static class GuiElements
140  {
141    final GralMng gralMng;
142
143    GralTextField widgInput;
144    
145    GralButton widgButton;
146    
147    GralTextBox widgOutput;
148  
149    /**Constructor with given widget manager.
150     * @param gralMng
151     */
152    GuiElements(GralMng gralMng)
153    {
154      this.gralMng = gralMng;
155    }
156  }
157  
158  
159  /**Code snippet for initializing the GUI. This snippet will be executed
160   * in the graphic thread. It is an anonymous inner class. 
161   */
162  protected class InitGuiCodeSimpleButton extends GralGraphicTimeOrder
163  {
164    InitGuiCodeSimpleButton(){
165      super("ExampleSimpleButton.initGuiCode");
166    }
167    
168    /**This routine is called in the graphic thread if it was added.
169     * @see org.vishia.gral.base.GralGraphicTimeOrder#executeOrder(boolean)
170     */
171    @Override public void executeOrder()
172    {
173      //we have only one panel. But if there are more as one, select which.
174      gui.gralMng.selectPanel("primaryWindow");
175      //
176      //Sets the positions in grid line and columns. line 5 to 8, column 2 to 15
177      gui.gralMng.setPosition(5, 8, 2, 15, 0, '.');
178      //Adds a text input field.
179      //NOTE: the element gui is arranged in the outer class because it may be accessed later.
180      gui.widgInput = gui.gralMng.addTextField("input", true, null, "t");
181      //Sets the position of the next widget, the button, relative to the last one, 5 lines deeper.
182      //Use size instead an line position. 
183      gui.gralMng.setPosition(GralPos.same+5, GralPos.size +3, 2, GralPos.size +10, 0, '.');
184      gui.widgButton = gui.gralMng.addButton("button", actionButtonCode, "test", null, "Hello");
185      //
186      //The button can be presented with colors. Use named colors 'Pastel GreeN' and 'Pastel YEllow'.
187      //The button is a switching button then. 
188      gui.widgButton.setSwitchMode(GralColor.getColor("pgn"), GralColor.getColor("pye"));
189      //
190      //Sets the position of the next widget, the textbox, relative to the last one, 5 lines deeper.
191      //Use size instead an line position. 
192      //The columns are dedicated with 0 (left) and 0 (from right). It means the full window width.
193      gui.gralMng.setPosition(-10, 0, 0, 0, 0, '.');
194      gui.widgOutput = gui.gralMng.addTextBox("outputText", true, null, '.');
195    }
196  };
197
198
199  
200  /**The main routine. It creates the factory of this class
201   * and then calls {@link #main(String[], Factory)}.
202   * With that pattern a derived class may have a simple main routine too.
203   * @param args command line arguments.
204   */
205  public static void main(String[] args)
206  {
207    main(args, new Factory());
208  
209  }  
210  
211  
212  
213  
214  /**Main routine with a factory class. That allows to use the same main routine for a derived class
215   * for further more complex examples.
216   * @param args command line arguments.
217   * @param factoryExample The factory to create the current class which should be derived from this.
218   */
219  protected static void main(String[] args, Factory factoryExample)
220  {
221    boolean bOk = true;
222    //
223    //choose a factory, recomment one of the following:
224    //
225    GralFactory graphicFactory = new AwtFactory();
226    //GralFactory_ifc graphicFactory = new FactorySwt();
227    //
228    //A logger is a final thing what is need. This logger writes to the console.
229    //A complexer application may write to a graphic output window.
230    LogMessage log = new LogMessageStream(System.out);
231    //
232    //create the window, use the factory.
233    GralWindow primaryWindow = graphicFactory.createWindow(log, "Example Simple Button", 'C', 50,50,400, 300);
234    //
235    //The widget manager is created with the primary window. Use it.
236    GralMng gralMng = primaryWindow.gralMng();
237    //
238    //An empty graphic window is present now. It is time to create this application class now. 
239    //In an complexer application the graphic window can contain an output window, so information
240    //while building the application class can be shown for the user. 
241    //
242    //The gralMng is the main access to the graphic. It is indpenendent of the graphical implementation layer.
243    ExampleSimpleButton mainData = factoryExample.create(gralMng);
244    //
245    //Now the appearance of the graphic should be initialized:
246    mainData.initGui();
247    //
248    //Now executes the application code which may be independent of the graphic execution.
249    mainData.execute();
250  }
251  
252  
253  
254 
255  /**This inner class creates this class with given parameter.
256   */
257  static class Factory{
258    ExampleSimpleButton create(GralMng gralMng){
259      ExampleSimpleButton obj = new ExampleSimpleButton(gralMng);
260      obj.setInitGuiCode(obj.new InitGuiCodeSimpleButton());
261      return obj;
262    }
263  }
264  
265  
266  
267}