根據https://wiki.openjdk.java.net/display/OpenJFX/ChoiceBox User Experience Documentation
Any Alpha-numeric Keys應該 Jumps to the first item in the list with that letter or letters在Selected state
但是,情況似乎完全不是這樣,在選擇小部件時輸入似乎沒有任何作用。
這是我最小的可重現示例:
package com.techniqab.testchoicebox;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.ChoiceBox;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import java.net.URL;
import java.nio.file.Paths;
public class TestchoiceboxApplication extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
URL url = Paths.get("./src/main/resources/sample.fxml").toUri().toURL();
Parent root = FXMLLoader.load(url);
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 300, 275));
primaryStage.show();
var cb = new ChoiceBox();
cb.getItems().add("a");
cb.getItems().add("b");
((Pane) root).getChildren().add(cb);
}
public static void main(String[] args) {
launch(args);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="com.techniqab.testchoicebox.TestchoiceboxApplication"
prefHeight="400.0" prefWidth="600.0">
</AnchorPane>
module testchoicebox {
requires javafx.controls;
requires javafx.graphics;
requires javafx.fxml;
exports com.techniqab.testchoicebox;
opens com.techniqab.testchoicebox to javafx.graphics;
}
uj5u.com熱心網友回復:
這似乎重新發明了一些應該作業的東西......顯然人們想要子類化ChoiceBox并添加這種行為而不是我在這里作為POC所做的黑客......但這有效
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.ChoiceBox;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import java.net.URL;
import java.nio.file.Paths;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalTime;
public class TestchoiceboxApplication extends Application {
private String typed="";
private Boolean gotIt=false;
private Instant lastKeyTime = Instant.now();
@Override
public void start(Stage primaryStage) throws Exception{
URL url = Paths.get("./src/main/resources/sample.fxml").toUri().toURL();
Parent root = FXMLLoader.load(url);
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 300, 275));
primaryStage.show();
var cb = new ChoiceBox();
cb.getItems().add("a");
cb.getItems().add("b");
cb.getItems().add("ab");
cb.getItems().add("aa");
cb.getItems().add("c");
cb.getItems().add("cba");
EventHandler<KeyEvent> keyEventHandler =
new EventHandler<KeyEvent>() {
public void handle(final KeyEvent keyEvent) {
keyEvent.consume();
var now = Instant.now();
if (Duration.between(lastKeyTime, now).getSeconds()>3) {
//reset search after timeout
typed="";
}
lastKeyTime = now;
typed = typed keyEvent.getCharacter();
var items = cb.getItems();
int nMatch = 0;
int i=0;
for (var item: items) {
if (item.toString().startsWith(typed)) {
if (nMatch==0) {
cb.getSelectionModel().select(item);
}
nMatch ;
i ;
}
}
if (nMatch>1) {
cb.show();
return;
} else {
if (nMatch == 1) {
cb.hide();
return;
}
}
// key didn't match
typed = keyEvent.getCharacter();
cb.show();
nMatch = 0;
for (var item: items) {
if (item.toString().startsWith(typed)) {
if (nMatch==0) {
cb.getSelectionModel().select(item);
}
nMatch ;
}
}
if (nMatch>1) {
cb.show();
return;
} else {
if (nMatch == 1) {
cb.hide();
return;
}
}
typed = "";
};
};
cb.setOnKeyTyped(keyEventHandler);
((Pane) root).getChildren().add(cb);
}
public static void main(String[] args) {
launch(args);
}
}
uj5u.com熱心網友回復:
雖然ChoiceBox 用戶體驗檔案是規范性的,但這種更簡單的變體會跳轉到串列中鍵入字母的第一項。它還回應Enter和Return鍵。
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.ChoiceBox;
import javafx.scene.input.KeyEvent;
import javafx.stage.Stage;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.StackPane;
/**
* https://stackoverflow.com/a/69591397/230513
*/
public class KeyTest extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("Key Test");
ObservableList<String> items = FXCollections.observableArrayList(
"a10", "b42", "c33", "a11", "b22", "c333", "d0");
FXCollections.sort(items);
ChoiceBox cb = new ChoiceBox(items);
EventHandler<KeyEvent> keyEventHandler = (var e) -> {
if (e.getCode() == KeyCode.ENTER) {
return;
}
e.consume();
for (var item : cb.getItems()) {
if (item.toString().startsWith(e.getCharacter())) {
cb.getSelectionModel().select(item);
cb.show();
break;
}
}
};
cb.setOnKeyTyped(keyEventHandler);
StackPane root = new StackPane();
StackPane.setMargin(cb, new Insets(16, 16, 16, 16));
root.getChildren().add(cb);
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/318410.html
