【问题标题】:JavaFX: Make comboBox cell to change disable state dynamicallyJavaFX:使组合框单元格动态更改禁用状态
【发布时间】:2018-11-22 09:25:42
【问题描述】:

除了第一项之外,组合框的所有项最初都是禁用的(我使用setCellFactory 来完成此操作)。

如果我点击选项0,我希望它解锁选项1等等。

我尝试在组合框侦听器中使用一些布尔变量,但似乎 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 ;
}

【问题讨论】:

  • 最好创建一些对象。
  • 看起来怎么样,你能给我举个例子吗?
  • 给我一秒钟。

标签: javafx combobox


【解决方案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);
    }
}

自定义编号

/*
 * 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;
    }


}

【讨论】:

  • 一个问题:代码box.setCellFactory...是否等同于您的“Callback
  • 它们是一回事。只是两种不同的方式。
猜你喜欢
  • 1970-01-01
  • 2018-03-25
  • 2015-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-06
相关资源
最近更新 更多