如何将JavaFX ComboBox的滚动条重置回顶部?

时间:2019-09-10 19:29:32

标签: javafx combobox scrollbar

我有一个ComboBox,上面装有一个长的ObservableList,因此它具有滚动条。如果我进行选择,请在ComboBox列表的底部说,然后单击CLEAR按钮,我希望ComboBox没有选择并且滚动条重置到顶部。我似乎无法使滚动条回到顶部。有人可以告诉我我在做什么错吗?

ComboBoxView.fxml:

<?xml version="1.0" encoding="UTF-8"?>

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


<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="70.0" prefWidth="154.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="comboboxscroll.ComboBoxViewController">
   <children>
      <ComboBox fx:id="myCB" prefWidth="150.0" />
      <Button layoutX="51.0" layoutY="35.0" mnemonicParsing="false" onAction="#clearCB" text="CLEAR" />
   </children>
</AnchorPane>

ComboBoxViewController.java:

package comboboxscroll;

import java.net.URL;
import java.util.ResourceBundle;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ComboBox;

public class ComboBoxViewController implements Initializable
{
    @FXML
    private ComboBox<String> myCB;

    @Override
    public void initialize(URL url, ResourceBundle rb)
    {
        ObservableList<String> myList = FXCollections.observableArrayList("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P");
        myCB.getItems().clear();
        myCB.setItems(myList);
    }

    @FXML
    private void clearCB(ActionEvent event)
    {
        myCB.getSelectionModel().clearSelection();

        // I thought this would position the scrollbar back to the top but it doesn't
        myCB.setValue(null);
    }
}

ComboBoxScroll.java:

package comboboxscroll;

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

public class ComboBoxScroll extends Application {

    @Override
    public void start(Stage stage) throws Exception
    {
        try
        {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("ComboBoxView.fxml"));
            Scene scene = new Scene((Parent) loader.load());
            stage.setScene(scene);
            stage.setTitle("ComboBox Scroll Test");
            stage.show();
        }
        catch (IOException ignored)
        {
        }
    }

    public static void main(String[] args)
    {
        launch(args);
    }
}

2 个答案:

答案 0 :(得分:2)

ComboBox本身没有api来滚动其列表,但是弹出窗口中显示的ListView可以(尽管默认情况下,它不执行任何操作以将所选项目滚动到可见区域):基本上,您必须像< / p>

listView.scrollTo(comboBox.getSelectionModel().getSelectedIndex())

这样做的一个好位置是comboBox中的onShowing处理程序-那时,保证listView可以实例化(在comboBox的皮肤中完成)并可以访问(通过comboBoxSkin)。

一个小例子:

public class ComboBoxScroll extends Application {

    int count;
    private Parent createContent() {
        List<String> data = Stream.generate(() -> "item " + count++).limit(30).collect(toList());
        ComboBox<String> combo = new ComboBox<>(observableArrayList(data));

        // scroll just before the comboBox is showing
        combo.setOnShowing(e -> {
            // Beware: type of skin is an implementation detail!
            ListView list = (ListView) ((ComboBoxListViewSkin) combo.getSkin()).getPopupContent();
            list.scrollTo(Math.max(0, combo.getSelectionModel().getSelectedIndex()));
        });

        // to see the handler working initially
        combo.getSelectionModel().select(25);
        // a button to clear see the handler working on clearing selection
        Button clear = new Button("clear selection");
        clear.setOnAction(e -> combo.getSelectionModel().clearSelection());
        BorderPane content = new BorderPane(combo);
        content.setBottom(new HBox(10, clear));
        return content;
    }

    @Override
    public void start(Stage stage) throws Exception {
        stage.setScene(new Scene(createContent()));
        //stage.setTitle(FXUtils.version());
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

答案 1 :(得分:1)

不幸的是,JavaFX ComboBox组件阻止您直接使用滚动条。您只能管理三个相关事件(onScrollonScrollStartedonScrollFinished),但是在这里没有用。