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}