2012-09-07 8 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 उन्हें एक ही आईडी को रूट बच्चे के रूप में असाइन करें। आप VBox प्राप्त कर सकते हैं आप अगले उपयोगिता विधि द्वारा की जरूरत है:

    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' एनोटेशन पता है लेकिन मैं इसका उपयोग नहीं कर सकता क्योंकि आईडी स्वचालित रूप से जेनरेट की जाती हैं। –

+0

एक वर्कअराउंड –

+0

ग्रेट के साथ अपडेट किया गया, यह ठीक काम करता है। मुझे नहीं लगता था कि FXMLoader ने उन्हें एक ही आईडी को रूट बच्चे के रूप में असाइन किया था। ओरेकल में जावाएफएक्स यूआई टीम में क्यूए टेक लीड को देखकर मुझे खुशी है कि स्टैक ओवरफ्लो प्रश्नों का जवाब है। ** बहुत धन्यवाद ** –

9

VBox का संदर्भ प्राप्त करने का सबसे आसान तरीका FXMLLoader # getNamespace() को कॉल करना है। उदाहरण के लिए:

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

ध्यान दें कि आप FXMLLoader का एक उदाहरण बनाने के लिए और कॉल के क्रम में इस बात के लिए की आवश्यकता होगी लोड() की गैर स्थिर संस्करण काम करने के लिए:

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