3

One of my implementation classes has methods that takes quite long to finish and that makes my view to freeze. So these methods must be threaded!

All these methods are returning data with HashMaps or Lists.

My controller is getting that data by calling them and then pass them to the View.

What i can't figure out is where should i create the thread. Should it be in the Controller layer or in the implementation class (and how so since i have many methods there).

Also i need to refresh the view only when the thread work is finished. These methods are going to be re-called.

I'm really lost in all those threading techniques i came across.

Controller:

SomeParser someParser = new FirstParserImpl();

HashMap<String,String> map = someParser.parseSomething();
loadTableView(map);

FirstParserImpl:

public HashMap<String,String> parseSomething() {
    //opening http connection, scrape and parse data. This takes long time!
    return map;
}
3
  • Its hard to know how to help if we don't have code. Commented Sep 23, 2016 at 17:05
  • @MichaelPickett Sorry, i thought my question would be descriptive enough. Please give me some time to post some of my code. Thanks Commented Sep 23, 2016 at 17:07
  • I tried to be simple on how i'm calling these methods for the sake of your eyes. Commented Sep 23, 2016 at 17:35

2 Answers 2

3

Combining James_D answer + Services(tutorial) you can do the below: (Basically a Service starts a Thread which will do the work you want and return a result)

public class WorkerService extends Service<Map<String, String>> {

    /**
     * Constructor
     */
    public WorkerService () {

        // if succeeded
        setOnSucceeded(s -> {
            //code if Service succeeds
        });

        // if failed
        setOnFailed(fail -> {
            //code it Service fails
        });

        //if cancelled
        setOnCancelled(cancelled->{
            //code if Service get's cancelled
        });
    }

    /**
    * This method starts the Service
    */
    public void startTheService(){
        if(!isRunning()){
           //...
           reset();
           start();
        }

    }

    @Override
    protected Task<Map<String, String>> createTask() {
        return new Task<Map<String, String>>() {
            @Override
            protected Void call() throws Exception {

                    //create a Map<String, String>
                    Map<String,String> map  = new HashMap<>();

                   //create other variables here

                   try{
                        //some code here
                        //.....do your manipulation here

                        updateProgress(++currentProgress, totalProgress);
                    }

                } catch (Exception ex) {                  
                    return null; //something bad happened so you have to do something instead of returning null
                }

                return map;
            }
        };
    }

}
Sign up to request clarification or add additional context in comments.

Comments

2

Use a Task. You can do this directly in the controller class:

Task<Map<String, String>> parseDataTask = new Task<Map<String, String>>() {

    @Override
    public Map<String, String> call() {
        SomeParser someParser = new FirstParserImpl();
        return someParser.parseSomething();
    }
};

parseDataTask.setOnSucceeded(e -> {
    Map<String,String> parseResults = parseDataTask.getValue();
    // update UI here with parseResults, e.g:
    loadTableView(parseResults);
});

Thread t = new Thread(parseDataTask);
t.setDaemon(true);
t.start();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.