JavaFX文本字段:禁用光标移动

时间:2013-05-08 12:45:13

标签: javafx

我创建了一个扩展TextField的自定义组件,允许对特定类型的字符串进行高级编辑。

箭头键已重新定义以允许特定行为,并且会触发默认插入符号移动但是我似乎无法阻止其移动。我已经消耗了()我能想象到的每种类型的事件,当按下箭头键时,插入符将始终移动。

此外,在键入新字母时,首先会对其进行验证,如果发现无效,则会撤消编辑。但是,当您输入的字母无效时,插入符总是移动一个位置,而不应移动。

我目前有逻辑,它会将插入符号移动到正确的位置,因此控件或多或少有效,唯一的问题是当代码试图对抗默认移动时,用户会看到插入符号疯狂跳跃。 / p>

一个有趣的说明:我已经为控件提供了一个上下文菜单,当显示上下文菜单时,插入符号会停止其默认移动(或者它突然足够快,因此用户看不到它)。

我正在深入研究上下文菜单的源代码,看它是否设置或取消设置,但我没有看到它。任何想法如何停止文本字段的默认插入符号移动?

3 个答案:

答案 0 :(得分:5)

您可以使用事件过滤器来阻止节点处理左箭头和右箭头:

textField.addEventFilter(KeyEvent.ANY, new EventHandler<KeyEvent>() {
  @Override public void handle(KeyEvent keyEvent) {
    switch (keyEvent.getCode()) {
      case LEFT:
      case RIGHT:
        keyEvent.consume();
    }
  }
});

这有点奇怪,因为TextField将不再像用户通常期望的那样行事。

可执行样本

import javafx.application.*;
import javafx.beans.*;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class TextFieldControl extends Application {
  @Override public void start(Stage stage) {
    final TextField textField = new TextField("Phone: ");
    textField.addEventFilter(KeyEvent.ANY, new EventHandler<KeyEvent>() {
      @Override
      public void handle(KeyEvent keyEvent) {
        switch (keyEvent.getCode()) {
          // block cursor control keys.
          case LEFT:
          case RIGHT:
          case UP:
          case DOWN:
          case PAGE_UP:
          case PAGE_DOWN:
          case HOME:
          case END:
            keyEvent.consume();

          // allow deletion and tab.
          case DELETE:
          case BACK_SPACE:
          case TAB:
            return;
        }

        // only allow digits and a few punctuation symbols to be entered.
        if (!"0123456789-() ".contains(keyEvent.getCharacter())) {
          keyEvent.consume();
        }
      }
    });

    textField.focusedProperty().addListener(new InvalidationListener() {
      @Override public void invalidated(Observable observable) {
        // due to some weirdness JavaFX will auto select the text when the text field
        // receives focus, so instead deselect and position the caret at the end of the field.
        // Another weird thing is that a pulse must be run before the deselection or caret
        // positioning request occurs or it won't take effect, so a runnable seems to suffic to ensure that.
        Platform.runLater(new Runnable() {
          @Override public void run() {
            textField.deselect();
            textField.positionCaret(textField.getText().length());
          }
        });
      }
    });

    VBox layout = new VBox();
    layout.getChildren().setAll(new VBox(textField, new TextField()));
    stage.setScene(new Scene(layout));
    stage.show();

    textField.requestFocus();
  }

  public static void main(String[] args) {
    launch(args);
  }
}

答案 1 :(得分:0)

@FXML
    private void handleKeyPressed(KeyEvent ke){
        //System.out.println(testing.getName());
        Scene scene = (Scene) logoHbox.getScene();
        System.out.println(ke.getCode());

        switch (ke.getCode()) {
            case LEFT:
               Integer previousKey = Integer.parseInt(((Control)ke.getSource()).getId()) - 1;
               System.out.println(previousKey);
               //System.out.println("Key Pressed: " + ((Control)ke.getSource()).getId());
               if(previousKey == 0) {
                   return;
               }
               TextField tb = (TextField) scene.lookup("#"+previousKey);
               tb.requestFocus();
               System.out.println(tb.getText());
                break;

            case RIGHT:
               Integer nextKey = Integer.parseInt(((Control)ke.getSource()).getId()) + 1;
               System.out.println(nextKey);
               if(nextKey == 61) {
                   return;
               }
               //System.out.println("Key Pressed: " + ((Control)ke.getSource()).getId());
               TextField right = (TextField) scene.lookup("#"+nextKey);
               right.requestFocus();
               //System.out.println(tb.getText());
                break;
            case DOWN:
               Integer DownKey = Integer.parseInt(((Control)ke.getSource()).getId()) + 10;
               System.out.println(DownKey);
               if(DownKey == 70) {
                   return;
               }
               //System.out.println("Key Pressed: " + ((Control)ke.getSource()).getId());
               if(DownKey == 61) {
                   DownKey = 2;
               } else if(DownKey == 62) {
                   DownKey = 3;
               } else if(DownKey == 63) {
                   DownKey = 4;
               } else if(DownKey == 64) {
                   DownKey = 5;
               } else if(DownKey == 65) {
                   DownKey = 6;
               } else if(DownKey == 66) {
                   DownKey = 7;
               } else if(DownKey == 67) {
                   DownKey = 8;
               } else if(DownKey == 68) {
                   DownKey = 9;
               } else if(DownKey == 69) {
                   DownKey = 10;
               }
               TextField down = (TextField) scene.lookup("#"+DownKey);
               down.requestFocus();
               //System.out.println(tb.getText());
                break;
            case UP:
               Integer UpKey = Integer.parseInt(((Control)ke.getSource()).getId()) - 10;
               System.out.println(UpKey);
               //System.out.println("Key Pressed: " + ((Control)ke.getSource()).getId());
               if(UpKey == -9) {
                   return;
               }
               if(UpKey == 0) {
                   UpKey = 59;
               } else if(UpKey == -1) {
                   UpKey = 58;
               } else if(UpKey == -2) {
                   UpKey = 57;
               } else if(UpKey == -3) {
                   UpKey = 56;
               } else if(UpKey == -4) {
                   UpKey = 55;
               } else if(UpKey == -5) {
                   UpKey = 54;
               } else if(UpKey == -6) {
                   UpKey = 53;
               } else if(UpKey == -7) {
                   UpKey = 52;
               } else if(UpKey == -8) {
                   UpKey = 51;
               }
               TextField up = (TextField) scene.lookup("#"+UpKey);
               up.requestFocus();
               //System.out.println(tb.getText());
                break;
            case F9:
               clearAll();
               break;
            case TAB:
               break;
            default:
   }
}

答案 2 :(得分:0)

实现此函数的最佳方法是使用caretPositionProperty()方法并添加侦听器。 代码如下:

this.textField.caretPositionProperty().addListener(new InvalidationListener() {
        @Override
        public void invalidated(Observable observable) {
            TextField textField = (TextField) property.getBean();
    textField.positionCaret(textField.getText().length());
        }
    });