JavaFX组合框无限地调用listcell.updateitem

时间:2018-04-19 21:22:48

标签: java javafx view combobox

我正在尝试制作一个包含大量项目(超过10000个)的组合框。它初始化没有问题。但是当我点击它时,它就冻结了。为了调试我创建了自己的listCell并遵循updateitem函数。当我点击它时,它无限地调用updateitem。难道它不仅仅更新可见项目吗?这是一个示例控制器:

   package sample;

import javafx.fxml.FXML;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;


public class Controller {
    @FXML
    ComboBox comboBox1;

    public final class ExampleCell<T> extends ListCell<T> {

        Label myLabel;

        @Override
        protected void updateItem(T item, boolean empty) {
            super.updateItem(item,empty);
            System.out.println("update");
            if (empty) {
                setGraphic(null);
            } else {
                if(myLabel==null){
                    myLabel=new Label((String)item);

                }else{
                    myLabel.setText((String)item);}
                setGraphic(myLabel);
            }
        }
    }
    public void initialize(){

    for(int i =0;i<10000;i++){
        comboBox1.getItems().add("example");
    }
    comboBox1.setCellFactory(param -> new ExampleCell<>());
   }
}

我的fxml

<?import javafx.scene.layout.GridPane?>

<?import javafx.scene.control.ComboBox?>
<GridPane fx:controller="sample.Controller"
          prefWidth="500"
          prefHeight="500"
          xmlns:fx="http://javafx.com/fxml" alignment="center" hgap="10" vgap="10">
    <ComboBox
            fx:id="comboBox1"
    />
</GridPane>

1 个答案:

答案 0 :(得分:1)

原因确实是测量所有细胞的pref宽度,如(不公开!)记录在ComboBoxListViewSkin中:

// By default we measure the width of all cells in the ListView. If this
// is too burdensome, the developer may set a property in the ComboBox
// properties map with this key to specify the number of rows to measure.
// This may one day become a property on the ComboBox itself.
private static final String COMBO_BOX_ROWS_TO_MEASURE_WIDTH_KEY = "comboBoxRowsToMeasureWidth";

出路是限制应该测量的行数 - 不能保证,因为没有公共文档根本没有规范:

comboBox1.getProperties().put("comboBoxRowsToMeasureWidth", 10);

最初仍然调用updateItem,这至少是测量(填充和释放)期间给定限制的两倍加上设置实际值的一次。