2012-01-20 14 views
7

ऐसा लगता है कि WindowEvent.WINDOW_SHOWN दृश्य ग्राफ में किसी भी नोड्स पर कभी भी प्रेषित नहीं होता है, न ही वैसे भी है (जिसे मैं पा सकता हूं) यह जानने के लिए कि जब कोई नोड दिखाई देता है/प्रस्तुत/दिखाया जाता है। उदाहरण के लिए:दृश्य ग्राफ के नोड्स में WindowEvent.WINDOW_SHOWN के लिए कैसे सुनें?

TestLauncher.java

package com.example.javafx.event; 

import javafx.application.Application; 
import javafx.fxml.FXMLLoader; 
import javafx.scene.Parent; 
import javafx.scene.Scene; 
import javafx.stage.Stage; 

public class TestLauncher extends Application 
{ 
    public static void main(String[] args) 
    { 
     Application.launch(TestLauncher.class, args); 
    } 

    @Override 
    public void start(Stage stage) throws Exception 
    { 
     Parent root = FXMLLoader.load(TestController.class.getResource("TestView.fxml")); 
     Scene scene = new Scene(root); 
     stage.setScene(scene); 
     stage.show(); 
    } 
} 

TestController.java

package com.example.javafx.event; 

import java.net.URL; 
import java.util.ResourceBundle; 
import javafx.event.EventHandler; 
import javafx.fxml.FXML; 
import javafx.fxml.Initializable; 
import javafx.scene.Parent; 
import javafx.scene.control.TextField; 
import javafx.stage.WindowEvent; 

public class TestController implements Initializable 
{ 
    @FXML private Parent root; 
    @FXML private TextField serverAddressInput; 
    @FXML private TextField usernameInput; 

    @Override 
    public void initialize(URL url, ResourceBundle rb) 
    { 
     serverAddressInput.setText("127.0.0.1"); 

     //won't work because stage isn't visible yet 
     trySetFocusOnUsernameInput1(); 

     //apparently Stage never passes on any WindowEvents to the children... 
     trySetFocusOnUsernameInput2(); 
    } 

    private void trySetFocusOnUsernameInput1() 
    { 
     usernameInput.requestFocus(); 
    } 

    private void trySetFocusOnUsernameInput2() 
    { 
     root.addEventFilter(WindowEvent.WINDOW_SHOWN, new EventHandler<WindowEvent>() 
     { 
      @Override 
      public void handle(WindowEvent window) 
      { 
       usernameInput.requestFocus(); 
      } 
     }); 

     root.addEventHandler(WindowEvent.WINDOW_SHOWN, new EventHandler<WindowEvent>() 
     { 
      @Override 
      public void handle(WindowEvent window) 
      { 
       usernameInput.requestFocus(); 
      } 
     }); 
    } 

    public void handleWindowShownEvent() 
    { 
     usernameInput.requestFocus(); 
    } 
} 

TestView.fxml

<?xml version="1.0" encoding="UTF-8"?> 

<?import java.lang.*?> 
<?import javafx.scene.*?> 
<?import javafx.scene.control.*?> 
<?import javafx.scene.layout.*?> 

<VBox 
    xmlns:fx="http://javafx.com/fxml" 

    fx:id="root" 
    fx:controller="com.example.javafx.event.TestController" 

    prefHeight="150" 
    prefWidth="200" 
> 
    <children> 
     <TextField fx:id="serverAddressInput" /> 
     <TextField fx:id="usernameInput" /> 
    </children> 
</VBox> 

तो, वास्तव में, एक नोड इस तथ्य से अवगत कैसे हो सकता है कि यह दृश्यमान/प्रस्तुत/दिखाया गया है?

उत्तर

4

मैं संभव समाधान में से एक अनुमान

public void handleWindowShownEvent() 
    { 
     usernameInput.requestFocus(); 
    } 

TestController.javaके लिए निम्न विधि को जोड़ने के लिए है और फिर निम्न के लिए TestLauncherमें start पद्धति को बदलने:

@Override 
    public void start(Stage stage) throws Exception 
    { 
     FXMLLoader loader = new FXMLLoader(); 
     Parent root = (Parent)loader.load(TestController.class.getResourceAsStream("TestView.fxml")); 
     final TestController controller = (TestController)loader.getController(); 
     stage.addEventHandler(WindowEvent.WINDOW_SHOWN, new EventHandler<WindowEvent>() 
     { 
      @Override 
      public void handle(WindowEvent window) 
      { 
       controller.handleWindowShownEvent(); 
      } 
     }); 
     Scene scene = new Scene(root); 
     stage.setScene(scene); 
     stage.show(); 
    } 

मैं वास्तव में अन्य समाधानों का स्वागत करता हूं क्योंकि यह बहुत गुस्सा लगता है ...

+0

प्रिय एंड्री। मेरे आवेदन में नियंत्रकों की संख्या है और मुझे इसे कुछ यूआई प्रवाह के मध्य में बनाने की आवश्यकता है। जब आप windowEvent.WINDOW_SHOWN ईवेंट हैंडलर को जिक्र करते हैं, तो यह इस ईवेंट हैंडलर प्लेस को निष्पादित करने का प्रयास करेगा जिसे मैंने घोषित किया है जिसका मतलब एप्लिकेशन की शुरुआत (चरण विधि) के निष्पादन के साथ है, तो मुझे कुछ शून्य सूचक अपवाद मिला। क्या आप कृपया मुझे बता सकते हैं कि मैं इस मुद्दे को कैसे ठीक कर सकता हूं। धन्यवाद। – Channa

+0

यदि आप अभी भी एनोटर समाधान (4y बाद में ..) में रुचि रखते हैं, तो मेरे उत्तर –

3

एक अन्य समाधान है कि बेशक बहुत सेक्सी नहीं है, लेकिन आवेदन से नोड अलग करता:

root.sceneProperty().addListener(new ChangeListener<Scene>() { 
    @Override 
    public void changed(ObservableValue<? extends Scene> observable, Scene oldValue, Scene newValue) { 
    newValue.windowProperty().addListener(new ChangeListener<Window>() { 
     @Override 
     public void changed(ObservableValue<? extends Window> observable, Window oldValue, Window newValue) { 
     newValue.addEventHandler(WindowEvent.WINDOW_SHOWN, new EventHandler<WindowEvent>() { 
      @Override 
      public void handle(WindowEvent event) { 
      usernameInput.requestFocus(); 
      } 
     }); 
     } 
    }); 
    } 
}); 

मेरे मामले में और अधिक समझ में बनाया गया।

+2

पर एक नज़र डालें, मुझे लगता है कि यह सबसे अच्छा समाधान है, decoupling के कारण – DevWurm

संबंधित मुद्दे