2016-04-08 15 views
1

私はそれを働かせるように助けてください。シーンを変更する代わりにフリーズします。 ボタンがこのように作成されたときにそれが正常に動作します:Javafx関数を介してボタンを作成する方法は?

Button b1 = new Button("Go to s2"); 
b1.setOnAction(e -> window.setScene(s2)); 
Button b2 = new Button("Go to s1"); 
b2.setOnAction(e -> window.setScene(s1)); 

しかし、私はそれがよりエレガントにしたいのですが...

import javafx.application.Application; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.stage.Stage; 

public class Main extends Application { 

    Stage window; 
    Scene s1,s2; 

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

    @Override 
    public void start(Stage primaryStage) throws Exception { 
     window = primaryStage; 

     Button b1 = makeButton("Go to s2", s2); 
     Button b2 = makeButton("Go to s1", s1); 

     s1 = new Scene(b1); 
     s2 = new Scene(b2); 

     primaryStage.setScene(s1); 
     primaryStage.show(); 
    } 

    public Button makeButton(String name, Scene destScene) { 
     Button button = new Button(name); 
     button.setOnAction(e -> window.setScene(destScene)); 
     return button; 
    } 
} 

は事前にどうもありがとうございました!すべてが初期化されている方法のための順序で

答えて

1

ルック:あなたはmakeButtonを呼び出すと

Button b1 = makeButton("Go to s2", s2); 
Button b2 = makeButton("Go to s1", s1); 

s1 = new Scene(b1); 
s2 = new Scene(b2); 

、現在s1s2に格納されている基準の値を渡します。初期化されていないので、デフォルト値はnullです。これは、コピーされた参照のために、s1s2の文字セットを変更しても変更されません。

s1s2のコピーを作成しないため、最初のケースで同じ問題は発生しません。代わりに、EventHandlerは現在のインスタンスMainのフィールドを参照しています。このフィールドは、一度設定すると正しく更新されます。だからあなたの元のコードは、これと同等のものである:

Button b1 = new Button("Go to s2"); 
b1.setOnAction(e -> window.setScene(this.s2)); 

だから囲むMainインスタンスへの参照ではなく、ボタン自体への参照をコピーしています。

残念なことに、私はそれのための簡単な修正が表示されません。あなたが望むよう

Button b1 = makeButton("Go to s2", e -> window.setScene(s2)); 

として良くないが、それが動作するはずです:私が見る最も簡単な解決策はmakeButton(String, EventHandler<ActionEvent>)にあなたの関数を変更し、このようにそれを呼び出すことであろう。

もう1つの考えられる解決方法は、Buttonをすべて配列に入れてから、その配列にインデックスをmakeButtonに渡すことです。それはtihsのようになります。

public class Main extends Application { 
    Stage window; 
    Scene[] scenes = new Scene[2]; 

    @Override 
    public void start(Stage primaryStage) throws Exception { 
     window = primaryStage; 

     Button b1 = makeButton("Go to s2", 1); 
     Button b2 = makeButton("Go to s1", 0); 

     scenes[0] = new Scene(b1); 
     scenes[1] = new Scene(b2); 

     primaryStage.setScene(scenes[0]); 
     primaryStage.show(); 
    } 

    public Button makeButton(String name, int destScene) { 
     Button button = new Button(name); 
     button.setOnAction(e -> window.setScene(scenes[destScene])); 
     return button; 
    } 
} 

Mainのフィールド(scenes)ではなく、ローカル変数(destScene)を参照しEventHandlerを変更すること。