2013-02-03 22 views
20

लटकता है मेरे पास एक सरल जावाएफएक्स 2 ऐप है, जिसमें 2 बटन हैं, स्टार्ट एंड स्टॉप कह रहे हैं। जब स्टार्ट बटन क्लिक किया जाता है, तो मैं एक पृष्ठभूमि थ्रेड बनाना चाहता हूं जो यूआई (जैसे प्रगति पट्टी) के साथ कुछ प्रोसेसिंग और अपडेट करेगा। यदि स्टॉप बटन क्लिक किया गया है, तो मैं थ्रेड को समाप्त करना चाहता हूं।जावाएफएक्स में मल्टीथ्रेडिंग यूआई

मैंने javafx.concurrent.Task कक्षा का उपयोग करके ऐसा करने का प्रयास किया है जिसे मैंने दस्तावेज से एकत्र किया है, इसके लिए ठीक काम करेगा। लेकिन जब भी मैं स्टार्ट क्लिक करता हूं, यूआई सामान्य रहने के बजाए फ्रीज/लटकता है। यहाँ MyProcessor वर्ग के कोड है

public void start(Stage primaryStage) 
{    
    final Button btn = new Button(); 
    btn.setText("Begin"); 

    //This is the thread, extending javafx.concurrent.Task : 
    final MyProcessor handler = new MyProcessor(); 
    btn.setOnAction(new EventHandler<ActionEvent>() 
    { 
     public void handle(ActionEvent event) 
     {     
      handler.run(); 
     } 
    }); 

    Button stop = new Button(); 
    stop.setText("Stop"); 
    stop.setOnAction(new EventHandler<ActionEvent>() 
     { 
      public void handle(ActionEvent event) 
      { 
       handler.cancel(); 
      } 
     } 

    ); 
    // Code for adding the UI controls to the stage here. 
} 

:

उसके बटन दिखाने के लिए मुख्य Myprogram extends Application वर्ग से कोड है

import javafx.concurrent.Task; 
public class MyProcessor extends Task 
{ 
    @Override 
    protected Integer call() 
    { 
     int i = 0; 
     for (String symbol : feed.getSymbols()) 
     { 
      if (isCancelled()) 
      { 
       Logger.log("Stopping!"); 
       return i; 
      } 
      i++; 
      Logger.log("Doing # " + i); 
      //Processing code here which takes 2-3 seconds per iteration to execute 
      Logger.log("# " + i + ", DONE! ");    
     } 
     return i; 
    } 
} 

सुंदर आसान है, लेकिन यूआई लटका हुआ है जब भी मैं प्रारंभ क्लिक करें बटन, हालांकि कंसोल संदेश प्रदर्शित होने के लिए जारी है (Logger.log बस System.out.println करता है)

मैं गलत क्या कर रहा हूँ?

उत्तर

22

TaskRunnable लागू करता है, इसलिए जब आप फोन handler.run(); आप वास्तव में यूआई थ्रेड में call विधि चलाते हैं। वह यूआई लटकाएगा।

आपको किसी निष्पादक के माध्यम से या बस new Thread(handler).start(); पर कॉल करके पृष्ठभूमि थ्रेड में कार्य शुरू करना चाहिए।

यह the javadoc में या JavaFX concurrency tutorial में समझाया गया है (शायद स्पष्ट रूप से नहीं)।

+3

मैं आपको पर्याप्त साथी का धन्यवाद नहीं कर सकता। –

+0

मेरे पास एक और सवाल है। मैं मुख्य थ्रेड में कार्य थ्रेड की प्रगति के साथ एक लेबल अद्यतन करना चाहता हूं। इसके लिए मैं इस कोड का उपयोग कार्य में करूँगा: 'mainProg.updateStatus (i); ', और मुख्य कार्यक्रम में:' सार्वजनिक शून्य अद्यतन स्थिति (int i) {this.label.setText (i)); } '। क्या यह काम करेगा, या मुझे यूआई को अपडेट करने के लिए 'mainProg.updateStatus()' से 'platform.runLater()' का उपयोग करना चाहिए? –

+1

हां आपको इसे रन थिएटर के साथ यूआई थ्रेड में चलाने की आवश्यकता होगी - वैकल्पिक रूप से, आप अद्यतन प्रोग्रेस विधि का उपयोग कर सकते हैं (ट्यूटोरियल में उदाहरण 3 देखें) जो यूआई थ्रेड में चलाएगा। – assylias