水平滚动和TextField错误

Yat*_*tin 10 java customization blackberry textfield

我创建了一个CustomTextField,当我输入的文本超出了使用Horizo​​nalFieldManager的TextField的宽度时向左滚动但是现在的问题是如果我用鼠标右键单击并滚动它继续到不适当的长度但不停止到我输入的最后一个字这里有什么问题?这是一个错误

我只需要在它到达最后一个单词时禁用Horizo​​ntalScrolling它应该能够在单词中最后一个单词的开头和结尾之间滚动

看看代码

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);
    }

}
Run Code Online (Sandbox Code Playgroud)

我把它初始化为

 CustomTextField textField=new CustomTextField(200, 20);
            add(textField);
Run Code Online (Sandbox Code Playgroud)

我觉得需要为StackFieldManager提供Scroll(滚动功能)...但尚未找到解决方案但请帮助

Nat*_*ate 4

因此,在 BlackBerry 字段中,范围是字段的实际视觉大小。但是,虚拟范围是它可以使用的逻辑大小,其中一些可能不可见。对于Managers想要滚动的情况,通常将虚拟范围设置为大于范围。

我使用这个概念来动态地改变你的虚拟范围HorizontalFieldManager,基于当前需要多少空间来勉强容纳BasicEditField. 为此,我必须通过实施 来让HorizontalFieldManager监听器监听 的更改。然后,当在编辑字段中输入每个字符时,水平字段管理器将重新计算字段中当前文本量所需的宽度。然后它将虚拟宽度重新设置为该宽度。BasicEditFieldFieldChangeListener

这导致水平字段管理器只允许滚动到输入文本的末尾,而不是向右滚动,这就是代码最初的工作方式。

所以,我不认为黑莓做错了什么......操作系统中没有错误。以前,只是未设置虚拟范围。

我将您的 Horizo​​ntalFieldManager 拆分为一个新的私有类,因为当逻辑超过大约 5 行代码时,我不喜欢使用匿名类。因此,下面的解决方案看起来有点不同。

其他想法:

1) 由于您尝试使用自定义paint()实现绘制边框,因此出现了绘图伪影。但是,这个错误最初就存在,我将这个问题解释为关于滚动问题。看起来您正在尝试使用Border对象,这可能是实现滚动字段边框的更好方法。

2)使用我的新解决方案,实际的CustomTextField课程并没有太多内容。它Manager只是CustomHorizontalFieldManager. 如果你愿意的话,你可以去掉那层外层。但是,我知道有时当您发布代码时,您会删除对您遇到问题不重要的细节。所以,也许需要一个VerticalFieldManager包含 aHorizontalFieldManager的包含 a 。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);
         }
      }
   }

}
Run Code Online (Sandbox Code Playgroud)