我正在尝试在密码字段上实施大写锁定警报。如果大写锁定为开,则气泡将出现在密码字段下方。我进行了很多搜索,但没有找到如何在JavaFX的输入字段中实现这种冒泡的解决方案。我找到了一些用于获取大写锁定状态的源代码。
boolean isOn=Toolkit.getDefaultToolkit().getLockingKeyState(KeyEvent.VK_CAPS_LOCK);
scene.setOnKeyReleased( event -> {
if ( event.getCode() == KeyCode.CAPS ) {
System.out.println("Capslock pressed");
System.out.println("Capslock state: " + isOn);
}
});
但是我的问题是如何在文本字段上实现气泡警报。 在这里,您可以看到我要做的事情。
如果您建议我一些新的JavaFX可能方法会很有帮助。是否有任何JavaFX库在输入字段上执行此类气泡警报?
答案 0 :(得分:1)
JavaFX无法检测CapsLock。从理论上讲,您可以安装一个全场景的侦听器,但是当状态改变而其他应用程序具有焦点时,该侦听器将无法捕获。
混合AWT / Swing和JavaFX非常危险,因为它们每个都有自己的线程,几乎所有方法都必须在该线程上执行。由于仍然需要轮询CapsLock,因此使用javax.swing.Timer是有意义的,playground可以定期执行操作并确保操作在适当的线程(AWT事件分发线程)中运行:
BooleanProperty capsLockOn = new SimpleBooleanProperty();
EventQueue.invokeLater(() -> {
Timer timer = new Timer(500, e -> {
boolean state = Toolkit.getDefaultToolkit().getLockingKeyState(
KeyEvent.VK_CAPS_LOCK);
Platform.runLater(() -> capsLockOn.set(state));
});
timer.start();
Platform.runLater(() -> {
Window window = passwordField.getScene().getWindow();
window.setOnShown(e -> EventQueue.invokeLater(timer::restart));
window.setOnHidden(e -> EventQueue.invokeLater(timer::stop));
});
});
Region message = new BorderPane(new Label("Caps Lock is on"));
message.setStyle(
"-fx-background-color: #f4f4f4;" +
"-fx-border-color: black;" +
"-fx-border-width: 1px;" +
"-fx-padding: 1em 1em 0.75em 1em;" +
"-fx-shape: 'M 0 10 h 20 l 10 -10 l 10 10 h 150 v 90 h -190 z';"
);
Popup capsLockWarning = new Popup();
capsLockWarning.getContent().add(message);
capsLockOn.addListener((o, wasOn, on) -> {
if (on) {
Point2D location =
passwordField.localToScreen(-15, passwordField.getHeight());
capsLockWarning.show(passwordField,
location.getX(), location.getY());
} else {
capsLockWarning.hide();
}
});
答案 1 :(得分:1)
听起来您已经弄清楚如何获取输入状态,可以为监听器尝试类似的操作
public class Main extends Application {
private Label capsLabel = new Label("Caps is ON");
private boolean capsIsOn;
@Override
public void start(Stage stage) {
System.out.println(Toolkit.getDefaultToolkit().getLockingKeyState(20));
//Try adding this line to get state on startup
capsLabel.setVisible(Toolkit.getDefaultToolkit().getLockingKeyState(20));
TextField textField = new TextField();
//Also try adding this line and to check again so when the field
//is selected it will check again
textField.setOnMouseClicked(event -> capsLabel.setVisible(Toolkit.getDefaultToolkit().getLockingKeyState(20)));
textField.setOnKeyReleased(keyEvent -> {
if(keyEvent.getCode().toString().equals("CAPS")){
capsIsOn = !capsIsOn;
capsLabel.setVisible(capsIsOn);
}
});
VBox vBox = new VBox();
vBox.getChildren().addAll(textField, capsLabel);
stage = new Stage();
stage.setScene(new Scene(vBox));
stage.show();
}
public static void main(String[] args) { launch(args); }
}
或者,您可以在计时器上设置它,并让它不断地进行个人检查,我不喜欢不断使用计算机资源的想法,但是我的项目不是我的想法。