1

I am starting a JavaFX gui application from another class, namely StartClient by doing.

public class StartClient extends Application {

private Table gui;

@Override
public void start(Stage stage) throws Exception {
    gui = new Table();
    gui.start(stage);

I start a Task through which I connect to a server and receive the turns assigned by the server, which I set in the gui using Platform.runLater.

Task<Void> task = new Task<Void>() {
    @Override
    protected Void call() throws Exception {
        connectToServer(); // connect to server, set up socket, i/o streams
        Object read = inputStream.readObject();

        if (read instanceof String) {
            turn = //parseInt from read
            Platform.runLater(new Runnable() {
                public void run() {
                    gui.setPlayerID(turn);
                }
            });
        }
    }
}; //end of task

What my problem is that I want to get the move made by a player if it is their turn and send it back to the server doing something like this:

if(networkClientID == gui.getState().getTurn()){
    do {
        action = Table.getAction(); //static getAction returns the move from the table if there was one
    } while (action == -1);

    outputStream.writeObject(action + ""); // write out turn
}

Do I do this on background Thread (I am reading a static variable from the gui or should I do this in javaFX thread i.e. inside Platform.runLater, I have tried it, but not getting anywhere, my program is getting stuck.)

Any suggestions, help, advise welcome on how to solve this problem. Thanks!

blo0p3r
  • 6,790
  • 8
  • 49
  • 68
Atif Hussain
  • 85
  • 1
  • 6

1 Answers1

1

IMHO the best way to do this is to have your data (ie: turns) in a seperate class.

Remember JavaFX is a MVC model. You could use a Model class to keep this information and reference this one. If you are passing a reference to your model class to another thread you would have to synchronize this one.

This way you would keep things seperate. Your Controller would only be controlling WHAT the scenes are doing. Your model would be storing the information.

This answer gives a very good starting point as to how to implement this.

For example I have a task (file watcher) and I call it as indicated below. Here is a quick snapshot of my controller :

public class myController {
    private Context context;
    private Executor executor;

    ...

    myBtn.setOnAction(new EventHandler<ActionEvent>() {
        public void handle(ActionEvent event) {
            task = new ResultFileWatcher(context);  //context is my singleton model class
            executor.execute(task);
        }
    }

    ...

}

and my class that extends class looks a bit like this. This here is my Task (note this extends the class Task) that will be running in a different Thread.

public class ResultFileWatcher extends Task<Object> {
    private Context context;

    public ResultFileWatcher(Context context) {
        this.context = context;
    }

    ...

    @Override
    protected Object call() throws Exception {
        //...
    }
}

Hope this helps!

Community
  • 1
  • 1
blo0p3r
  • 6,790
  • 8
  • 49
  • 68
  • Can I also implement the MVC model, even if I do not have FXML. I am simply creating JavaFX gui by extending Application. – Atif Hussain Feb 22 '13 at 21:09
  • Is ResultFileWatcher the controller? I am slightly confused. Or is it simply the task which listens in for changes. – Atif Hussain Feb 22 '13 at 21:11
  • Yes you can still implement the MVC model even if you do not use FXML. The lines can get a bit blurrier in this case since it's a bit harder to seperate you code, but it can be done. `ResultFileWatcher` is just my implementation of a `Task`. I will update the answer to show this a bit better. – blo0p3r Feb 22 '13 at 22:02
  • 1
    Thanks a lot for your help. I have now implement the Controller class and it works like a charm. – Atif Hussain Feb 23 '13 at 15:31