当我键入超过TextField的宽度的文本时,它向左滚动
使用了HorizonalFieldManager
但现在的问题是如果我用鼠标右键单击并滚动它
它的长度不足
但是不要停止我打字的最后一个字
这里有什么问题?
这是一个bug吗
我只需要它来达到最后一个字时禁用HorizontalScrolling
它应该能够在最后一个单词的开始和结束之间滚动
查看代码
import net.rim.device.api.ui.Color; import net.rim.device.api.ui.Field; import net.rim.device.api.ui.FocusChangeListener; import net.rim.device.api.ui.Graphics; import net.rim.device.api.ui.Manager; import net.rim.device.api.ui.XYEdges; import net.rim.device.api.ui.XYRect; import net.rim.device.api.ui.component.BasicEditField; import net.rim.device.api.ui.container.HorizontalFieldManager; import net.rim.device.api.ui.container.VerticalFieldManager; import net.rim.device.api.ui.decor.Border; import net.rim.device.api.ui.decor.BorderFactory; public class CustomTextField extends VerticalFieldManager { private int textWidth=0; private int textHeight=0; private BasicEditField basicEditField; private HorizontalFieldManager hfm; //Border border; public CustomTextField(int width,int height) { super(); textWidth=width; textHeight=height; //border=BorderFactory.createSimpleBorder(new XYEdges(1,1,1)); hfm=new HorizontalFieldManager(Manager.HORIZONTAL_SCROLL){ protected void sublayout(int maxWidth,int maxHeight) { super.sublayout(maxWidth,maxHeight); setExtent(textWidth,textHeight); } }; basicEditField=new BasicEditField("","",200,BasicEditField.NO_NEWLINE); //basicEditField.setBorder(border); hfm.add(basicEditField); add(hfm); } protected void sublayout(int maxWidth,int maxHeight) { super.sublayout(textWidth,textHeight); setExtent(textWidth,textHeight); } protected void paint(Graphics graphics) { super.paint(graphics); graphics.setColor(Color.BLACK); graphics.drawRect(0,textWidth,textHeight); } }
我已经将其初始化为
CustomTextField textField=new CustomTextField(200,20); add(textField);
解决方法
我使用这个概念来动态地改变您的HorizontalFieldManager的虚拟范围,这取决于当前需要多少空间才能适应BasicEditField中的文本.为此,我必须让HorizontalFieldManager通过实现FieldChangeListener监听BasicEditField的更改.然后,当每个字符输入到编辑字段时,水平字段管理器将重新计算现在在该字段中的文本量所需的宽度.然后将虚拟宽度重新设置为该宽度.
这使得水平字段管理器只允许滚动到输入的文本的末尾,而不是右边的方式,这是代码最初工作的方式.
所以,我不认为黑莓手机做错了什么…没有操作系统的bug.以前,虚拟范围没有设置.
我将您的HorizontalFieldManager拆分成一个新的私有类,因为当逻辑超过5行代码时,我不喜欢使用匿名类.所以,下面的解决方案有所不同.
其他想法:
1)由于您尝试使用自定义paint()实现绘制边框,因此存在绘图工件.但是,那个bug最初在那里,我把这个问题解释成是滚动问题.看起来您正在尝试使用Border对象,这可能是实现滚动字段边框的更好方式.
2)使用我的新解决方案,实际的CustomTextField类没有太多的内容.它只是CustomHorizontalFieldManager的容器(Manager).如果你想要的话,你可能会摆脱外层.但是,我知道有时你发布代码时,会删除对您遇到麻烦的事情不重要的细节.所以,也许需要一个VerticalFieldManager包含一个HorizontalFieldManager,它包含一个BasicEditField.我会把它留给你,但它只会是可选的清理.
3)我在5.0 Storm2模拟器上测试了这个.
import net.rim.device.api.ui.Color; import net.rim.device.api.ui.Field; import net.rim.device.api.ui.FieldChangeListener; import net.rim.device.api.ui.Graphics; import net.rim.device.api.ui.Manager; import net.rim.device.api.ui.component.BasicEditField; import net.rim.device.api.ui.container.HorizontalFieldManager; import net.rim.device.api.ui.container.VerticalFieldManager; import net.rim.device.api.util.Arrays; public class CustomTextField extends VerticalFieldManager { private int textWidth = 0; private int textHeight = 0; private CustomHorizontalFieldManager hfm; public CustomTextField(int width,int height) { super(); textWidth = width; textHeight = height; hfm = new CustomHorizontalFieldManager(); add(hfm); } protected void sublayout(int maxWidth,int maxHeight) { super.sublayout(textWidth,textHeight); setExtent(textWidth,textHeight); } protected void paint(Graphics graphics) { // TODO: change me! super.paint(graphics); graphics.setColor(Color.BLACK); graphics.drawRect(0,textHeight); } private class CustomHorizontalFieldManager extends HorizontalFieldManager implements FieldChangeListener { private BasicEditField basicEditField; /** the maximum virtual width of the edit field,based on the max num of chars */ private int maxVirtualWidth; public CustomHorizontalFieldManager() { super(Manager.HORIZONTAL_SCROLL); int maxNumChars = 200; basicEditField = new BasicEditField("",maxNumChars,BasicEditField.NO_NEWLINE); // determine how wide the field would need to be to hold 'maxNumChars',with the font // in use ... just pick a long string of all W's,since that's usually the widest char char[] buffer = new char[maxNumChars]; Arrays.fill(buffer,'W'); String spacer = new String(buffer); maxVirtualWidth = basicEditField.getFont().getAdvance(spacer); // we need to listen as the user types in this field,so we can dynamically alter its // virtual width basicEditField.setChangeListener(this); add(basicEditField); } protected void sublayout(int maxWidth,int maxHeight) { super.sublayout(maxWidth,maxHeight); // extent is the visible size,virtual extent can be wider if we want scrolling setExtent(textWidth,textHeight); setVirtualExtent(maxVirtualWidth,textHeight); } public void fieldChanged(Field f,int context) { if (f == basicEditField) { // recalculate how much virtual width the edit field needs,based on the // current text content int newWidth = basicEditField.getFont().getAdvance(basicEditField.getText()); setVirtualExtent(newWidth,textHeight); } } } }