2012-09-07 18 views
5

Quiero encontrar un nodo caja vertical en una escena cargada de FXMLoader gracias a Node#lookup() pero tengo la siguiente excepción:JavaFX 2.0 + FXML - el comportamiento de búsqueda extraña

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

El código:

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 !!!")); 
    } 
} 

El archivo 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> 

me gustaría saber: 1. ¿Por qué
de búsqueda de métodos devuelven un SplitPaneSkin$Content y no un VBox?
2. ¿Cómo puedo conseguir el VBox de otra manera?

Gracias de antemano

Respuesta

7
  1. SplitPane pone todos los elementos de la pila paneles separados (imaginaron como SplitPaneSkin$Content). Por alguna razón desconocida, FXMLLoader les asigna la misma identificación que root child. Puede obtener VBox que necesita para el próximo método de utilidad:

    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); 
    } 
    

    y utilizarla manera siguiente:

    VBox myvbox = lookup(page, "#myvbox", VBox.class); 
    myvbox.getChildren().add(new Button("Hello world !!!")); 
    
  2. puede utilizar Controller y añadir campo autopopulated:

    @FXML 
    VBox myvbox; 
    
+0

He actualizado mi publique con un ejemplo simple. Sé la anotación de '@ FXML' pero no puedo usarla porque los identificadores se generan automáticamente. –

+0

actualizado con una solución –

+0

Genial, funciona bien. No había supuesto que FXMLoader les asignara la misma identificación que root child. Me alegra ver que el líder tecnológico de QA en el equipo de IU de JavaFX en Oracle responde a las preguntas de stackoverflow. ** Muchas gracias ** –

9

La forma más fácil de obtener una referencia de VBox es llamando a FXMLLoader # getNamespace(). Por ejemplo:

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

Tenga en cuenta que tendrá que crear una instancia de FXMLLoader y llama a la versión no estática de carga() con el fin de que esto funciona:

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