JavaFX:使comboBox单元格动态更改禁用状态

时间:2018-06-12 21:51:31

标签: javafx combobox

除第一项外,最初禁用了comboBox的所有项目(我使用setCellFactory来完成此操作。)

如果我点击0选项,我希望它能解锁选项1,依此类推。

我试图在comboBox Listener中使用一些布尔变量,但似乎setCellFactory只被调用一次。这是对的吗?

如果是这样,我怎么能实现我想要的呢?

以下的SSCCE改编自here

Main.java

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.stage.Stage;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ListCell;


public class Main extends Application {
    boolean isZeroLocked = false;
    boolean isOneLocked = true;
    boolean isTwoLocked = true;
    boolean isThreeLocked = true;

    @Override
    public void start(Stage stage) throws Exception {
        ComboBox<Integer> box = new ComboBox<Integer>();
        ObservableList<Integer> values = FXCollections.observableArrayList(0,1,2,3);
        box.setItems(values);

        box.getSelectionModel().selectedIndexProperty().addListener((observable,oldValue,newValue)->{
            System.out.println(newValue + " was clicked. The next option will be unlocked.");
            if(newValue.intValue() == 0)
                isOneLocked = false;
            if(newValue.intValue() == 1)
                isTwoLocked = false;
            if(newValue.intValue() == 2)
                isThreeLocked = false;
        });

        box.setCellFactory(lv -> new ListCell<Integer>() {
            @Override
            public void updateItem(Integer item, boolean empty) {
                super.updateItem(item, empty);
                if (empty) {
                    setText(null);
                } else {
                    setText(item.toString());

                    if(item.intValue() == 0)
                        setDisable(isZeroLocked);
                    if(item.intValue() == 1)
                        setDisable(isOneLocked);
                    if(item.intValue() == 2)
                        setDisable(isTwoLocked);
                    if(item.intValue() == 3)
                        setDisable(isThreeLocked);
                }
            }
        });
        Scene scene = new Scene(new Group(box));
        scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
        stage.setScene(scene);
        stage.show();
    }

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

application.css

.combo-box-popup .list-cell:disabled  {
    -fx-opacity: 0.4 ;
}

1 个答案:

答案 0 :(得分:1)

我创建了一个名为CustomNumber的对象来跟上disabled属性。

  

密码:

此代码设置ComboBox的文本并启用其单元格。

Callback<ListView<CustomNumber>, ListCell<CustomNumber>> factory = lv -> new ListCell<CustomNumber>() {
    @Override
    protected void updateItem(CustomNumber item, boolean empty) {
        super.updateItem(item, empty);
        if (empty) {
            setText(null);
        } else {
            System.out.println(item.getNum());
            setText(Integer.toString(item.getNum()));                   
            setDisable(item.isDisable());
        }
    }
};  

此代码获取单击的单元格下方的单元格并更新其禁用属性

box.getSelectionModel().selectedIndexProperty().addListener((observable,oldValue,newValue)->{            
    if(newValue.intValue() + 1 < box.getItems().size())
    {
        CustomNumber tempCustomNumber = (CustomNumber)box.getItems().get(newValue.intValue() + 1);
        tempCustomNumber.setDisable(false);
        System.out.println(tempCustomNumber.getNum() + " " + tempCustomNumber.isDisable() + " was unlocked.");
        box.getItems().set(newValue.intValue() + 1, tempCustomNumber);
    }
});
  

完整代码:

import java.util.ArrayList;
import java.util.List;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.stage.Stage;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.util.Callback;


public class Main extends Application {

    @Override
    public void start(Stage stage) throws Exception {
        ComboBox<CustomNumber> box = new ComboBox();
        List<CustomNumber> customNumbers = new ArrayList();
        customNumbers.add(new CustomNumber(0, false));
        customNumbers.add(new CustomNumber(1, true));
        customNumbers.add(new CustomNumber(2, true));
        customNumbers.add(new CustomNumber(3, true));
        ObservableList<CustomNumber> values = FXCollections.observableArrayList(customNumbers);

        box.setItems(values);

        Callback<ListView<CustomNumber>, ListCell<CustomNumber>> factory = lv -> new ListCell<CustomNumber>() {
            @Override
            protected void updateItem(CustomNumber item, boolean empty) {
                super.updateItem(item, empty);
                if (empty) {
                    setText(null);
                } else {
                    System.out.println(item.getNum());
                    setText(Integer.toString(item.getNum()));                   
                    setDisable(item.isDisable());
                }
            }
        };

        box.setCellFactory(factory);
        box.setButtonCell(factory.call(null));
        box.getSelectionModel().selectedIndexProperty().addListener((observable,oldValue,newValue)->{            
            if(newValue.intValue() + 1 < box.getItems().size())
            {
                CustomNumber tempCustomNumber = (CustomNumber)box.getItems().get(newValue.intValue() + 1);
                tempCustomNumber.setDisable(false);
                System.out.println(tempCustomNumber.getNum() + " " + tempCustomNumber.isDisable() + " was unlocked.");
                box.getItems().set(newValue.intValue() + 1, tempCustomNumber);
            }
        });

        Scene scene = new Scene(new Group(box));
        scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
        stage.setScene(scene);
        stage.show();
    }

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

<强> CustomNumber

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package javafxapplication9;

/**
 *
 * @author sedrick
 */
public class CustomNumber {
    private int num;
    private boolean disable;

    public CustomNumber(int num, boolean disable) {
        this.num = num;
        this.disable = disable;
    }

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }

    public boolean isDisable() {
        return disable;
    }

    public void setDisable(boolean isDisable) {
        this.disable = isDisable;
    }


}