我正在创建一个JavaFX
应用程序,我需要GUI来与类中的其他代码进行交互,但是如果没有我做出不同的Thread
,GUI和另一段代码显然无法运行让他们继续前进。
public class Client extends Application {
public static void main(String[] args){
launch(args);
}
@Override
public void start(Stage primaryStage){
primaryStage.setTitle("Hello world!");
Button btn = new Button();
btn.setText("Run Client");
btn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
try{runClient();}catch (Exception e){System.out.println("Exception Occurred, Server is down.");}
}
});
StackPane root = new StackPane();
root.getChildren().addAll(btn);
primaryStage.setScene(new Scene(root, 500, 500));
primaryStage.show();
}
public void runClient() throws Exception {
String sentence;
String modSentence;
BufferedReader inFromUser = new BufferedReader( new InputStreamReader(System.in));
Socket clientSocket = new Socket("localhost", 6789);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
sentence = inFromUser.readLine();
outToServer.writeBytes(sentence + "\n");
modSentence = inFromServer.readLine();
System.out.println("From Server: " + modSentence);
clientSocket.close();
}
runClient()
是服务器的客户端。我需要GUI与客户端进行通信,但我不能使新的Thread
同时运行它们。
答案 0 :(得分:1)
这就是我想你想要的。您创建了一个ExecutorService来处理多线程。然后使用execute()向其提交任务。您可以阅读链接中的基础知识。
当你想从FXThread外部做一些UI时,你只需要打电话:
Platform.runLater(some Runnable with GUI code);
它在FXThread上运行。
public class Client extends Application {
//Create a ExecutorService threadpool
ExecutorService threadPool = Executors.newWorkStealingPool();
public static void main(String[] args){
launch(args);
}
@Override
public void start(Stage primaryStage){
primaryStage.setTitle("Hello world!");
Button btn = new Button();
btn.setText("Run Client");
btn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
try {
//submit a new task to the threadPool which will be executed on another thread.
threadPool.execute(new Runnable() {
@Override
public void run() {
runClient();
}
});
} catch (Exception e) {
System.out.println("Exception Occurred, Server is down.");
}
}
});
StackPane root = new StackPane();
root.getChildren().addAll(btn);
primaryStage.setScene(new Scene(root, 500, 500));
primaryStage.show();
}
public void runClient() throws Exception {
String sentence;
String modSentence;
BufferedReader inFromUser = new BufferedReader( new InputStreamReader(System.in));
Socket clientSocket = new Socket("localhost", 6789);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
sentence = inFromUser.readLine();
outToServer.writeBytes(sentence + "\n");
modSentence = inFromServer.readLine();
System.out.println("From Server: " + modSentence);
clientSocket.close();
//############# Run something in the FXThread #############\\
Platform.runLater(new Runnable() {
@Override
public void run() {
//do some UI stuff like updating labels
}
});
}
}
修改强>
您应该使用哪个ExecutorService取决于您编写的应用程序类型。 WorkStealing对您来说可能不是最好的,但我不知道您的应用程序整体如何,所以我以它为例。您可以阅读有关不同线程池here的更多信息。
编辑2:
此外,如果您使用JavaFX-8,您可以使用Lambdas,这使您的代码更短。
你可以写:
Platform.runLater(() -> {
//DO STUFF HERE
});
或
threadPool.execute(() -> {
runClient();
});
或
btn.setOnAction(event -> {
try {
...
} catch(Exception e) {
...
}
});