我创建了一个扩展TextField的自定义组件,允许对特定类型的字符串进行高级编辑。
箭头键已重新定义以允许特定行为,并且不会触发默认插入符号移动但是我似乎无法阻止其移动。我已经消耗了()我能想象到的每种类型的事件,当按下箭头键时,插入符将始终移动。
此外,在键入新字母时,首先会对其进行验证,如果发现无效,则会撤消编辑。但是,当您输入的字母无效时,插入符总是移动一个位置,而不应移动。
我目前有逻辑,它会将插入符号移动到正确的位置,因此控件或多或少有效,唯一的问题是当代码试图对抗默认移动时,用户会看到插入符号疯狂跳跃。 / p>
一个有趣的说明:我已经为控件提供了一个上下文菜单,当显示上下文菜单时,插入符号会停止其默认移动(或者它突然足够快,因此用户看不到它)。
我正在深入研究上下文菜单的源代码,看它是否设置或取消设置,但我没有看到它。任何想法如何停止文本字段的默认插入符号移动?
答案 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());
}
});