Javafx 绑定枚举';s toString()到标签

Javafx 绑定枚举';s toString()到标签,javafx,binding,enums,label,Javafx,Binding,Enums,Label,我已将应用程序设置为基于枚举更改其功能。链接到此枚举的变量的值将决定程序如何解释某些操作,如鼠标单击等。我想要一个标签(可能在左下角的状态区域中)来反映应用程序当前的“模式”,并显示一条可读的消息供用户查看 这是我的枚举: enum Mode { defaultMode, // Example states that will determine alternativeMode; // how the program interprets mouse clicks

我已将应用程序设置为基于枚举更改其功能。链接到此枚举的变量的值将决定程序如何解释某些操作,如鼠标单击等。我想要一个标签(可能在左下角的状态区域中)来反映应用程序当前的“模式”,并显示一条可读的消息供用户查看

这是我的枚举:

enum Mode {
    defaultMode,     // Example states that will determine
    alternativeMode; // how the program interprets mouse clicks

    // My attempt at making a property that a label could bind to
    private SimpleStringProperty property = new SimpleStringProperty(this, "myEnumProp", "Initial Text");
    public SimpleStringProperty getProperty() {return property;}

    // Override of the toString() method to display prettier text
    @Override
    public String toString()
    {
        switch(this) {
            case defaultMode:
                return "Default mode";
            default:
                return "Alternative mode";
        }
    }
}
根据我收集的信息,我正在寻找一种将枚举的toString()属性(我将其转换为更易于消化的形式)绑定到此标签的方法。装订是这样的,每当我设置

applicationState = Mode.alternativeMode;
标签将自动显示
toString()
结果,而无需每次都放置
leftStatus.setText(applicationState.toString())

以下是我尝试过的:(在我的主控制器类中):

它将标签设置为初始文本,但在更新
applicationState
enum时不会更新

我做错了什么?

使用对象的
toString
方法从
属性
获取一个
StringBinding
,该属性包含转换为
String
的属性值

例如:

@Override
public void start(Stage primaryStage) {
    ComboBox<Mode> combo = new ComboBox<>();
    combo.getItems().setAll(Mode.values());
    Label label = new Label();

    // use "state" property from combo box
    // (you could replace combo.valueProperty() with your own property)
    label.textProperty().bind(combo.valueProperty().asString());

    Scene scene = new Scene(new VBox(combo, label), 200, 200);

    primaryStage.setScene(scene);
    primaryStage.show();
}
private final Random Random=new Random();
@凌驾
公共无效开始(阶段primaryStage){
ComboBox combo=新ComboBox();
combo.getItems().setAll(Mode.values());
标签=新标签();
//使用组合框中的“状态”属性
//(您可以用自己的属性替换combo.valueProperty())
label.textProperty().bind(Bindings.selectString(combo.valueProperty(),“property”);
场景=新场景(新VBox(组合,标签),200200);
scene.setOnMouseClicked(evt->{
//随机更改属性值
Mode.defaultMode.propertyProperty().set(random.nextBoolean()?“a”:“b”);
Mode.alternativeMode.propertyProperty().set(random.nextBoolean()?“c”:“d”);
});
初级阶段。场景(场景);
primaryStage.show();
}

为什么不为应用程序状态使用属性,而不是向enum类添加属性?看看这个:

导入javafx.application.application;
导入javafx.beans.property.ObjectProperty;
导入javafx.beans.property.SimpleObject属性;
导入javafx.scene.scene;
导入javafx.scene.control.Button;
导入javafx.scene.control.Label;
导入javafx.scene.layout.FlowPane;
导入javafx.stage.stage;
公共类示例扩展了应用程序{
private ObjectProperty appState=新的SimpleObjectProperty(Mode.DEFAULT);
公共静态void main(字符串[]args){
发射(args);
}
@凌驾
public void start(Stage primaryStage)引发异常{
按钮btn=新按钮(“切换模式”);
btn.setOnMouseClicked((事件)->appState.setValue(appState.get()==Mode.DEFAULT?Mode.ALTERNATIVE:Mode.DEFAULT));
标签lbl=新标签();
lbl.textProperty().bind(appState.asString());
FlowPane=新的FlowPane();
pane.getChildren().addAll(btn,lbl);
初始阶段。设置场景(新场景(窗格));
primaryStage.show();
}
公共枚举模式{
默认(“默认模式”),
替代(“替代模式”);
私有字符串描述;
专用模式(字符串描述){
this.description=描述;
}
@凌驾
公共字符串toString(){
返回说明;
}
}
}

我个人认为,因此不应该提供可绑定属性。这是一个非常好的答案,也是我所需要的。对于任何未来可能会偶然发现这一点的人,我可能会补充说,我必须调整我的switch语句(当我检查处于哪种模式时),以便在最后添加.get()。其他一切都完美无瑕。谢谢你们的回答,我会选择这一个作为最好的,因为它是最优雅和易于实现的。
@Override
public void start(Stage primaryStage) {
    ComboBox<Mode> combo = new ComboBox<>();
    combo.getItems().setAll(Mode.values());
    Label label = new Label();

    // use "state" property from combo box
    // (you could replace combo.valueProperty() with your own property)
    label.textProperty().bind(combo.valueProperty().asString());

    Scene scene = new Scene(new VBox(combo, label), 200, 200);

    primaryStage.setScene(scene);
    primaryStage.show();
}
enum Mode {
    ...

    public StringProperty propertyProperty() {return property;}
    ...
}
private final Random random = new Random();

@Override
public void start(Stage primaryStage) {
    ComboBox<Mode> combo = new ComboBox<>();
    combo.getItems().setAll(Mode.values());
    Label label = new Label();

    // use "state" property from combo box
    // (you could replace combo.valueProperty() with your own property)
    label.textProperty().bind(Bindings.selectString(combo.valueProperty(), "property"));

    Scene scene = new Scene(new VBox(combo, label), 200, 200);
    scene.setOnMouseClicked(evt -> {
        // change property values at random
        Mode.defaultMode.propertyProperty().set(random.nextBoolean() ? "a" : "b");
        Mode.alternativeMode.propertyProperty().set(random.nextBoolean() ? "c" : "d");
    });

    primaryStage.setScene(scene);
    primaryStage.show();
}
import javafx.application.Application;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.FlowPane;
import javafx.stage.Stage;

public class Example extends Application {

    private ObjectProperty<Mode> appState = new SimpleObjectProperty<>(Mode.DEFAULT);

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

    @Override
    public void start(Stage primaryStage) throws Exception {
        Button btn = new Button("Toggle mode");
        btn.setOnMouseClicked((event) -> appState.setValue(appState.get() == Mode.DEFAULT ? Mode.ALTERNATIVE : Mode.DEFAULT));

        Label lbl = new Label();
        lbl.textProperty().bind(appState.asString());

        FlowPane pane = new FlowPane();
        pane.getChildren().addAll(btn, lbl);

        primaryStage.setScene(new Scene(pane));
        primaryStage.show();
    }

    public enum Mode {
        DEFAULT("Default mode"),
        ALTERNATIVE("Alternative mode");

        private String description;

        private Mode(String description) {
            this.description = description;
        }

        @Override
        public String toString() {
            return description;
        }
    }

}