2012-09-07 18 views
5

は私がNode#lookup()からFXMLoaderおかげでロードシーンでのVBoxノードを見つけたいが、私は次の例外を取得:のJavaFX 2.0 + FXML - 奇妙なルックアップ動作

java.lang.ClassCastException: com.sun.javafx.scene.control.skin.SplitPaneSkin$Content cannot be cast to javafx.scene.layout.VBox

コード:

public class Main extends Application { 
    public static void main(String[] args) { 
     Application.launch(Main.class, (java.lang.String[]) null); 
    } 
    @Override 
    public void start(Stage stage) throws Exception { 
     AnchorPane page = (AnchorPane) FXMLLoader.load(Main.class.getResource("test.fxml")); 
     Scene scene = new Scene(page); 
     stage.setScene(scene); 
     stage.show(); 

     VBox myvbox = (VBox) page.lookup("#myvbox"); 
     myvbox.getChildren().add(new Button("Hello world !!!")); 
    } 
} 

FXMLファイル:

<AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml" > 
    <children> 
    <SplitPane dividerPositions="0.5" focusTraversable="true" prefHeight="400.0" prefWidth="600.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> 
     <items> 
     <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0" /> 
     <VBox fx:id="myvbox" prefHeight="398.0" prefWidth="421.0" /> 
     </items> 
    </SplitPane> 
    </children> 
</AnchorPane> 

私が知りたいのですが:
1.なぜ、ルックアップ方法がSplitPaneSkin$ContentないVBoxを返しますか?
2.別の方法でVBoxをどうすれば入手できますか?

答えて

7
  1. をSplitPaneは別個のスタックペイン内のすべての項目を入れ、事前に

    おかげで(SplitPaneSkin$Contentとして架空)。不明な理由により、FXMLLoaderはルートの子と同じIDを割り当てます。

    public <T> T lookup(Node parent, String id, Class<T> clazz) { 
        for (Node node : parent.lookupAll(id)) { 
         if (node.getClass().isAssignableFrom(clazz)) { 
          return (T)node; 
         } 
        } 
        throw new IllegalArgumentException("Parent " + parent + " doesn't contain node with id " + id); 
    } 
    

    、次の方法でそれを使用する:

    VBox myvbox = lookup(page, "#myvbox", VBox.class); 
    myvbox.getChildren().add(new Button("Hello world !!!")); 
    
  2. あなたがControllerを使用してautopopulatedフィールドを追加することができます。

    @FXML 
    VBox myvbox; 
    
+0

私は自分を更新しました簡単な例で投稿してください。私は '@ FXML'アノテーションを知っていますが、IDは自動的に生成されるので使用できません。 –

+0

が回避策で更新されました –

+0

素晴らしいです、それはうまく動作します。私はFXMLoaderがrootの子と同じidを割り当てたとは考えていませんでした。 OracleのJavaFX UIチームのQAテクニカル・リードがスタックオーバーフローの問題に対応しているのを見てうれしいです。 **多くのありがとう** –

9
あなたは次のユーティリティメソッドで、あなたは必要なのVBoxを得ることができます

VBoxへの参照を取得する最も簡単な方法は、FXMLLoader#getNamespace()を呼び出すことです。あなたがFXMLLoaderのインスタンスを作成して、負荷の非静的バージョンを(呼び出す必要があります

VBox myvbox = (VBox)fxmlLoader.getNamespace().get("myvbox"); 

注)これが機能するためには:たとえば

FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("test.fxml")); 
AnchorPane page = (AnchorPane) fxmlLoader.load();