将枚举的toString()绑定到标签

时间:2016-10-22 00:49:22

标签: javafx binding enums label

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

这是我的枚举:

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())

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

leftStatus.textProperty().bind(applicationState.getProperty());

将标签设置为初始文本,但在更新applicationState枚举时不会更新。

我做错了什么?

2 个答案:

答案 0 :(得分:3)

为什么不将ObjectProperty用于应用程序状态,而不是向枚举类添加属性?看看这个MCVE

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

}

答案 1 :(得分:1)

使用asStringStringBinding获取Property<Mode>,其中包含使用对象String方法转换为toString的属性值

示例:

@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();
}

否则,如果您想要枚举中包含的属性值,则可以使用Bindings.selectString,前提是将getProperty()方法重命名为propertyProperty()以符合命名约定:

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();
}