Javafx 在按键时选择组合框选项。我希望选择模型自动滚动/跳转到所选选项

Javafx 在按键时选择组合框选项。我希望选择模型自动滚动/跳转到所选选项,javafx,combobox,Javafx,Combobox,到目前为止我拥有的: import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.stage.Stage; public class Main extends Application { @Override public void start(Stage pri

到目前为止我拥有的:

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{

        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));

        Scene scene = new Scene(root, 850.0, 650.0);

        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
import java.net.URL;
import java.util.ResourceBundle;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ComboBox;
import javafx.scene.control.SingleSelectionModel;
import javafx.scene.input.KeyCode;

public class SampleController implements Initializable {

    @FXML private ComboBox<String> cb;

    //Entered random options
    private final ObservableList<String> options = FXCollections.observableArrayList(
            "Aab",
            "Aer",
            "Aeq",
            "Arx",
            "Byad",
            "Csca",
            "Csee",
            "Cfefe",
            "Cead",
            "Defea",
            "Dqeqe",
            "Fefaf",
            "Gert",
            "Wqad",
            "Xsad",
            "Zzz"
            );

    @Override
    public void initialize(URL location, ResourceBundle resources) {

        cb.getItems().addAll(options);

        selectOptionOnKey();
    }

    /* When you press a letter key
    *  this method will search for an option(item) that starts with the input letter key 
    *  and it selects the first occurrence in combo box
    */
    public void selectOptionOnKey() {
        cb.setOnKeyPressed(e -> {
            KeyCode keyCode = e.getCode();

            if (keyCode.isLetterKey()) {
                char key = keyCode.getName().charAt(0);

                SingleSelectionModel<String> cbSelectionModel = cb.getSelectionModel();

                cbSelectionModel.select(0);

                for (int i = 0; i < options.size(); i++) {
                    if(cbSelectionModel.getSelectedItem().charAt(0) == key) {
                        // option which starts with the input letter found -> select it
                        cbSelectionModel.select(i);
                        /* Before exiting the function it would be nice if after the selection,
                           the combo box would auto slide/jump to the option which is selected.
                           I don't know how to do that. */
                        return;
                    }
                    else
                        cbSelectionModel.selectNext();
                }   
            }
        });
    }
}
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="SampleController">
   <children>
      <ComboBox fx:id="cb" layoutX="300.0" layoutY="300.0" prefHeight="25.0" prefWidth="173.0" />
   </children>
</AnchorPane>
例如,当我按下C键按钮时,会发生以下情况:

selectOptionOnKey(见下文)功能选择以字母C开头的选项

问题:

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{

        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));

        Scene scene = new Scene(root, 850.0, 650.0);

        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
import java.net.URL;
import java.util.ResourceBundle;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ComboBox;
import javafx.scene.control.SingleSelectionModel;
import javafx.scene.input.KeyCode;

public class SampleController implements Initializable {

    @FXML private ComboBox<String> cb;

    //Entered random options
    private final ObservableList<String> options = FXCollections.observableArrayList(
            "Aab",
            "Aer",
            "Aeq",
            "Arx",
            "Byad",
            "Csca",
            "Csee",
            "Cfefe",
            "Cead",
            "Defea",
            "Dqeqe",
            "Fefaf",
            "Gert",
            "Wqad",
            "Xsad",
            "Zzz"
            );

    @Override
    public void initialize(URL location, ResourceBundle resources) {

        cb.getItems().addAll(options);

        selectOptionOnKey();
    }

    /* When you press a letter key
    *  this method will search for an option(item) that starts with the input letter key 
    *  and it selects the first occurrence in combo box
    */
    public void selectOptionOnKey() {
        cb.setOnKeyPressed(e -> {
            KeyCode keyCode = e.getCode();

            if (keyCode.isLetterKey()) {
                char key = keyCode.getName().charAt(0);

                SingleSelectionModel<String> cbSelectionModel = cb.getSelectionModel();

                cbSelectionModel.select(0);

                for (int i = 0; i < options.size(); i++) {
                    if(cbSelectionModel.getSelectedItem().charAt(0) == key) {
                        // option which starts with the input letter found -> select it
                        cbSelectionModel.select(i);
                        /* Before exiting the function it would be nice if after the selection,
                           the combo box would auto slide/jump to the option which is selected.
                           I don't know how to do that. */
                        return;
                    }
                    else
                        cbSelectionModel.selectNext();
                }   
            }
        });
    }
}
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="SampleController">
   <children>
      <ComboBox fx:id="cb" layoutX="300.0" layoutY="300.0" prefHeight="25.0" prefWidth="173.0" />
   </children>
</AnchorPane>
组合框存储了可同时显示的更多选项。因此,当选择的选项不在显示区域时,我希望组合框向下滚动/跳转到该选项,但我不知道如何操作


示例代码:

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{

        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));

        Scene scene = new Scene(root, 850.0, 650.0);

        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
import java.net.URL;
import java.util.ResourceBundle;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ComboBox;
import javafx.scene.control.SingleSelectionModel;
import javafx.scene.input.KeyCode;

public class SampleController implements Initializable {

    @FXML private ComboBox<String> cb;

    //Entered random options
    private final ObservableList<String> options = FXCollections.observableArrayList(
            "Aab",
            "Aer",
            "Aeq",
            "Arx",
            "Byad",
            "Csca",
            "Csee",
            "Cfefe",
            "Cead",
            "Defea",
            "Dqeqe",
            "Fefaf",
            "Gert",
            "Wqad",
            "Xsad",
            "Zzz"
            );

    @Override
    public void initialize(URL location, ResourceBundle resources) {

        cb.getItems().addAll(options);

        selectOptionOnKey();
    }

    /* When you press a letter key
    *  this method will search for an option(item) that starts with the input letter key 
    *  and it selects the first occurrence in combo box
    */
    public void selectOptionOnKey() {
        cb.setOnKeyPressed(e -> {
            KeyCode keyCode = e.getCode();

            if (keyCode.isLetterKey()) {
                char key = keyCode.getName().charAt(0);

                SingleSelectionModel<String> cbSelectionModel = cb.getSelectionModel();

                cbSelectionModel.select(0);

                for (int i = 0; i < options.size(); i++) {
                    if(cbSelectionModel.getSelectedItem().charAt(0) == key) {
                        // option which starts with the input letter found -> select it
                        cbSelectionModel.select(i);
                        /* Before exiting the function it would be nice if after the selection,
                           the combo box would auto slide/jump to the option which is selected.
                           I don't know how to do that. */
                        return;
                    }
                    else
                        cbSelectionModel.selectNext();
                }   
            }
        });
    }
}
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="SampleController">
   <children>
      <ComboBox fx:id="cb" layoutX="300.0" layoutY="300.0" prefHeight="25.0" prefWidth="173.0" />
   </children>
</AnchorPane>
Main:

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{

        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));

        Scene scene = new Scene(root, 850.0, 650.0);

        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
import java.net.URL;
import java.util.ResourceBundle;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ComboBox;
import javafx.scene.control.SingleSelectionModel;
import javafx.scene.input.KeyCode;

public class SampleController implements Initializable {

    @FXML private ComboBox<String> cb;

    //Entered random options
    private final ObservableList<String> options = FXCollections.observableArrayList(
            "Aab",
            "Aer",
            "Aeq",
            "Arx",
            "Byad",
            "Csca",
            "Csee",
            "Cfefe",
            "Cead",
            "Defea",
            "Dqeqe",
            "Fefaf",
            "Gert",
            "Wqad",
            "Xsad",
            "Zzz"
            );

    @Override
    public void initialize(URL location, ResourceBundle resources) {

        cb.getItems().addAll(options);

        selectOptionOnKey();
    }

    /* When you press a letter key
    *  this method will search for an option(item) that starts with the input letter key 
    *  and it selects the first occurrence in combo box
    */
    public void selectOptionOnKey() {
        cb.setOnKeyPressed(e -> {
            KeyCode keyCode = e.getCode();

            if (keyCode.isLetterKey()) {
                char key = keyCode.getName().charAt(0);

                SingleSelectionModel<String> cbSelectionModel = cb.getSelectionModel();

                cbSelectionModel.select(0);

                for (int i = 0; i < options.size(); i++) {
                    if(cbSelectionModel.getSelectedItem().charAt(0) == key) {
                        // option which starts with the input letter found -> select it
                        cbSelectionModel.select(i);
                        /* Before exiting the function it would be nice if after the selection,
                           the combo box would auto slide/jump to the option which is selected.
                           I don't know how to do that. */
                        return;
                    }
                    else
                        cbSelectionModel.selectNext();
                }   
            }
        });
    }
}
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="SampleController">
   <children>
      <ComboBox fx:id="cb" layoutX="300.0" layoutY="300.0" prefHeight="25.0" prefWidth="173.0" />
   </children>
</AnchorPane>
控制器:

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{

        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));

        Scene scene = new Scene(root, 850.0, 650.0);

        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
import java.net.URL;
import java.util.ResourceBundle;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ComboBox;
import javafx.scene.control.SingleSelectionModel;
import javafx.scene.input.KeyCode;

public class SampleController implements Initializable {

    @FXML private ComboBox<String> cb;

    //Entered random options
    private final ObservableList<String> options = FXCollections.observableArrayList(
            "Aab",
            "Aer",
            "Aeq",
            "Arx",
            "Byad",
            "Csca",
            "Csee",
            "Cfefe",
            "Cead",
            "Defea",
            "Dqeqe",
            "Fefaf",
            "Gert",
            "Wqad",
            "Xsad",
            "Zzz"
            );

    @Override
    public void initialize(URL location, ResourceBundle resources) {

        cb.getItems().addAll(options);

        selectOptionOnKey();
    }

    /* When you press a letter key
    *  this method will search for an option(item) that starts with the input letter key 
    *  and it selects the first occurrence in combo box
    */
    public void selectOptionOnKey() {
        cb.setOnKeyPressed(e -> {
            KeyCode keyCode = e.getCode();

            if (keyCode.isLetterKey()) {
                char key = keyCode.getName().charAt(0);

                SingleSelectionModel<String> cbSelectionModel = cb.getSelectionModel();

                cbSelectionModel.select(0);

                for (int i = 0; i < options.size(); i++) {
                    if(cbSelectionModel.getSelectedItem().charAt(0) == key) {
                        // option which starts with the input letter found -> select it
                        cbSelectionModel.select(i);
                        /* Before exiting the function it would be nice if after the selection,
                           the combo box would auto slide/jump to the option which is selected.
                           I don't know how to do that. */
                        return;
                    }
                    else
                        cbSelectionModel.selectNext();
                }   
            }
        });
    }
}
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="SampleController">
   <children>
      <ComboBox fx:id="cb" layoutX="300.0" layoutY="300.0" prefHeight="25.0" prefWidth="173.0" />
   </children>
</AnchorPane>
import java.net.URL;
导入java.util.ResourceBundle;
导入javafx.collections.FXCollections;
导入javafx.collections.ObservableList;
导入javafx.fxml.fxml;
导入javafx.fxml.Initializable;
导入javafx.scene.control.ComboBox;
导入javafx.scene.control.SingleSelectionModel;
导入javafx.scene.input.KeyCode;
公共类SampleController实现可初始化{
@FXML专用组合框cb;
//输入随机选项
private final ObservableList options=FXCollections.observableArrayList(
“Aab”,
“Aer”,
“Aeq”,
“Arx”,
“拜亚德”,
“欧安会”,
“Csee”,
“Cfefe”,
“消除种族歧视委员会”,
“Defea”,
“DQE”,
“Fefaf”,
“格特”,
“Wqad”,
“Xsad”,
“Zzz”
);
@凌驾
公共void初始化(URL位置、ResourceBundle资源){
cb.getItems().addAll(选项);
选择optiononkey();
}
/*当你按字母键时
*此方法将搜索以输入字母键开头的选项(项)
*并选择组合框中的第一个匹配项
*/
public void selectOptionOnKey(){
cb.按下设置键(e->{
KeyCode KeyCode=e.getCode();
if(keyCode.isleterkey()){
char key=keyCode.getName().charAt(0);
SingleSelectionModel cbSelectionModel=cb.getSelectionModel();
cbSelectionModel.select(0);
对于(int i=0;i选择它
cbSelectionModel.选择(i);
/*在退出功能之前,如果在选择之后,
组合框将自动滑动/跳转到选定的选项。
我不知道怎么做*/
返回;
}
其他的
cbSelectionModel.selectNext();
}   
}
});
}
}
FXML:

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{

        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));

        Scene scene = new Scene(root, 850.0, 650.0);

        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
import java.net.URL;
import java.util.ResourceBundle;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ComboBox;
import javafx.scene.control.SingleSelectionModel;
import javafx.scene.input.KeyCode;

public class SampleController implements Initializable {

    @FXML private ComboBox<String> cb;

    //Entered random options
    private final ObservableList<String> options = FXCollections.observableArrayList(
            "Aab",
            "Aer",
            "Aeq",
            "Arx",
            "Byad",
            "Csca",
            "Csee",
            "Cfefe",
            "Cead",
            "Defea",
            "Dqeqe",
            "Fefaf",
            "Gert",
            "Wqad",
            "Xsad",
            "Zzz"
            );

    @Override
    public void initialize(URL location, ResourceBundle resources) {

        cb.getItems().addAll(options);

        selectOptionOnKey();
    }

    /* When you press a letter key
    *  this method will search for an option(item) that starts with the input letter key 
    *  and it selects the first occurrence in combo box
    */
    public void selectOptionOnKey() {
        cb.setOnKeyPressed(e -> {
            KeyCode keyCode = e.getCode();

            if (keyCode.isLetterKey()) {
                char key = keyCode.getName().charAt(0);

                SingleSelectionModel<String> cbSelectionModel = cb.getSelectionModel();

                cbSelectionModel.select(0);

                for (int i = 0; i < options.size(); i++) {
                    if(cbSelectionModel.getSelectedItem().charAt(0) == key) {
                        // option which starts with the input letter found -> select it
                        cbSelectionModel.select(i);
                        /* Before exiting the function it would be nice if after the selection,
                           the combo box would auto slide/jump to the option which is selected.
                           I don't know how to do that. */
                        return;
                    }
                    else
                        cbSelectionModel.selectNext();
                }   
            }
        });
    }
}
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="SampleController">
   <children>
      <ComboBox fx:id="cb" layoutX="300.0" layoutY="300.0" prefHeight="25.0" prefWidth="173.0" />
   </children>
</AnchorPane>


非常感谢您的帮助。

作为一般行为,虚拟控件中的选择不会将所选索引/项目滚动到可见区域。有点惊讶的是,组合框下拉列表中的列表也不例外,这条规则应该在打开时选择的列表中是可见的

解决方法是在代码中滚动新选择的项目。这包括:

  • 抓住组合框的皮肤
  • 通过
    skin.getPopupContent()
    获取listView:虽然该方法是公共的,但其返回类型是一个实现细节
  • 调用
    列表。滚动到(索引)
只要选择发生更改,就可以调用代码段,即密钥处理程序中的f.i.:

cbSelectionModel.select(i);
ComboBoxListViewSkin<?> skin = (ComboBoxListViewSkin<?>) cb.getSkin();
ListView<?> list = (ListView<?>) skin.getPopupContent();
list.scrollTo(i);
cbSelectionModel.选择(i);
ComboBoxListViewSkin=(ComboBoxListViewSkin)cb.getSkin();
ListView列表=(ListView)skin.getPopupContent();
列表。滚动至(i);

请提供一个示例来说明问题。正如你在前面的问题中已经提出的那样。。现在就做-如果没有它,它是不可回答的(在你非常私人的环境中,有很多事情可能会出错,无法知道它是什么)好的,现在我明白你的意思了,谢谢你的例子:)嗯。。可能是个bug,也可能不是:导航键确实会触发滚动,但选择通常不会触发滚动(即使在打开之前选择了,这也是我最不希望看到的)。需要挖一点。。