2016-05-30 9 views
0

いくつかのJava fxコンポーネントを処理している間に私はいくつかの奇妙な動作を観察しました。 GUI上でボタンを押すと、コントローラを介して子ノードを親ノードに動的に追加しようとしています。ここでは、問題の再現可能なシナリオです:親ノードがその子を失う

VBox vbox = new VBox(); 
    HBox entry = new HBox(); 
    Button button = new Button(); 
    TextField text = new TextField(); 

    entry.getChildren().add(text); 
    entry.getChildren().add(button); 

    vbox.getChildren().add(entry); 

    System.out.println(vbox.getChildren().isEmpty() ? "empty" : "not empty"); //prints out "not empty" 
    HBox newEntry = new HBox(entry); 
    System.out.println(vbox.getChildren().isEmpty() ? "empty" : "not empty"); //prints out "empty" 

私はコンストラクタにentryを渡すときvboxが子供としてentry失っているなぜあなたは私を啓発してくださいことはできますか?私はentryをコンストラクタに渡して、FXMLフォームを介して既に設定されている他のすべてのオブジェクト属性/プロパティをコピーします。私の実際のコードでは、各要素はnode.setId()メソッドで設定された異なる識別子を持っているので、重複するIDは問題ではありません。根底にあるメカニズムを認識していませんか?ありがとうございました。

+0

あなたは 'HBoxのnewEntry =エントリを行う必要があります;'の代わりに '新しいHBoxの(エントリー)の;' – ScriptKiddy

+0

私はそれで、 'newEntry'が' entry'を指していて、 'newEntry'で修正したものが' entry'を変更するので、そう思わないでください。 – Marius

答えて

3

私はentryをコンストラクタに渡して、FXMLフォームで既に設定されている他のすべてのオブジェクト属性/プロパティをコピーします。

このようには機能しません。そのコンストラクタは、新しく作成されたHBoxの子と同じインスタンスを追加します。 Nodeは1つの親しか持つことができず、Parentの子リストにNodeが存在するため、JavaFXは元の子の子リストからNodeを削除して状態を修正する必要があります。

Paneの多くは、子をコンストラクタの1つに渡すことができます。それらはであり、コピーコンストラクタではありませんが、単純な「ショートカット」はpane.getChildren().addAll(children);を使用せずに子を追加することができます。実際には、JavaFX APIのNodeのコピーコンストラクタは認識していません。

HBox newEntry = new HBox(entry); 

それが唯一の子としてentryを含む新しいHBoxを作成します。

シーングラフの一部をコピーするのではなく、シーングラフの一部を作成するヘルパーメソッドを作成する方が簡単です(これはfxmlファイルを使用して行うこともできます)。

(あなたがNode階層のコピーを作成することを可能にするのJavaFX APIには機能はありません。)

+0

あなたの返事をありがとう。それでも、同じインスタンスであれば 'newEntry'が' vbox'の子になり、 'entry'が' vbox'から削除されることが期待されます。あなたは何をお勧めしますか? GUI上のボタンを押すと、新しいFXMLを作成せずに読み込むことで回避策がありますか? – Marius

+0

@マリアスこれは 'entry'と同じインスタンスの' newEntry'ではありません。あなたは新しい 'HBox'を作成しますが、' HBox'は子として言及されたインスタンスを取得します。ノード階層の "コピー"機能がないので、新しいfxmlを作成するのが最良の方法です。一般的な 'Node'タイプのその機能の実装では、プロパティの値をコピーするためにリフレクションを多用する必要があります。いくつかのケースで失敗する(例えば、デフォルトのコンストラクタがない場合など)、単純に新しいfxmlを作成するよりも複雑になります。 – fabian

+0

ええ、私もそう思った。それは私が最終的に反映を通過しなければならないということです。ええと、私はちょうど私が推測するいくつかのJavaスクリプトを使用します。最初に 'node'を複製しようとしていましたが、それは動作しませんでした。意外にも、あなたは '新しいHBox(anotherHBox)'と '新しいVBox(anotherVBox)'を持つことができますが、あなたは 'new Button(anotherButton)'を何とかすることはできません。私はそれについての説明があると確信しています:/答えの本文にあなたのコメントのテキストを追加してください。私は答えとしてそれを選ぶことができます。あなたのトラブルに感謝します。 – Marius

関連する問題