Горизонтальная прокрутка и ошибка текстового поля

Я создал CustomTextField  который прокручивается влево, когда я набираю текст, который больше, чем ширина TextField  для которых используется HorizonalFieldManager  Но теперь проблема в том, что я правой кнопкой мыши и прокручиваю ее  он переходит к неадекватной длине  но не останавливается до последнего слова я type В чем проблема? Это ошибка

Мне просто нужно отключить 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);
    }

}

i инициализировал его как

 CustomTextField textField=new CustomTextField(200, 20);
            add(textField);

Я чувствую потребность в Scroll (функция прокрутки) для HorizontalFieldManager... но еще не придумал решение Пожалуйста, помогите

Ответ 1

Итак, в полях BlackBerry размер - это фактический визуальный размер поля. Но виртуальная степень - это логический размер, который он может использовать, некоторые из которых могут быть не видны. Для Managers, который вы хотите иметь прокрутку, вы обычно устанавливаете виртуальную степень больше, чем размер.

Я использовал эту концепцию для динамического изменения виртуальной протяженности вашего HorizontalFieldManager, основываясь на том, сколько пространства в настоящее время необходимо, чтобы едва соответствовать тексту в BasicEditField. Чтобы сделать это, я должен был позволить HorizontalFieldManager прослушать изменения в BasicEditField, выполнив FieldChangeListener. Затем, когда каждый символ вводится в поле редактирования, диспетчер горизонтальных полей пересчитывает, сколько ширины требуется для количества текста, который теперь находится в поле. Затем он снова устанавливает виртуальную ширину в эту ширину.

Это приводит к тому, что диспетчер горизонтального поля разрешает прокрутку только до конца введенного текста, а не справа, так как исходный код был выполнен.

Итак, я не думаю, что BlackBerry делал что-то неправильно... никаких ошибок в ОС. Раньше виртуальная степень просто не была установлена.

Я разделил свой HorizontalFieldManager на новый частный класс, потому что мне не нравится использовать анонимные классы, когда логика превышает примерно 5 строк кода. Итак, нижеприведенное решение выглядит несколько иначе.

Другие мысли:

1) В результате попытки рисования границы с пользовательской реализацией paint() появляются рисунки артефактов. Но эта ошибка была изначально там, и я решил этот вопрос о проблеме прокрутки. Похоже, вы пытались использовать объекты Border, что, вероятно, является лучшим способом достижения границы для поля прокрутки.

2) С моим новым решением фактический класс CustomTextField в нем мало. Это только контейнер (Manager) для CustomHorizontalFieldManager. Возможно, вы могли бы избавиться от этого внешнего слоя, если хотите. Но я знаю, что иногда, когда вы отправляете код, вы удаляете детали, которые не важны для того, с чем вы столкнулись. Таким образом, возможно наличие VerticalFieldManager содержит a HorizontalFieldManager, который содержит 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 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);
         }
      }
   }

}