2016-11-09 1 views
0

私は説明のために考えを単純化しました:なぜボタングラフィックは最新のJavaFXページにのみ表示されますか?重複したコントローラは互いに独立していないのですか?

私はMDIアプリケーションを持っています。ボタンがあります。そのボタンを押すと、そのMDIアプリケーション内に新しいウィンドウが開きます。ボタンをもう一度押すと、そのウィンドウの別の複製が開きます。ウィンドウにはボタンがあり、ボタンにはグラフィックス(SVG)があります。グラフィックスは正しく表示されますが、新しいウィンドウを開くと、グラフィックスは新しいウィンドウに表示されなくなり、最近開いたウィンドウにのみ表示されます。

これは懸念事項ではありませんが、同じ種類のさまざまなWindowsのすべての機能で問題になると思います。なぜこれが起こったのですか?ところで

:ライブラリはJFoenixとJFXtras

/* this will be called when the button is pressed to open a new window. mdiCenter is the anchor pane the windows are displayed on */ 

public void addWindow() throws IOException 
{ 
    try 
    { 
     BorderPane pane = FXMLLoader.load(getClass().getResource("MyPage.fxml")); 
     pane.setMinSize(400, 300); 
     Window window = new Window(); 
     window.getContentPane().getChildren().add(pane); 
     mdiCenter.getChildren().add(window); 
    } 
    catch (IOException e) 
    { 
     e.printStackTrace(); 
    } 
} 

/* this method is called when MyPage is initialized */ 
private void setButtonSvgs() 
{ 
    double size = 20; 
    String style = "-fx-background-color: white;"; 

    button1.setGraphic(Util.getGlyph("SVGname", size, style)); 
    button2.setGraphic(Util.getGlyph("SVGname", size, style)); 
    button3.setGraphic(Util.getGlyph("SVGname", size, style)); 
    button4.setGraphic(Util.getGlyph("SVGname", size, style)); 
} 

/* the following are in the Util class. this is the method that's called in the method above^*/ 

private static final List<SVGGlyph> glyphs = SVGGlyphLoader.getAllGlyphsIDs().stream().map(item -> SVGGlyphLoader.getIcoMoonGlyph(item)).collect(Collectors.toList()); 

public static SVGGlyph getGlyph(String name, double size, String style) 
{ 
    for (SVGGlyph glyph : glyphs) 
    { 
     if (glyph.getName().equals(name)) 
     { 
      glyph.setSize(size, size); 
      glyph.setStyle(style); 
      return glyph; 
     } 
    } 
    return null; 
} 

/* the SVG glyph list is initialized in the main application but I'm not sure that's relevant. */ 

は助けてくださいます!なぜこれが起こっているのか分かりません! FXMLがロードされるたびに、新しいコントローラをインスタンス化して他のコントローラと独立してはいけませんか?

+0

静的メソッドを呼び出すので、新しいコントローラはこれまでに作成されませんyタイム。これは、Javadocが明確に主張していないものです... '非静的' load()メソッドを使用するたびに、新しいコントローラを作成したい場合。実際には私は8つのload()メソッドから2最初の静的ではないと思います.FXMLLoaderクラスを逆コンパイルすることでチェックできます。あなたがそれをキャッチしていない場合、私は答えを追加します;) – GOXR3PLUS

答えて

0

私はそれを理解しました。私のユーティリティクラスでは、グリフリストとgetGlyphメソッドは静的です。これらを非静的にすることで問題を解決しました。シングルトンのユーティリティクラスがソリューションになります。

+0

いいえ、それはありません。メソッド/リストを非静的にするだけで、 "症状"が取り除かれました。シングルトンパターンを使用すると、同じ問題が発生します。 – fabian

+0

はい実装しようとしているときにこれを発見しました。意味をなさない残念ながら、毎回新しいインスタンスをインスタンス化する必要があります。 – skex

0

FXMLLoaderクラスは、setController()メソッドを使用してコードのルート要素 ためのコントローラを設定することができます。 getController()メソッドを使用して、コントローラーの参照をローダー から取得します。開発者はコントローラの参照 を取得する際によくある間違いをします。 load() メソッドの設計方法が間違っています。 load() メソッドには7つのオーバーロードされたバージョンがあります。そのうち2つはインスタンスメソッドであり、5つは静的メソッドです。 、あなたが FXMLLoaderクラスのオブジェクトを作成し、文書をロードするために、クラスのインスタンス のいずれかの方法を使用することを確認する必要がありgetController()メソッドを使用するには:


すべて

非静的:

@CallerSensitive 
public <T> T load() throws IOException { .. } 

@CallerSensitive 
public <T> T load(InputStream arg0) throws IOException { ... } 
JavaFXのに既存のロード方法は、(JavaFXの8から)逆コンパイル FXMLLoaderクラスを発見しました

静的:

@CallerSensitive 
public static <T> T load(URL arg) throws IOException { ...} 

@CallerSensitive 
public static <T> T load(URL arg, ResourceBundle arg0) throws IOException { ... } 

@CallerSensitive 
public static <T> T load(URL arg, ResourceBundle arg0, BuilderFactory arg1) throws IOException { ... } 

@CallerSensitive 
public static <T> T load(URL arg, ResourceBundle arg0, BuilderFactory arg1, Callback<Class<?>, Object> arg2) 
      throws IOException { ... } 

@CallerSensitive 
public static <T> T load(URL arg, ResourceBundle arg0, BuilderFactory arg1, Callback<Class<?>, Object> arg2, 
      Charset arg3) throws IOException { ...} 

最後に:あなたは、静的メソッドを使用している

言及、あなたのコントローラがNodesの同じインスタンスを取得するので、あなたはNodesことをcreate.Soしたいです元の親から削除され、新しいものに追加されます。

関連する問題