我创建了一个 CustomTextField 当我键入超出 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, 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,0, textWidth, textHeight);
}
}
我已经将它初始化为
CustomTextField textField=new CustomTextField(200, 20);
add(textField);
我觉得 HorizontalFieldManager 需要 Scroll(是滚动功能)...但是还没有想出解决方案 请帮忙
最佳答案
因此,在 BlackBerry 字段中,extent 是字段的实际视觉 大小。但是,虚拟范围 是它可以使用的逻辑 大小,其中一些可能不可见。对于要滚动的 Managers
,通常会将虚拟范围设置为大于范围。
我使用这个概念来动态更改 HorizontalFieldManager
的虚拟范围,基于当前需要多少空间来勉强容纳 BasicEditField
中的文本。为此,我必须通过实现 FieldChangeListener
让 HorizontalFieldManager
监听对 BasicEditField
的更改。然后,当每个字符被输入到编辑字段时,水平字段管理器将重新计算字段中现在的文本量需要多少宽度。然后它将虚拟宽度重新设置为该宽度。
这导致水平字段管理器只允许滚动到输入文本的末尾,而不是向右滚动,这是代码最初的工作方式。
因此,我不认为黑莓手机做错了什么……操作系统中没有错误。以前,只是没有设置虚拟范围。
我将您的 HorizontalFieldManager 拆分为一个新的私有(private)类,因为我不喜欢在逻辑超过大约 5 行代码时使用匿名类。因此,下面的解决方案看起来有点不同。
其他想法:
1) 由于您尝试使用自定义 paint()
实现绘制边框,因此存在绘图伪像。但是,那个错误本来就在那里,我将这个问题解释为关于滚动问题。看起来您正在尝试使用 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, 0, textWidth, 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);
}
}
}
}
关于java - 水平滚动和 TextField 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10617804/