2015-06-10 12 views
5

मेरे पास एक जावा स्विंग ऐप है जो मैं जांच कर रहा हूं कि जावाफैक्स को बंदरगाह के लिए भी संभव है। ऐप आंतरिक रूप से उपयोग की जाने वाली स्क्रिप्टिंग भाषा के लिए एक विकास वातावरण और सिम्युलेटर है। इसके बारे में दिलचस्प बात यह है कि आप इस स्क्रिप्टिंग भाषा के लिए ब्रेकपॉइंट्स सेट कर सकते हैं और इसके माध्यम से कदम उठा सकते हैं, जैसे किसी भी प्रोग्रामर भाषा की अपेक्षा करता है।जावाफ़ैक्स में सेकेंडरी लूप, स्विंग की तरह?

अब क्योंकि सिम्युलेटर की भाषा का अर्थ है, दुभाषिया के निष्पादन के भीतर गहराई, जब यह ब्रेकपॉइंट हिट करता है, तो यह जावा स्विंग सेकेंडरी लूप क्लास के साथ गुई में वापस आ सकता है। तो जब ब्रेकपॉइंट मारा जाता है, तो यह द्वितीयक Loop.enter() को कॉल करता है। गुई तब प्रयोक्ता के लिए चर का निरीक्षण करने के लिए सक्रिय है और गुई घटक सक्रिय हैं। जब उपयोगकर्ता प्रोग्राम में "जारी रखें" हिट करता है, तो यह दुभाषिया के निष्पादन को जारी रखने के लिए द्वितीयकLoop.exit() को कॉल करता है। दुभाषिया के लिए प्राथमिक लूप पर वापस जाने के लिए यह पूरी स्थिति को खोलने के लिए वास्तव में संभव नहीं होगा, और उसके बाद इसे उसी बिंदु पर छोड़ दिया जाए। यही कारण है कि माध्यमिक लूप इसे काम करने में अमूल्य है।

क्या यह जावाएफएक्स में संभव है?

उत्तर

2

हां, यह संभव है। आपको enterNestedEventLoop और exitNestedEventLoop विधियों (वे com.sun.javafx.tk.Toolkit क्लास के अंदर हैं) का उपयोग करने की आवश्यकता है।

// Make sure to import the FX Toolkit first 
import com.sun.javafx.tk.Toolkit; 

// This object will be used as a unique identifier to the nested loop (to 
// block the execution of the thread until exitNestedEventLoop is called) 
final Object loopLock = new Object(); 

// Simulate a long process thread (DB call, download, etc) 
Thread longProcess = new Thread(new Runnable() 
{ 
    @Override 
    public void run() 
    { 
     // Sleep for 12 seconds to simulate a long process 
     try 
     { 
      Thread.sleep(12000); 
     } catch (InterruptedException e) 
     { 
      e.printStackTrace(); 
     } 

     // Setup a result to pass back to the enterNestedLoop() caller 
     String result = "Result of this long process"; 

     // We are now done. Call exitNestedEventLoop() to unblock 
     // the enterNestedLoop() caller. This needs to run from 
     // the FX Thread so use Platform.runLater() 
     Runnable fxRunner = new Runnable() 
     { 
      public void run() 
      { 
       try 
       { 
        Toolkit.getToolkit().exitNestedEventLoop(loopLock, 
          result); 
       } catch (Throwable t) 
       { 
        t.printStackTrace(); 
       } 
      } 
     }; 
     Platform.runLater(fxRunner); 
    } 
}); 

// Start that long process from the FX Thread 
longProcess.start(); 
// The next call will block until exitNestedEventLoop is called, however 
// the FX Thread will continue processing UI requests 
Object result = Toolkit.getToolkit().enterNestedEventLoop(loopLock); 
// Next statement will print: "Result of this long process" 
System.out.println("Result is: " + result); 

अब, इससे पहले कि आप इस चेतावनी दी दो महत्वपूर्ण बातें की हो का उपयोग करें:: इस प्रयोग उदाहरण देखें

  1. com.sun.javafx.tk.Toolkit वर्ग है सार्वजनिक एपीआई का हिस्सा नहीं है, इसलिए ओरेकल को नोटिस के बिना इसे हटाने का अधिकार सुरक्षित है। मैं इसका उपयोग जावा 7 से 8u51 तक ठीक कर रहा हूं ताकि वे हमेशा के लिए वहां रह सकें, पैकेज/नाम बदल सकें या पूरी तरह से गायब हो सकें (संभावना नहीं)।

  2. नेस्टेड लूप (और स्विंग के माध्यमिक लूप) लचीलापन और छोटे अनुप्रयोगों के लिए बहुत अच्छे हैं लेकिन उन्हें अधिक उपयोग करने से अक्सर कीमत आती है। कई लूपों (विशाल स्टैक ट्रेस) के लिए घोंसले अक्सर आपके अनुप्रयोगों में "अजीब" व्यवहार का कारण बनेंगे क्योंकि आपके कोड के शुरुआती हिस्सों में चार या पांच चीजें पूरी तरह से असंबंधित होने की प्रतीक्षा कर सकती हैं। मैंने एफएक्स नेस्टेड लूप को एफएक्स वेबइंजिन निष्पादन स्क्रिप्ट() कॉल में "रिक्त" अपवादों और अन्य समस्याओं के बीच कीबोर्ड प्रीप्रोकैसिंग (जब एफएक्स + स्विंग जोड़ते हैं) को डुप्लिकेट कर दिया है।

कहा कि मैं बजाय javafx.concurrent.Task का उपयोग कर की सिफारिश करेंगे (अगर यह समझ में आता है)। टास्क क्लास का उपयोग करने के लिए थोड़ा और प्रयास की आवश्यकता होगी, लेकिन मुझे लगता है कि यह चीजों को करने का सही तरीका है और शायद आपको बहुत से रखरखाव का समय बचाएगा।

FX टास्क वर्ग के बारे में अतिरिक्त जानकारी के लिए इस महान लेख देखें: http://docs.oracle.com/javase/8/javafx/interoperability-tutorial/concurrency.htm

अद्यतन: enterNestedEventLoop और exitNestedEventLoopजावा 9 सार्वजनिक एपीआई (प्लेटफार्म वर्ग) का हिस्सा है, में अधिक जानकारी के लिए किया जाएगा JDK-8090865

आशा है कि इससे मदद मिलती है!

+1

जेईपी 253 के अनुसार: "जावा 9 की आगामी रिलीज के साथ, और विशेष रूप से प्रोजेक्ट आरा में मॉड्यूल के बीच मजबूत सीमाओं के परिचय के साथ, डेवलपर्स को पता चलेगा कि उनका कोड अब com comun से संकलित या चलाएगा * * पैकेज अब उपलब्ध नहीं होंगे। " [इसके अलावा] (http://blog.codefx.org/java/dev/how-java-9-and-project-jigsaw-may-break-your-code/#Internal-APIs): "तो अगर' com.sun। * ', यह किसी भी गैर-ओरेकल जेडीके पर मौजूद नहीं होगा। और यदि यह उन पैकेजों में से एक से संबंधित है और' @ jdk.exported' के साथ एनोटेटेड नहीं है, तो यह जावा 9 से उपलब्ध नहीं होगा। " – jewelsea

+1

अतिरिक्त जानकारी गहने के लिए धन्यवाद! वास्तव में यह हमेशा * सूर्य * पैकेज का उपयोग करने का जोखिम है। हालांकि, मुझे लगता है कि एफएक्स टूलकिट सार्वजनिक एपीआई का हिस्सा बन जाएगा, वैसे भी अगर कोई इसका अनुसरण करने में रूचि रखता है [इस ओपनजेडीके अनुरोध को देखें] (https://bugs.openjdk.java.net/browse/JDK- 8090865) – JavierJ

+0

आपका उदाहरण काम नहीं करता है। 'exitNestedEventLoop' एक अपवाद फेंकता है कि इसे प्लेटफ़ॉर्म थ्रेड पर नहीं कहा जाता है। : -/ – Vampire

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