This discussion is archived
2 Replies Latest reply: Feb 1, 2013 7:28 PM by 988471 RSS

Service/Task communication with Application (UI)?

988471 Newbie
Currently Being Moderated
Joined: Feb 19, 2012
Posts: 11
     
[Post New]posted Monday, January 28, 2013 5:33:49 PM
Quote
Here's the scenario: A "start" button is clicked which sets up a Service/Task which includes I/O with a device. A changeListener is started, and the "start" button handler ends. Eventually, the changeListener detects a "change" and does its thing with the I/O device. NOW my question: How do I "notify" the user that the "change" (event) has occurred? "Update message" doesn't do anything since the "start" button routine has ended. I know I'm missing something fundamental here, but I'm baffled. (This is my first foray into the Service/Task business...) (The code in all other respects works great.) Thanks! L (Here is the boiled-down code.)
    public class TestPhServerv1Controller  {  
        @FXML  private Button btnStart;  
        USBDevice usbDevice;  //It's a Phidget.  
        @FXML  
        private void handleStartAction(ActionEvent event) {        
          //Set up Service:  
            ThrService thrService = new ThrService();   
            thrService.start();                      
            thrService.setOnSucceeded(new EventHandler<WorkerStateEvent>() {  
                @Override  
                public void handle(WorkerStateEvent wse) {  
                    txaInfo.appendText("On Succeeded: " +   
                                        wse.getSource().getValue() + " \n");  
                    txaInfo.appendText("Message: " +   
                                    wse.getSource().getMessage() + " \n");  
                }  
            });  
        } //End of Start-button-handler.  
    //-----------------------------------------------------------------------  
        public static class ThrService extends Service<String> {  
            @Override  
            protected Task createTask() {  
                return new Task<String>() {  
                    @Override protected String call() throws Exception {  
                          
                    // Omitted: section which sets up a USB I/O device, usbDevice; works great.                     
                        //Set up serverSocket, clientSocket, PrintWriter outPW, BufferedReader inBR  
                        //Send msg to client; read response. All is well...  
                    //Set up change-listener using device jar:    
                        usb-device.addInputChangeListener(new InputChangeListenerImpl(usb-device,     
                                                outPW, inBR) );       //Start InputChgListener... !!!!!  
      
                        updateMessage("Waiting for an Alarm Signal...");  
                        return "Waiting for alarm signal...";  
                     
                    } //End Task Call definition.                 
    //-----------------------------------------------------------------------                  
              //Implement InputChangeListener:  
                    class InputChangeListenerImpl implements InputChangeListener {  
      
                        private final USBDevice usbDevice;   
                        private final PrintWriter outPW;  
                        private final BufferedReader inBR;  
      
                        public InputChangeListenerImpl(USBDevice usbDevice,   
                                        PrintWriter outPW,   
                                            BufferedReader inBR) {  
                            this.usbDevice = usbDevice;  
                            this.outPW = outPW;  
                            this.inBR = inBR;  
                        }   
      
                        @Override     
                        public void inputChanged(InputChangeEvent ice) {                          
                                    outPW.println("Alarm!");                //Send to client.  
                                    String inputLine = inBR.readLine();     //Read response from client.  
                        }  //End of inputChanged method                      
                    } //End of inputChangeListener class                  
                }; //End of Task definition.              
            } //End of CreateTask.          
        } //End of Thread/Service/Task Class.        
    } //End of Controller Class.  
  • 1. Re: Service/Task communication with Application (UI)?
    RichardBair Journeyer
    Currently Being Moderated
    The first question I'd ask is whether you looked at the examples in the class documentation? The reason I ask that is because if there is an example that is missing let me know and I'll add one (I can't think of an example off hand which directly addresses this question).

    You are successfully setting the message on the service, but you then need to (using one of a number of techniques) wire the 'message' property of the Service up to some UI element. For example:
    Label label = new Label();
    ThrService service = new ThrService();
    label.textProperty().bind(service.messageProperty());
    service.start();
    (Of course the Label has to be in the scene graph somewhere). The label's text property is bound to the service's message property. Whenever you update the message, the label's text will be automatically kept in sync.

    Now, you also appear to have a problem in your service's task implementation. The problem is that the service will say it has completed almost immediately (I'm assuming the usb-device.addInputChangeListener doesn't block). As soon as the task's call method completes, the Service will think it has finished and move to the succeeded state. The way the Service is intended to be used is that as long as the background operation is happening, it should be in the RUNNING state.

    Which USB library are you using? I'll give it a try.
  • 2. Re: Service/Task communication with Application (UI)?
    988471 Newbie
    Currently Being Moderated
    Richard, thank you for the info. I've concluded I need to completely restructure my Service/Task! I've also plowed through the ProJavaFX (book) chapter on Bindings and I'm mostly through the chapter on Concurrency. I have a lot of learning to do yet. I'm not at all sure I won't have more questions later, but I need to struggle with it a bit more (which is how I learn, unfortunately). I DID do a simple binding like you suggested, just to show myself that it works, and I think that will be the key once I get the pieces reorganized properly. Thanks for the inspiration to re-think it! L

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points