Platform.runLater और टास्क JavaFX में


88

मैं इस पर कुछ शोध कर रहा हूं लेकिन मैं अभी भी बहुत कम कहने के लिए उलझन में हूं।

क्या कोई मुझे इसका ठोस उदाहरण दे सकता है कि कब उपयोग करना है Taskऔर कब उपयोग करना है Platform.runLater(Runnable);? वास्तव में क्या अंतर है? क्या इनमें से किसी का उपयोग करने का सुनहरा नियम है?

यह भी सही है कि अगर मैं गलत हूँ, लेकिन ये दोनों "ऑब्जेक्ट्स" GUI में मुख्य धागे के अंदर एक और धागा बनाने का एक तरीका नहीं है (GUI को अपडेट करने के लिए उपयोग किया जाता है)?

जवाबों:


108

Platform.runLater(...)त्वरित और सरल संचालन के लिए और Taskजटिल और बड़े कार्यों के लिए उपयोग करें ।

उदाहरण: हम Platform.runLater(...)लंबी गणना के लिए उपयोग क्यों नहीं कर सकते (नीचे संदर्भ से लिया गया)।

समस्या: पृष्ठभूमि थ्रेड जो केवल 0 से 1 मिलियन तक गिना जाता है और UI में प्रगति बार को अपडेट करता है।

कोड का उपयोग कर Platform.runLater(...):

final ProgressBar bar = new ProgressBar();
new Thread(new Runnable() {
    @Override public void run() {
    for (int i = 1; i <= 1000000; i++) {
        final int counter = i;
        Platform.runLater(new Runnable() {
            @Override public void run() {
                bar.setProgress(counter / 1000000.0);
            }
        });
    }
}).start();

यह कोड का एक गुप्त हंक है, प्रकृति के खिलाफ अपराध (और सामान्य रूप से प्रोग्रामिंग)। सबसे पहले, आप मस्तिष्क कोशिकाओं को रनवेबल्स के इस दोहरे घोंसले को देखते हुए खो देंगे। दूसरा, यह बहुत कम Runnables के साथ घटना कतार को स्वाहा करने जा रहा है - वास्तव में उनमें से एक लाख। स्पष्ट रूप से, हमें पृष्ठभूमि श्रमिकों को लिखना आसान बनाने के लिए कुछ एपीआई की आवश्यकता थी जो तब UI के साथ वापस संचार करते हैं।

कार्य का उपयोग कर कोड:

Task task = new Task<Void>() {
    @Override public Void call() {
        static final int max = 1000000;
        for (int i = 1; i <= max; i++) {
            updateProgress(i, max);
        }
        return null;
    }
};

ProgressBar bar = new ProgressBar();
bar.progressProperty().bind(task.progressProperty());
new Thread(task).start();

यह पिछले कोड में प्रदर्शित दोषों में से किसी से ग्रस्त है

संदर्भ: जावाएफएक्स 2.0 में वर्कर थ्रेडिंग


एन्सेम्बल ऐप लिंक में टास्क उदाहरण अब काम नहीं करेगा।
Cugomastik

यह सही लिंक है, लेकिन मैं इसे संपादित नहीं कर सकता क्योंकि संपादन केवल 2 वर्णों का है।
एरियस

29
यह कहना कि "त्वरित" संचालन के लिए एक और "जटिल" लोगों के लिए एक और भ्रामक है। मुख्य अंतर, सब के बाद, यह है कि एक JFX GUI धागे में कोड को कहीं और से चलाने की अनुमति देता है, और दूसरा सटीक विपरीत करता है - GUI थ्रेड से पृष्ठभूमि थ्रेड में कोड चलाने की अनुमति देता है (होने का एक बोनस जोड़कर) जीयूआई थ्रेड के साथ संवाद करने में सक्षम)।
सर्गेई टैचेनोव

मैं प्रत्येक दृश्य की एक छवि बचाना चाहता हूं - और इसमें समय लगेगा। क्या टास्क के माध्यम से अलग थ्रेड पर चलने पर यह समस्याएँ आएंगी? मुझे समझ में आया कि सभी संबंधित संबंधित कार्य FxApplication थ्रेड पर होने चाहिए।
StephenBoesch

@ सेर्गेई-टैचेनोव तो आप उन मामलों में जीयूआई थ्रेड को अपडेट करने के लिए एक टास्क थ्रेड से रनलैटर () का उपयोग करते हैं, जहां आप प्रगति जैसी एकल संपत्ति को अपडेट करने से अधिक करना चाहते हैं?
सादा

58
  • Platform.runLater: यदि आपको GUI घटक को गैर-GUI थ्रेड से अपडेट करने की आवश्यकता है, तो आप इसका उपयोग अपने अपडेट को एक कतार में रखने के लिए कर सकते हैं और इसे जल्द से जल्द GUI थ्रेड द्वारा हैंडल किया जाएगा।
  • TaskWorkerजब आप GUI थ्रेड के बाहर एक लंबे कार्य को चलाने के लिए (अपने एप्लिकेशन को ठंड से बचने के लिए) को चलाने के लिए उपयोग किए जाने वाले इंटरफ़ेस को लागू करता है, लेकिन फिर भी कुछ चरण में GUI के साथ सहभागिता करने की आवश्यकता होती है।

यदि आप स्विंग से परिचित हैं, तो पूर्व SwingUtilities.invokeLaterकी अवधारणा के बराबर और बाद की है SwingWorker

टास्क का जावदॉक कई उदाहरण देता है जो स्पष्ट करना चाहिए कि उनका उपयोग कैसे किया जा सकता है। आप संक्षिप्त नाम के ट्यूटोरियल का भी उल्लेख कर सकते हैं ।


धन्यवाद, क्या आप प्लेटफॉर्म का उपयोग करने का एक छोटा सा उदाहरण दे सकते हैं? क्या आप इसे गुई धागे के बाहर इस्तेमाल कर सकते हैं या? और डॉक्स में कार्य उदाहरण वास्तव में अस्पष्ट हैं
मार्क रासमुसेन

Yes Platform.runLater का उपयोग GUI थ्रेड के बाहर किया जा सकता है - यही इसका मुख्य उद्देश्य है। आपको इस ट्यूटोरियल को javadoc की तुलना में अधिक जानकारीपूर्ण कार्यों पर मिल सकता है ।
अस्वच्छता

3
आप इस तरह Platform.runLater का उपयोग करें:Platform.runLater(new Runnable() {public void run() {updateYourGuiHere();}});
assylias

मैं GUI घटकों का उपयोग कैसे कर पाऊंगा =: S
मार्क रासमुसेन

1
@ केविनमेडिथ टास्क की कॉल विधि को एफएक्स थ्रेड पर नहीं बुलाया जाना चाहिए - लेकिन टास्क पुल के तरीके (अपडेटप्रोग्रेस आदि) प्रदान करता है जो एफएक्स थ्रेड पर चलते हैं। अधिक जानकारी के लिए javadoc और ट्यूटोरियल्स देखें।
assylias

12

इसे अब लैम्ब्डा वर्जन में बदला जा सकता है

@Override
public void actionPerformed(ActionEvent e) {
    Platform.runLater(() -> {
        try {
            //an event with a button maybe
            System.out.println("button is clicked");
        } catch (IOException | COSVisitorException ex) {
            Exceptions.printStackTrace(ex);
        }
    });
}

8
यदि आप कोई GUI इवेंट हैंडल कर रहे हैं, तो आप GUI थ्रेड में हैं। आप रनलैटर () का उपयोग क्यों करेंगे?
टीफुटो

जब आप सही होते हैं, तो कागलर का जवाब एक लंबोदर अभिव्यक्ति के उपयोग को उजागर करने की कोशिश कर रहा था, जरूरी नहीं कि एक अच्छा कोडिंग उदाहरण दिया जाए। मैं Platform.runLater(() -> progressBar.setProgress(X/Y));
बजे

2

एक explicite Platform.runLater () का उपयोग करने का एक कारण यह हो सकता है कि आप ui में एक संपत्ति को एक सेवा (परिणाम) संपत्ति के लिए बाध्य करते हैं। इसलिए यदि आप बाउंड सर्विस प्रॉपर्टी को अपडेट करते हैं, तो आपको इसे रनलैटर () के जरिए करना होगा:

UI थ्रेड में JavaFX एप्लिकेशन थ्रेड के रूप में भी जाना जाता है:

...    
listView.itemsProperty().bind(myListService.resultProperty());
...

सेवा कार्यान्वयन (पृष्ठभूमि कार्यकर्ता) में:

...
Platform.runLater(() -> result.add("Element " + finalI));
...
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.