我正在制作一个组合框,该组合框将按键入的文本进行过滤,并在键入文本时显示下拉列表。
我发现this example效果很好。我对其做了一些修改,因此在输入文本时会出现下拉菜单。
但是,当我键入几个字母然后按ctrl + A选择TextField
中的所有文本时,如果下拉列表可见,则不会选择所有文本。其他东西正在消耗该热键。
这是MCVE代码:
import com.sun.javafx.scene.control.skin.ComboBoxListViewSkin;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class MCVE extends Application {
public void start(Stage stage) {
HBox root = new HBox();
ComboBox<String> cb = new ComboBox<String>();
cb.setEditable(true);
ObservableList<String> items = FXCollections.observableArrayList("One", "Two", "Three", "Four", "Five", "Six",
"Seven", "Eight", "Nine", "Ten");
FilteredList<String> filteredItems = new FilteredList<String>(items, p -> true);
cb.getEditor().textProperty().addListener((obs, oldValue, newValue) -> {
final TextField editor = cb.getEditor();
final String selected = cb.getSelectionModel().getSelectedItem();
Platform.runLater(() -> {
if ( !editor.getText().isEmpty() ) {
cb.show();
} else {
cb.hide();
}
if (selected == null || !selected.equals(editor.getText())) {
filteredItems.setPredicate(item -> {
if (item.toUpperCase().startsWith(newValue.toUpperCase())) {
return true;
} else {
return false;
}
});
}
});
});
cb.setItems(filteredItems);
root.getChildren().add(cb);
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
以下是我尝试过的一些解决方案。他们都不工作。看来问题在于JavaFX保留了热键Ctrl + A
,不会让我抓住它。
(如果密钥是D
而不是A
((ComboBoxListViewSkin)cb.getSkin()).getDisplayNode().addEventFilter( KeyEvent.KEY_PRESSED, keyEvent -> {
if ( keyEvent.isControlDown() && keyEvent.getCode() == KeyCode.A ) {
cb.getEditor().selectAll();
}
});
(如果键是D
而不是A
cb.setOnKeyPressed( ( KeyEvent e ) -> {
if ( e.isControlDown() && e.getCode() == KeyCode.D ) {
cb.getEditor().selectAll();
}
});
答案 0 :(得分:1)
该行为对于普通组合(没有任何过滤)是相同的,并且看起来像一个错误:ctrl-A被dropDown中的ListView吞噬了。要变通,您可以在列表f.i上安装eventFilter。在onShown处理程序中-此时已安装皮肤:
cb.setOnShown(e -> {
ComboBoxListViewSkin<?> skin = (ComboBoxListViewSkin<?>) cb.getSkin();
ListView<?> list = (ListView<?>) skin.getPopupContent();
list.addEventFilter( KeyEvent.KEY_PRESSED, keyEvent -> {
if (keyEvent.isControlDown() && keyEvent.getCode() == KeyCode.A ) {
cb.getEditor().selectAll();
}
});
cb.setOnShown(null);
});
这适用于所有版本(8和9+)。 For 9+ the bug更糟糕的是,编辑器内部的所有导航均被禁用(又名:列表也向左/向右吃)。