2012-06-25 13 views
5

मेरे दृश्य में एक छवि प्रदर्शित करने वाला केवल ImageView है। मैं छवि को काला (दृश्य के असाइन किए गए रंग) में फीका करना चाहता हूं, फिर कुछ समय बाद, काले से छवि में फिर से फीका। मुझे FadeTransition इस उद्देश्य के लिए बहुत उपयुक्त पाया गया। यह मेरा कोड का एक टुकड़ा है:javafx 2.1 में समाप्त होने के लिए संक्रमण की प्रतीक्षा कैसे करें?

// fade to black transition 
    FadeTransition ft1 = new FadeTransition(Duration.millis(2000), myImageView); 
    ft1.setFromValue(1.0); 
    ft1.setToValue(0.0); 
    ft1.play(); 

    // fade from black transition 
    FadeTransition ft2 = new FadeTransition(Duration.millis(2000), myImageView); 
    ft2.setFromValue(0.0); 
    ft2.setToValue(1.0); 
    ft2.play(); 

मेरे समस्या यह है कि ft1.play() तो नीचे दिए गए कोड निष्पादित किया जा रहा शुरू कर देंगे से पहले ft1.play() से बाहर निकल गया है, अतुल्यकालिक है। नतीजतन मैं केवल दूसरा संक्रमण देखता हूं। मैं पहले संक्रमण को समाप्त करने के लिए और फिर दूसरा संक्रमण लॉन्च करने का इंतजार कैसे कर सकता हूं? मैं धागे को बीच में सो नहीं सकता क्योंकि यह मुख्य जावाफक्स धागा है (कोशिश की और काम नहीं किया)।

मैंने ध्वज पर व्यस्त प्रतीक्षा के संयोजन के साथ ऑनफिनिशप्रॉपर्टी() विधि का उपयोग करने की कोशिश की, लेकिन मैं हमेशा के लिए लूप में फंस गया। इसके लिए मेरा कोड यहां दिया गया है:

boolean isTransitionPlaying; 
    FadeTransition ft = new FadeTransition(Duration.millis(2000), iv); 
    ft.setFromValue(1.0); 
    ft.setToValue(0.0); 
    ft.onFinishedProperty().set(new EventHandler<ActionEvent>() { 
     @Override 
     public void handle(ActionEvent actionEvent) { 
      transitionPlaying = false; 
     } 
    }); 
    transitionPlaying = true; 
    ft.play(); 

    while (transitionPlaying == true) 
    { 
     // busy wait 
     System.out.println("still waiting..."); 
    } 

    FadeTransition ft2 = new FadeTransition(Duration.millis(2000), iv); 
    ft2.setFromValue(0.0); 
    ft2.setToValue(1.0); 
    ft2.play(); 

ठीक से इंतजार कैसे किया जा रहा है? आप

उत्तर

3

व्यस्त प्रतीक्षा (या यहां तक ​​Thread.Sleep) JavaFX आवेदन धागे पर हमेशा एक बुरा विचार है - आप धागा जो अपने संक्रमण इतना यूआई प्रसंस्करण संभालती बाँध , साथ ही साथ आपका बाकी यूआई अपडेट नहीं किया गया है - व्यस्त प्रतीक्षा की अवधि के लिए प्रभावी रूप से अपने ऐप यूआई को ठंडा कर रहा है। एक उत्तरदायी यूआई के लिए, आपको जितनी जल्दी हो सके एफएक्स एप्लिकेशन थ्रेड पर अपना तर्क चलाने की जरूरत है, फिर थ्रेड को जाने दें ताकि शेष जावाएफएक्स सिस्टम इसके प्रसंस्करण के साथ मिल सके। यही कारण है कि संक्रमणों में एसिंक कॉलबैक होते हैं - जो, जब आप उन्हें उपयोग करते हैं, तो विकास का एक बहुत ही स्वाभाविक तरीका है।

उलुक के समाधान (जो महान हैं) के अतिरिक्त, आप अनुक्रम में संक्रमण करने में सहायता को संभालने के लिए SequentialTransition कक्षा को भी देख सकते हैं। ध्यान दें कि यदि आप अनुक्रमिक ट्रांज़िशन पूरा होने के बाद कोई कार्रवाई करना चाहते हैं, तो भी आप उस समय कार्रवाई करने के लिए अनुक्रमिक ट्रांजिशन में एक पूर्ण हैंडलर जोड़ना चाहेंगे।

+0

मुझे लगता है कि मैं सोच रहा था कि संक्रमण के बाद() असीमित हैं, वे जावाफैक्स एप्लिकेशन थ्रेड के बाद किसी अन्य थ्रेड पर होते हैं। यही कारण है कि मैंने सोचा कि मैं मुख्य धागा संक्रमण को अपनी चीज खत्म करने के लिए इंतजार कर सकता हूं और फिर फिर से शुरू कर सकता हूं। अब मैं देखता हूं कि यदि आवेदन धागा सो रहा है, तो संक्रमण भी संसाधित नहीं किया जा सकता है, है ना? तो मुझे लगता है कि अनुक्रमिक ट्रांजिशन मेरे मामले के लिए सबसे स्पष्ट समाधान है। आप और Ukuk दोनों के लिए धन्यवाद। – dadox

17

ठीक धन्यवाद अगर आपके ft2ft1 को प्रतिबिंबित करता एनीमेशन तो

ft1.setAutoReverse(true); 
ft1.setCycleCount(1); 
// Or 
// ft1.setCycleCount(Timeline.INDEFINITE); 
// to loop infinitely (blinking effect) until stop() 

करना है और आप ft2 नहीं है। आप अभी भी ft2 की जरूरत है ft1 के बाद खेलने के लिए तो

ft1.setOnFinished(new EventHandler<ActionEvent>() { 

    @Override 
    public void handle(ActionEvent event) { 
     ft2.play(); 
    } 
}); 
+0

ठीक है, क्या आप playOnFinished() के अलावा play() के माध्यम से कोड के दिए गए टुकड़े को निष्पादित करने का एक और तरीका जानते हैं? मैं संक्रमण के चारों ओर तर्क को व्यवस्थित करने के बजाय अपने कोड पर संक्रमण को व्यवस्थित करने में सक्षम होना चाहता हूं ... – dadox

+1

दुर्भाग्यवश, जैसा कि आपने बताया है कि मुख्य धागा को सोने/प्रतीक्षा मोड में रखना असहज है। मोडल (पुष्टिकरण) संवाद विंडो दिखाते समय भी वही कठिनाई उठाई जाती है। लेकिन वहाँ showWWait (v2.2) विधि समाधान प्रदान करेगी, जो केवल मोडल चरणों पर लागू होती है। –

1

मुझे समस्या थी जहां अन्य कोड कुछ गणना कर रहे थे और मैं जावाफ़ैक्स ऐप में एनिमेशन चलाने के लिए चाहता था, लेकिन एनीमेशन समाप्त होने के लिए अन्य कोड बनाने की आवश्यकता थी। मैं जब एनीमेशन समाप्त हो गया है यह अन्य कोड बताने के लिए सक्षम नहीं था, इसलिए मैं एनीमेशन खेल रहा है और फिर इसे खत्म करने के लिए के लिए इंतजार करने के लिए विधि बनाया है:

private synchronized void playAnimationAndWaitForFinish(final Animation animation) { 
    if (Platform.isFxApplicationThread()) { 
     throw new IllegalThreadStateException("Cannot be executed on main JavaFX thread"); 
    } 
    final Thread currentThread = Thread.currentThread(); 
    final EventHandler<ActionEvent> originalOnFinished = animation.getOnFinished(); 
    animation.setOnFinished(new EventHandler<ActionEvent>() { 

     @Override 
     public void handle(ActionEvent event) { 
      if (originalOnFinished != null) { 
       originalOnFinished.handle(event); 
      } 
      synchronized (currentThread) { 
       currentThread.notify(); 
      } 
     } 
    }); 
    Platform.runLater(new Runnable() { 

     @Override 
     public void run() { 
      animation.play(); 
     } 
    }); 
    synchronized (currentThread) { 
     try { 
      currentThread.wait(); 
     } catch (InterruptedException ex) { 
      //somebody interrupted me, OK 
     } 
    } 
} 

यह आवश्यक है कि इस विधि मुख्य JavaFX में लागू नहीं किया गया है धागा, अन्यथा, यह मेरे लिए काम करता है।

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