2016-10-22 3 views
1

私はenumに基づいて関数を変更するようにアプリケーションを設定しました。この列挙型にリンクされた変数の値は、プログラムがマウスクリックなどの特定のアクションをどのように解釈するかを決定します。アプリケーションの現在の「モード」が何であるかを反映するラベル(おそらく左下のステータス領域)を表示し、ユーザーに表示するための読み取り可能なメッセージを表示します。列挙型のtoString()をラベルにバインド

はここに私の列挙です:

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()プロパティをバインドする方法ですラベル。私はleftStatus.setText(applicationState.toString())私はそれを行うたびに配置しなくても、私は

applicationState = Mode.alternativeMode; 

ラベルが自動的にtoString()結果を表示するようなものを設定するときは常にそうということでしょうバインディング。 (私のメインのコントローラクラスで):最初のテキストにラベルを設定します

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

を、私はapplicationState列挙型を更新したときに更新されません

は、ここで私が試したものです。

私は間違っていますか?

答えて

2

enumクラスにプロパティを追加する代わりに、アプリケーションの状態に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; 
     } 
    } 

} 
+0

これは素晴らしい答えであり、私が必要とするものです。将来これに遭遇する可能性がある人のために、最後に.get()を追加するためにswitch文を調整しなければならないと付け加えたいかもしれません。他のすべては完璧に動作します。私はあなたの答えの両方をありがとう、私はそれが最もエレガントで簡単に実装するため、この1つを最高として選択します。 – Prester

1

使用asStringは、オブジェクトのtoStringメソッドを使用してStringに変換プロパティの値を含むProperty<Mode>からStringBindingを取得します。

例:あなたが列挙型に含まれるプロパティ値をしたい場合

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

そうでない場合は、あなたが命名規則を遵守するためにあなたがpropertyProperty()getProperty()メソッドの名前を変更して、Bindings.selectStringを使用することができます。

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

、そこで私は、バインド可能なプロパティを提供してはならない、(http://stackoverflow.com/q/540293/3429133)[列挙型はステートレスでなければなりません]と思います。 – beatngu13