001package org.vishia.gral.awt; 002 003import java.awt.Canvas; 004import java.awt.Component; 005import java.awt.Container; 006import java.awt.Graphics; 007import java.awt.Label; 008import java.awt.Rectangle; 009import java.awt.TextField; 010import java.awt.event.FocusListener; 011import java.awt.event.HierarchyBoundsListener; 012import java.awt.event.HierarchyEvent; 013import java.awt.event.KeyEvent; 014import java.awt.event.KeyListener; 015 016import org.vishia.gral.base.GralPos; 017import org.vishia.gral.base.GralTextField; 018import org.vishia.gral.base.GralWidget; 019import org.vishia.gral.ifc.GralRectangle; 020import org.vishia.gral.swt.SwtMng; 021import org.vishia.util.KeyCode; 022 023/**Implementation of the {@link GralTextField} in awt graphics. 024 * The original {@link java.awt.TextField} has a considerable border for a smart outfit. That is not proper for some applications 025 * which needs an slim and simple outfit without borders because the smart outfit properties are given outside of the textfield itself. 026 * Therefore the functionality of a text field is implemented with a simple canvas. All functions to edit the content with keyboard 027 * are implemented here in an independent way of the awt.TextField. The {@link #paint(Graphics)} shows the simple outfit in a special kind. 028 * 029 * @author Hartmut Schorrig 030 * 031 */ 032public class AwtTextField extends GralTextField.GraphicImplAccess 033{ 034 035 /**Version, history and license. 036 * <ul> 037 * <li>2015-10-30 Hartmut improved, own implementation with canvas 038 * <li>2011-10-31 Hartmut created. 039 * </ul> 040 * 041 * <b>Copyright/Copyleft</b>: 042 * For this source the LGPL Lesser General Public License, 043 * published by the Free Software Foundation is valid. 044 * It means: 045 * <ol> 046 * <li> You can use this source without any restriction for any desired purpose. 047 * <li> You can redistribute copies of this source to everybody. 048 * <li> Every user of this source, also the user of redistribute copies 049 * with or without payment, must accept this license for further using. 050 * <li> But the LPGL is not appropriate for a whole software product, 051 * if this source is only a part of them. It means, the user 052 * must publish this part of source, 053 * but don't need to publish the whole source of the own product. 054 * <li> You can study and modify (improve) this source 055 * for own using or for redistribution, but you have to license the 056 * modified sources likewise under this LGPL Lesser General Public License. 057 * You mustn't delete this Copyright/Copyleft inscription in this source file. 058 * </ol> 059 * If you are intent to use this sources without publishing its usage, you can get 060 * a second license subscribing a special contract with the author. 061 * 062 * @author Hartmut Schorrig = hartmut.schorrig@vishia.de 063 */ 064 public final static String sVersion = "2015-10-30"; 065 066 067 /**The AWT widget. A TextField is not used because a TextField has a border which is not proper in any case. 068 * Therefore the capability of text output and edit is implemented with an own algorithm. 069 */ 070 final TextCanvas widgetAwt; 071 072 /**A possible prompt for the text field or null. */ 073 /*packagePrivate*/ Label promptSwt; 074 075 /**It contains the association to the swt widget (Control) and the {@link SwtMng} 076 * and implements some methods of {@link GralWidgImpl_ifc} which are delegate from this. 077 */ 078 private final AwtWidgetHelper widgHelper; 079 080 StringBuilder editBuffer; 081 082 083 public AwtTextField(GralTextField widgg, AwtWidgetMng mng) 084 { widgg.super(widgg); //NOTE: superclass is a non static inner class of GralTextField. 085 if(widgg.isEditable()){ 086 editBuffer = new StringBuilder(20); 087 editBuffer.setLength(0); editBuffer.append(dyda().displayedText); 088 } 089 GralPos pos = widgg.pos(); 090 Container panelAwt = (Container)pos.panel.getWidgetImplementation(); 091 092 widgetAwt = new TextCanvas(); //TextField(); 093 widgetAwt.setData(widgg); 094 widgetAwt.addFocusListener(mng.focusListener); 095 widgetAwt.addMouseListener(mng.mouseStdAction); 096 widgetAwt.addKeyListener(keyListener); 097 //widgetAwt.set 098 //widgetAwt.addHierarchyBoundsListener(hierarchyBoundsListener); 099 mng.setPosAndSize_(posField, widgetAwt); 100 //widgetAwt.setForeground(mng.propertiesGuiAwt.colorAwt(GralColor.getColor("rd"))); 101 //widgetAwt.setBackground(mng.propertiesGuiAwt.colorAwt(GralColor.getColor("gn"))); 102 panelAwt.add(widgetAwt); 103 widgHelper = new AwtWidgetHelper(widgetAwt, mng); 104 } 105 106 @Override 107 public void removeWidgetImplementation() 108 { 109 // TODO Auto-generated method stub 110 111 } 112 113 //@Override public int getCursorPos(){ return widgetAwt.getCaretPosition(); } 114 115 116 @Override 117 public Object getWidgetImplementation() 118 { 119 return widgetAwt; 120 } 121 122 123 124 @Override public boolean setFocusGThread() 125 { return AwtWidgetHelper.setFocusOfTabSwt(widgetAwt); 126 } 127 128 /**Sets the implementation widget vible or not. 129 * @see org.vishia.gral.base.GralWidgImpl_ifc#setVisibleGThread(boolean) 130 */ 131 @Override public void setVisibleGThread(boolean bVisible){ super.setVisibleState(bVisible); widgHelper.setVisibleGThread(bVisible); } 132 133 134 public int setCursorPos(int pos){ 135 //int oldPos = widgetAwt.getCaretPosition(); 136 ///widgetAwt.setCaretPosition(pos); 137 return 0; //oldPos; 138 } 139 140 141 142 143 144 145 @Override 146 public void setBoundsPixel(int x, int y, int dx, int dy){ widgHelper.setBoundsPixel(x, y, dx, dy); } 147 148 149 150 151 152 public void setEditable(boolean editable){ 153 //widgetAwt.setEditable(editable); 154 } 155 156 157 158 @Override public void repaintGthread(){ 159 GralWidget.DynamicData dyda = dyda(); 160 int chg = dyda.getChanged(); 161 if((chg & chgText) !=0 && dyda.displayedText !=null){ 162 if(widgg.isEditable()){ 163 editBuffer.setLength(0); editBuffer.append(dyda().displayedText); 164 } 165 } 166 if((chg & chgEditable) !=0) { 167 if(widgg.isEditable()){ 168 if(editBuffer == null) { editBuffer = new StringBuilder(20); } 169 editBuffer.setLength(0); editBuffer.append(dyda().displayedText); 170 } else { //not editable 171 editBuffer = null; //garbage it. 172 } 173 } 174 dyda.acknChanged(chg); 175 if((chg & chgColorText) !=0){ widgetAwt.setForeground(widgHelper.mng.getColorImpl(dyda.textColor)); } 176 if((chg & chgColorBack) !=0){ widgetAwt.setBackground(widgHelper.mng.getColorImpl(dyda.backColor)); } 177 widgetAwt.repaint(); 178 } 179 180 181 182 @Override public GralRectangle getPixelPositionSize() 183 { 184 // TODO Auto-generated method stub 185 return null; 186 } 187 188 189 190 191 private void processKey(int key){ 192 int caretPos = caretPos(); 193 int caretPos1 = caretPos; 194 if(KeyCode.isWritingKey(key) && widgg.isEditable()){ 195 switch(key){ 196 case KeyCode.del: { 197 if(caretPos < editBuffer.length()) { 198 editBuffer.deleteCharAt(caretPos); 199 caretPos1 = -1; //force repaint 200 } 201 } break; 202 case KeyCode.back: { 203 if(caretPos >=1){ 204 caretPos -=1; 205 editBuffer.deleteCharAt(caretPos); 206 } 207 } break; 208 default: { 209 } 210 editBuffer.insert(caretPos, (char)key); 211 caretPos +=1; 212 } //switch 213 dyda().displayedText = editBuffer.toString(); //it will be shown, a String is necessary. 214 } else { 215 switch(key){ 216 case KeyCode.left: if(caretPos >=1){ caretPos -=1; } break; 217 case KeyCode.right: if(caretPos < editBuffer.length()){ caretPos +=1; } break; 218 } 219 } 220 if(caretPos != caretPos1) { 221 caretPos(caretPos); //set new pos. 222 widgetAwt.repaint(); 223 } 224 } 225 226 227 private void paint(Graphics gc) { 228 String text = dyda().displayedText; 229 Rectangle r = widgetAwt.getBounds(); 230 if(text != null) { 231 gc.drawString(text, 1, r.height -2); 232 if(widgg.isEditable() && widgg.isInFocus()) { 233 int caretPos = caretPos(); 234 int x = 7*caretPos; 235 gc.drawLine(x, 1, x, r.height-2); 236 } 237 } 238 } 239 240 HierarchyBoundsListener hierarchyBoundsListener = new HierarchyBoundsListener() 241 { 242 243 @Override public void ancestorMoved(HierarchyEvent e) 244 { 245 System.out.println("AwtField: hierarchy-anchestorMoved"); 246 247 } 248 249 @Override public void ancestorResized(HierarchyEvent e) 250 { 251 System.out.println("AwtField: hierarchy-anchestorResized"); 252 253 } 254 255 }; 256 257 258 @SuppressWarnings("serial") 259 class TextCanvas extends Canvas implements AwtWidget { 260 261 Object data; 262 263 @SuppressWarnings("synthetic-access") 264 @Override public void paint(Graphics gc) { 265 AwtTextField.this.paint(gc); 266 } 267 268 @Override public Object getData() { return data; } 269 270 @Override public void setData(Object data){ this.data = data; } 271 272 } 273 274 275 276 KeyListener keyListener = new KeyListener() { 277 278 /**Invoked on character keys 279 * @see java.awt.event.KeyListener#keyTyped(java.awt.event.KeyEvent) 280 */ 281 @SuppressWarnings("synthetic-access") 282 @Override public void keyTyped(KeyEvent e) 283 { 284 int key = AwtGralKey.convertFromAwt(e.getKeyCode(), e.getModifiersEx(), e.getKeyChar()); 285 //processKey(key); 286 287 } 288 289 /**Invoked on function keys and on character keys. 290 * @see java.awt.event.KeyListener#keyPressed(java.awt.event.KeyEvent) 291 */ 292 @SuppressWarnings("synthetic-access") 293 @Override public void keyPressed(KeyEvent e) 294 { 295 int key = AwtGralKey.convertFromAwt(e.getKeyCode(), e.getModifiersEx(), e.getKeyChar()); 296 processKey(key); 297 } 298 299 @Override public void keyReleased(KeyEvent e) 300 { 301 // TODO Auto-generated method stub 302 303 } 304 305 }; 306 307 308 309 310 311 312 313 314}