将枚举的 toString() 绑定到标签
Binding an enum's toString() to a Label
我已将我的应用程序设置为根据枚举更改其功能。链接到此枚举的变量值将决定程序如何解释某些操作,如鼠标点击等。我想要一个标签(可能在左下角的状态区域)来反映当前 "mode" 应用程序所在的位置,并显示一条可读消息供用户查看。
这是我的枚举:
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())
。
这是我尝试过的:(在我的主控制器中 class):
leftStatus.textProperty().bind(applicationState.getProperty());
将标签设置为初始文本,但在我更新 applicationState
枚举时不会更新。
我做错了什么?
使用 asString
从包含 属性 的值的 Property<Mode>
获取 StringBinding
使用对象的 [=17= 转换为 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();
}
否则,如果您想要 属性 值包含在枚举中,您可以使用 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();
}
与其将 属性 添加到枚举 class,不如使用 ObjectProperty
for the application state? Have a look at this 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;
}
}
}
我已将我的应用程序设置为根据枚举更改其功能。链接到此枚举的变量值将决定程序如何解释某些操作,如鼠标点击等。我想要一个标签(可能在左下角的状态区域)来反映当前 "mode" 应用程序所在的位置,并显示一条可读消息供用户查看。
这是我的枚举:
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())
。
这是我尝试过的:(在我的主控制器中 class):
leftStatus.textProperty().bind(applicationState.getProperty());
将标签设置为初始文本,但在我更新 applicationState
枚举时不会更新。
我做错了什么?
使用 asString
从包含 属性 的值的 Property<Mode>
获取 StringBinding
使用对象的 [=17= 转换为 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();
}
否则,如果您想要 属性 值包含在枚举中,您可以使用 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();
}
与其将 属性 添加到枚举 class,不如使用 ObjectProperty
for the application state? Have a look at this 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;
}
}
}