There are different ways to solve this problem. I have listed three of the solutions below. You can use any one of the below solutions which you feel is apt for your scenario.
Using a custom class
Create a custom class KeyValuePair
, for storing the string and its corresponding value. Exposed the getters for the required fields.
Later, I have used the setCellFactory()
of the comboxbox to show the required data. Use StringConverter to show the key in place of the object.
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.util.StringConverter;
public class Main extends Application {
@Override
public void start(Stage stage) throws Exception
{
KeyValuePair keyValuePair1 = new KeyValuePair("Active", 0);
KeyValuePair keyValuePair2 = new KeyValuePair("Blocked", 1);
ObservableList<KeyValuePair> options = FXCollections.observableArrayList();
options.addAll(keyValuePair1, keyValuePair2);
ComboBox<KeyValuePair> comboBox = new ComboBox<>(options);
// show the correct text
comboBox.setCellFactory((ListView<KeyValuePair> param) -> {
final ListCell<KeyValuePair> cell = new ListCell<KeyValuePair>(){
@Override
protected void updateItem(KeyValuePair t, boolean bln) {
super.updateItem(t, bln);
if(t != null){
setText(String.valueOf(t.getKey()));
}else{
setText(null);
}
}
};
return cell;
});
comboBox.setConverter(new StringConverter<KeyValuePair>() {
@Override
public String toString(KeyValuePair object) {
return object.getKey();
}
@Override
public KeyValuePair fromString(String string) {
return null; // No conversion fromString needed.
}
});
// print the value
comboBox.valueProperty().addListener((ov, oldVal, newVal) -> {
System.out.println(newVal.getKey() + " - " + newVal.getValue());
});
BorderPane bp = new BorderPane(comboBox);
bp.setPrefSize(800, 800);
Scene scene = new Scene(bp);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
class KeyValuePair {
private final String key;
private final int value;
public KeyValuePair(String key, int value) {
this.key = key;
this.value = value;
}
public String getKey() {
return key;
}
public int getValue() {
return value;
}
}
}
Without using an extra class
As suggested by @kleopatra, you can even do this without using an extra class.
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.util.StringConverter;
public class Main extends Application {
@Override
public void start(Stage stage) throws Exception {
ObservableList<Integer> options = FXCollections.observableArrayList();
options.addAll(1, 0);
ComboBox<Integer> comboBox = new ComboBox<>(options);
// show the correct text
comboBox.setCellFactory((ListView<Integer> param) -> {
final ListCell<Integer> cell = new ListCell<Integer>(){
@Override
protected void updateItem(Integer t, boolean bln) {
super.updateItem(t, bln);
if(t != null){
setText(t == 1 ? "Active" : "Blocked");
}else{
setText(null);
}
}
};
return cell;
});
comboBox.setConverter(new StringConverter<Integer>() {
@Override
public String toString(Integer object) {
return object == 1 ? "Active" : "Blocked";
}
@Override
public Integer fromString(String string) {
return null;
}
});
// print the value
comboBox.valueProperty().addListener((ov, oldVal, newVal) -> {
System.out.println("Changed from " + oldVal + " to " + newVal);
});
BorderPane bp = new BorderPane(comboBox);
bp.setPrefSize(800, 800);
Scene scene = new Scene(bp);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Using Bindings
You can also use Bindings if you don't want to take the pain of creating a new class and you will always have two elements i.e. Active and Blocked.
Just bind the valueProperty() of your combobox to the state, which is supposed to store the value i.e. 0 or 1.
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage stage) throws Exception {
IntegerProperty state = new SimpleIntegerProperty();
ObservableList options = FXCollections.observableArrayList("Active", "Blocked");
ComboBox<String> comboBox = new ComboBox<>(options);
state.bind(Bindings.when(comboBox.valueProperty().isEqualTo("Active")).then(0).otherwise(1));
BorderPane bp = new BorderPane(comboBox);
bp.setPrefSize(800, 800);
Scene scene = new Scene(bp);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
enum
? – James_D