001package org.vishia.gral.base; 002 003import java.io.IOException; 004 005import org.eclipse.swt.graphics.Point; 006import org.vishia.gral.ifc.GralColor; 007import org.vishia.gral.ifc.GralFont; 008import org.vishia.gral.ifc.GralMng_ifc; 009import org.vishia.gral.ifc.GralTextBox_ifc; 010import org.vishia.gral.ifc.GralTextFieldUser_ifc; 011import org.vishia.util.KeyCode; 012 013public class GralTextBox extends GralTextField implements Appendable, GralTextBox_ifc 014{ 015 016 /**Version and history 017 * <ul> 018 * <li>2014-08-16 Hartmut chg: GrapTextBox not abstract, using GraphicImplAccess like new concept of all GralWidgets. 019 * <li>2012-01-06 Hartmut chg: The {@link #append(CharSequence)} etc. methods are implemented 020 * in this super class instead in the graphic layer implementation classes. Therefore 021 * the methods {@link #appendTextInGThread(CharSequence)} and {@link #setTextInGThread(CharSequence)} 022 * are defined here to implement in the graphic layer. The set- and apppend methods are <b>threadsafe</b> now. 023 * </ul> 024 * 025 * <b>Copyright/Copyleft</b>: 026 * For this source the LGPL Lesser General Public License, 027 * published by the Free Software Foundation is valid. 028 * It means: 029 * <ol> 030 * <li> You can use this source without any restriction for any desired purpose. 031 * <li> You can redistribute copies of this source to everybody. 032 * <li> Every user of this source, also the user of redistribute copies 033 * with or without payment, must accept this license for further using. 034 * <li> But the LPGL is not appropriate for a whole software product, 035 * if this source is only a part of them. It means, the user 036 * must publish this part of source, 037 * but don't need to publish the whole source of the own product. 038 * <li> You can study and modify (improve) this source 039 * for own using or for redistribution, but you have to license the 040 * modified sources likewise under this LGPL Lesser General Public License. 041 * You mustn't delete this Copyright/Copyleft inscription in this source file. 042 * </ol> 043 * If you are indent to use this sources without publishing its usage, you can get 044 * a second license subscribing a special contract with the author. 045 * 046 * @author Hartmut Schorrig = hartmut.schorrig@vishia.de 047 * 048 * 049 */ 050 @SuppressWarnings("hiding") 051 public final static String sVersion = "2014-08-16"; 052 053 /**Buffer for new text which is set or appended in another thread than the graphic thread. 054 * This buffer is empty if the graphic thread has processed the {@link GralGraphicTimeOrder} 055 * after calling {@link #append(CharSequence)} or {@link #setText(CharSequence)}. 056 * It is filled only temporary. 057 */ 058 private StringBuffer newText = new StringBuffer(); 059 060 public GralTextBox(String name, Type... property) 061 { super(name, property); 062 } 063 064 /**Sets the text to the widget, invoked only in the graphic thread. 065 * This method have to be implemented in the Graphic implementation layer. 066 * @param text The text which should be shown in the widget. 067 */ 068 //protected abstract void setTextInGThread(CharSequence text); 069 070 /**Appends the text to the current text in the widget, invoked only in the graphic thread. 071 * This method have to be implemented in the Graphic implementation layer. 072 * @param text The text which should be appended and shown in the widget. 073 */ 074 //protected abstract void appendTextInGThread(CharSequence text); 075 076 /**Append the text, able to call threadsafe in any thread. 077 * If the thread is the graphic thread, the text will be appended to the current text 078 * of the widget immediately. But if the thread is any other one, the text will be stored 079 * in a StringBuilder and the graphic thread will be waked up with the {@link #appendTextViewTrail} 080 * dispatch listener. 081 * 082 * @see java.lang.Appendable#append(java.lang.CharSequence) 083 */ 084 @Override public final Appendable append(CharSequence arg0) throws IOException 085 { synchronized(newText) { 086 newText.append(arg0); 087 dyda.setChanged(GraphicImplAccess.chgAddText | GraphicImplAccess.chgViewTrail); 088 repaint(); 089 } 090 return this; 091 } 092 093 /**Append a single char, able to call threadsafe in any thread. 094 * @see #append(CharSequence) 095 * 096 * @see java.lang.Appendable#append(java.lang.CharSequence) 097 */ 098 @Override public final Appendable append(char arg0) throws IOException 099 { synchronized(newText) { 100 newText.append(arg0); 101 dyda.setChanged(GraphicImplAccess.chgAddText | GraphicImplAccess.chgViewTrail); 102 repaint(); 103 } 104 return this; 105} 106 107 /**Append a sub char sequence, able to call threadsafe in any thread. 108 * @see #append(CharSequence) 109 * 110 * @see java.lang.Appendable#append(java.lang.CharSequence, int, int) 111 */ 112 @Override public final Appendable append(CharSequence arg0, int arg1, int arg2) throws IOException 113 { 114 append(arg0.subSequence(arg1, arg2)); 115 return this; 116 } 117 118 119 120 @Override public void setTextStyle(GralColor color, GralFont font) 121 { 122 dyda.textFont = font; 123 dyda.textColor = color; 124 dyda.setChanged(GralWidget.ImplAccess.chgColorText); 125 if(_wdgImpl !=null){ 126 repaint(); 127 } 128 } 129 130 131 132 @Override public void setEditable(boolean editable){ 133 dyda.setChanged(editable ? GraphicImplAccess.chgEditable : GraphicImplAccess.chgNonEditable); 134 if(_wdgImpl !=null){ 135 repaint(); 136 } 137 } 138 139 140 141 @Override public int getNrofLines(){ return 0; } //TODO 142 143 144 @Override public void viewTrail() 145 { 146 dyda.setChanged(GraphicImplAccess.chgViewTrail); 147 if(_wdgImpl !=null){ 148 repaint(); 149 } 150 151 } 152 153 154 155 public abstract class GraphicImplAccess extends GralTextField.GraphicImplAccess //GralWidget.ImplAccess 156 implements GralWidgImpl_ifc 157 { 158 public static final int chgCursor = 0x200, chgEditable = 0x400, chgNonEditable = 0x800 159 , chgViewTrail = 0x1000, chgAddText = 0x2000; 160 161 162 protected GraphicImplAccess(GralWidget widgg) 163 { 164 super(widgg); 165 } 166 167 protected String getAndClearNewText(){ String ret; synchronized(newText){ ret = newText.toString(); newText.setLength(0); } return ret; } 168 169 protected int caretPos(){ return GralTextBox.this.caretPos; } 170 171 protected void caretPos(int newPos){ GralTextBox.this.caretPos = newPos; } 172 173 protected GralTextFieldUser_ifc user(){ return GralTextBox.this.user; } 174 175 } 176 177}