2

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

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

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

我目前有逻辑可以将插入符号移动到正确的位置,因此控件或多或少起作用,唯一的问题是用户看到插入符号在代码试图对抗默认移动时疯狂地跳跃。

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

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

4

3 回答 3

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);
  }
}
于 2013-05-09T05:50:11.670 回答
0

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

this.textField.caretPositionProperty().addListener(new InvalidationListener() {
        @Override
        public void invalidated(Observable observable) {
            TextField textField = (TextField) property.getBean();
    textField.positionCaret(textField.getText().length());
        }
    });
于 2017-04-22T07:50:12.333 回答
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:
   }
}
于 2017-01-03T08:48:38.363 回答