2016-10-07 4 views
0

JavaFXアプリケーションを構築中で、JavaFX UI内で引数として渡された値にアクセスする必要があります。何らかの理由で、基本メソッドlaunchForm以外のすべてのメソッドでこれらの値にアクセスできません。私のコードは次のようになります。JavaFXメソッドでパラメータを使用する

public class FormBuilder extends Application { 

    /* 
    * (non-Javadoc) 
    * @see javafx.application.Application#start(javafx.stage.Stage) 
    * Scene scene 
    *  Group root 
    *   BorderPane borderPane 
    *    TabPane tabPane 
    *     Tab stocksTab 
    *      BorderPane stockTabBorderPane 
    *       GridPane gridPane 
    *   
    */ 

    private Stocks stockData = new Stocks(); 
    private int size; 

    @Override 
    public void start(Stage stage) throws Exception { 
     stage.setTitle("Stock Manager"); 
     Group root = new Group(); 
     Scene scene = new Scene(root, 1024, 800, Color.WHITE); 

     TabPane tabPane = new TabPane(); 
     BorderPane borderPane = new BorderPane(); 
     BorderPane stockTabBorderPane = new BorderPane(); 

     Tab stocksTab = new Tab("Stocks"); 

     stockTabBorderPane.setTop(this.addHBox()); 
     stockTabBorderPane.setCenter(this.createGridPane()); 

     stocksTab.setContent(stockTabBorderPane); 
     tabPane.getTabs().add(stocksTab); 

     borderPane.setCenter(tabPane); 

     borderPane.prefHeightProperty().bind(scene.heightProperty()); 
     borderPane.prefWidthProperty().bind(scene.widthProperty()); 

     root.getChildren().add(borderPane); 


     stage.setScene(scene); 
     stage.show(); 


    } 

    private HBox addHBox() { 
     HBox hbox = new HBox(); 
     hbox.setPadding(new Insets(15, 12, 15, 12)); 
     hbox.setSpacing(10); 
     hbox.setStyle("-fx-background-color: #336699;"); 

     Button buttonCurrent = new Button("Current"); 
     buttonCurrent.setPrefSize(100, 20); 

     Button buttonProjected = new Button("Projected"); 
     buttonProjected.setPrefSize(100, 20); 
     hbox.getChildren().addAll(buttonCurrent, buttonProjected); 

     return hbox; 
    } 

    private GridPane createGridPane() { 

     GridPane gridPane = new GridPane(); 

     gridPane.setLayoutX(39); 
     gridPane.setLayoutY(131.0); 
     gridPane.setAlignment(Pos.TOP_CENTER); 
     gridPane.setVgap(5.0); 
     gridPane.setHgap(10.0); 

     gridPane.add(new Label("Active"), 1,1); 
     gridPane.add(new Label("Stock"), 2, 1); 
     gridPane.add(new Label("Symbol"), 3, 1); 
     gridPane.add(new Label("LPP"), 4, 1); 
     gridPane.add(new Label("LPP"), 5, 1); 
     gridPane.add(new Label("HPP"), 6, 1); 
     gridPane.add(new Label("LTP"), 7, 1); 

     System.out.println(this.size); 
     for(int v=2;v < this.stockData.getStocks().size()+2; v++) { 
      gridPane.add(new CheckBox(), 1, v); 
      gridPane.add(new Label("Amazon"), 2, v); 
      gridPane.add(new TextField(), 3,v); 
      gridPane.add(new TextField(), 4,v); 
      gridPane.add(new TextField(), 5,v); 
      gridPane.add(new TextField(), 6,v); 
      gridPane.add(new TextField(), 7,v); 

     } 

     return gridPane; 
    } 

    public void launchForm(Stocks stockData) { 
     this.stockData = stockData; 
     this.size = stockData.getStocks().size(); 
     System.out.println(stockData.getStocks().size()); 
     System.out.println(stockData.getStocks().get(0).getSector()); 
     launch(); 
    } 
} 

今の問題は、私がしようとcreateGridPaneメソッド内stockDataオブジェクトの下に任意の値にアクセスすると、値が利用できないということです。

としては

this.stockData.getStocks().size()あるcreateGridPane方法における0の値を与えます。しかし、launchFormメソッドでは2の値を与えます。

再びlaunchForm方法で値"Retail"を返し

this.stockData.getStocks().get(0).getSector() 

のような他の値が存在します。しかし、同じクラスの別のメソッドで同じメソッドにアクセスしようとすると、例外が発生します。

誰かが私を助けてくれますか?

+0

「launchForm」はどこから呼び出していますか?なぜそのメソッドの中から 'launch()'を呼び出すのですか? ['launch()'](http://docs.oracle.com/javase/8/javafx/api/javafx/application/Application.html#launch-java.lang.String-.-)は、アプリケーションを起動します。確かにその時点でアプリケーションは既に開始されています。 JavaFXのライフサイクルを根本的に誤解していたに違いないと思います。['Application' docs](http://docs.oracle.com/javase/8/javafx/api/javafx/application/Application.html) –

+0

私はおそらく、あなたがやっていることや、アプリケーションの構造をどのようにしているのかといったこの質問に、より多くの情報を含める必要があります。 –

答えて

0

JavaFXでは、基本的にApplicationサブクラス、特にそのstart()メソッドをアプリケーションのエントリポイントとみなしてください。アプリケーションのライフサイクルはApplication Javadocsに記載されていますが、簡単に説明すると、静的Application.launch(...)メソッドの1つをコールするか、Oracle JDKを使用してJVMを起動し、サブクラスApplicationをメインクラス(evenそれがmainメソッドを持たない場合)。その後、

起動プロセス:

  1. Applicationサブクラスにinit()を呼び出すApplicationサブクラスの新しいインスタンスを作成しますJavaFXのツールキットを開始し
  2. (デフォルトの実装は何もしません)
  3. FXアプリケーションスレッドを開始します
  4. Applicationサブクラスでstart()を呼び出します。exec FXアプリケーションスレッドでそれを試してみてください。

start()は、異なるスレッドで呼び出されていますが、init()が完了するまで呼び出されないことが保証されています。

投稿したコードから、あなたのFormBuilderクラスを別の場所でインスタンス化し、そのインスタンスでlaunchForm(...)を呼び出す必要があります。そこからlaunch()を呼び出すと、2番目のインスタンスが作成され、前述のようにstart()が呼び出されます。もちろん、launchForm(...)が呼び出されたインスタンスで設定したフィールドは、start(...)が呼び出されたインスタンスには設定されません。

あなたはどちらかFormBuilderは、アプリケーションへのエントリポイントがあるように、あなたのコードをリファクタリング、またはApplicationサブクラスではないFormBuilderを作成し、インスタンス化し、それを使用する新しいエントリポイントを作成する必要があります。データを読み込むバックグラウンドの作業があるように見えます。これはエントリポイントではない別のクラスでなければなりません。だから、最初のリファクタリングは、次のようになります。そして、FormBuilderがどのように見える

// class that reads data and encapsulates it as a Stocks object 

public class StockDataAccessor { 

    // ... 

    public Stocks getStocks() { 
     // ... 
    } 

} 

:次に、あなたのメインクラスとしてFormBuilderを起動

public class FormBuilder extends Application { 

    /* 
    * (non-Javadoc) 
    * @see javafx.application.Application#start(javafx.stage.Stage) 
    * Scene scene 
    *  Group root 
    *   BorderPane borderPane 
    *    TabPane tabPane 
    *     Tab stocksTab 
    *      BorderPane stockTabBorderPane 
    *       GridPane gridPane 
    *   
    */ 

    private Stocks stockData ; 
    private int size; 

    @Override 
    public void start(Stage stage) throws Exception { 

     StockDataAccessor stockDataAccessor = new StockDataAccessor(); 
     stockData = stockDataAccessor.getStocks(); 

     stage.setTitle("Stock Manager"); 
     Group root = new Group(); 
     Scene scene = new Scene(root, 1024, 800, Color.WHITE); 

     TabPane tabPane = new TabPane(); 
     BorderPane borderPane = new BorderPane(); 
     BorderPane stockTabBorderPane = new BorderPane(); 

     Tab stocksTab = new Tab("Stocks"); 

     stockTabBorderPane.setTop(this.addHBox()); 
     stockTabBorderPane.setCenter(this.createGridPane()); 

     stocksTab.setContent(stockTabBorderPane); 
     tabPane.getTabs().add(stocksTab); 

     borderPane.setCenter(tabPane); 

     borderPane.prefHeightProperty().bind(scene.heightProperty()); 
     borderPane.prefWidthProperty().bind(scene.widthProperty()); 

     root.getChildren().add(borderPane); 


     stage.setScene(scene); 
     stage.show(); 


    } 

    private HBox addHBox() { 
     HBox hbox = new HBox(); 
     hbox.setPadding(new Insets(15, 12, 15, 12)); 
     hbox.setSpacing(10); 
     hbox.setStyle("-fx-background-color: #336699;"); 

     Button buttonCurrent = new Button("Current"); 
     buttonCurrent.setPrefSize(100, 20); 

     Button buttonProjected = new Button("Projected"); 
     buttonProjected.setPrefSize(100, 20); 
     hbox.getChildren().addAll(buttonCurrent, buttonProjected); 

     return hbox; 
    } 

    private GridPane createGridPane() { 

     GridPane gridPane = new GridPane(); 

     gridPane.setLayoutX(39); 
     gridPane.setLayoutY(131.0); 
     gridPane.setAlignment(Pos.TOP_CENTER); 
     gridPane.setVgap(5.0); 
     gridPane.setHgap(10.0); 

     gridPane.add(new Label("Active"), 1,1); 
     gridPane.add(new Label("Stock"), 2, 1); 
     gridPane.add(new Label("Symbol"), 3, 1); 
     gridPane.add(new Label("LPP"), 4, 1); 
     gridPane.add(new Label("LPP"), 5, 1); 
     gridPane.add(new Label("HPP"), 6, 1); 
     gridPane.add(new Label("LTP"), 7, 1); 

     System.out.println(this.size); 
     for(int v=2;v < this.stockData.getStocks().size()+2; v++) { 
      gridPane.add(new CheckBox(), 1, v); 
      gridPane.add(new Label("Amazon"), 2, v); 
      gridPane.add(new TextField(), 3,v); 
      gridPane.add(new TextField(), 4,v); 
      gridPane.add(new TextField(), 5,v); 
      gridPane.add(new TextField(), 6,v); 
      gridPane.add(new TextField(), 7,v); 

     } 

     return gridPane; 
    } 

    // for non-JavaFX aware environments (like your IDE...) 
    public static void main(String[] args) { 
     launch(args); 
    } 
} 

何が必要でしょう。


あなたは完全にFormBuilderクラスのうち、アプリケーションのエントリポイントを考慮したい場合は、(かなり似ている)の代替リファクタリングは、次のようになります。

public class FormBuilder { 

    /* 
    * (non-Javadoc) 
    * @see javafx.application.Application#start(javafx.stage.Stage) 
    * Scene scene 
    *  Group root 
    *   BorderPane borderPane 
    *    TabPane tabPane 
    *     Tab stocksTab 
    *      BorderPane stockTabBorderPane 
    *       GridPane gridPane 
    *   
    */ 

    private Stocks stockData ; 
    private int size; 

    private Group root ; 

    public FormBuilder() { 

     StockDataAccessor stockDataAccessor = new StockDataAccessor(); 
     stockData = stockDataAccessor.getStocks(); 

     root = new Group(); 

     TabPane tabPane = new TabPane(); 
     BorderPane borderPane = new BorderPane(); 
     BorderPane stockTabBorderPane = new BorderPane(); 

     Tab stocksTab = new Tab("Stocks"); 

     stockTabBorderPane.setTop(this.addHBox()); 
     stockTabBorderPane.setCenter(this.createGridPane()); 

     stocksTab.setContent(stockTabBorderPane); 
     tabPane.getTabs().add(stocksTab); 

     borderPane.setCenter(tabPane); 

     borderPane.prefHeightProperty().bind(scene.heightProperty()); 
     borderPane.prefWidthProperty().bind(scene.widthProperty()); 

     root.getChildren().add(borderPane); 



    } 

    public Parent getView() { 
     return root ; 
    } 

    private HBox addHBox() { 
     HBox hbox = new HBox(); 
     hbox.setPadding(new Insets(15, 12, 15, 12)); 
     hbox.setSpacing(10); 
     hbox.setStyle("-fx-background-color: #336699;"); 

     Button buttonCurrent = new Button("Current"); 
     buttonCurrent.setPrefSize(100, 20); 

     Button buttonProjected = new Button("Projected"); 
     buttonProjected.setPrefSize(100, 20); 
     hbox.getChildren().addAll(buttonCurrent, buttonProjected); 

     return hbox; 
    } 

    private GridPane createGridPane() { 

     GridPane gridPane = new GridPane(); 

     gridPane.setLayoutX(39); 
     gridPane.setLayoutY(131.0); 
     gridPane.setAlignment(Pos.TOP_CENTER); 
     gridPane.setVgap(5.0); 
     gridPane.setHgap(10.0); 

     gridPane.add(new Label("Active"), 1,1); 
     gridPane.add(new Label("Stock"), 2, 1); 
     gridPane.add(new Label("Symbol"), 3, 1); 
     gridPane.add(new Label("LPP"), 4, 1); 
     gridPane.add(new Label("LPP"), 5, 1); 
     gridPane.add(new Label("HPP"), 6, 1); 
     gridPane.add(new Label("LTP"), 7, 1); 

     System.out.println(this.size); 
     for(int v=2;v < this.stockData.getStocks().size()+2; v++) { 
      gridPane.add(new CheckBox(), 1, v); 
      gridPane.add(new Label("Amazon"), 2, v); 
      gridPane.add(new TextField(), 3,v); 
      gridPane.add(new TextField(), 4,v); 
      gridPane.add(new TextField(), 5,v); 
      gridPane.add(new TextField(), 6,v); 
      gridPane.add(new TextField(), 7,v); 

     } 

     return gridPane; 
    } 

} 

と、エントリ・ポイントを作成:

public class StockApp extends Application { 

    @Override 
    public void start(Stage stage) { 
     FormBuilder formBuilder = new FormBuilder(); 
     Scene scene = new Scene(formBuilder.getView(), 1024, 800, Color.WHITE); 
     stage.setTitle("Stock Manager"); 
     stage.setScene(scene); 
     stage.show(); 
    } 

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

これは助けと私は問題を解決することができました。ありがとうございました。 – ngnear

1

Application.launchlaunchFormインスタンスメソッドで呼び出して、このメソッドがアプリケーションクラスとして呼び出されたインスタンスを使用するとします。

しかし、JavaFXの起動はこの方法では機能しません。 Application.launchが呼び出された場合

、方法はlaunch法自体によって作成されてから起動され、それがinitstartで使用され、この新しいインスタンスであるクラスの新しいインスタンス。

あなたは(おそらくlaunchへのパラメータとして、いくつかの文字列を渡す)initまたはstartStocksを作成することができれば、この問題を解決する最も簡単な方法は、でしょう。

それ以外の場合は、Applicationサブクラスの新しく作成されたインスタンスと通信する必要があります。 staticメンバー...

+0

これは 'Application'サブクラスであってはならないようで、' Stage'サブクラス(または 'Stage'への参照を持つ必要があります)でなければなりません。それから 'launch()'を 'show()'に置き換えてください。 –

+0

@James_D:OPは 'start'メソッドは新しいインスタンスで呼び出されたポイントになった場合は、プラットフォームが発売されていないと' Stage'を表示しようとするが、必然的に失敗する... – fabian

+0

真です。しかし、ライフサイクルがすべてここで間違っているように思えます。明らかに、 'launchForm'を呼び出す前に他のコードが実行されています。実際にはそれ以前には何もあってはなりません。すべてのスタートアップコードは本当に珍しい場合を除いて、 'init()'または 'start()'になければなりません。 (あなたの最後から2番目のパラグラフで言っているのと似ています)。 "その他のコード"は 'Application'サブクラスでなければなりません。私は、OPが掲示したコードよりも構造的な問題が多いことを意味していると思います。 –

関連する問題