0
IM在JavaFX的工作UI。我創建了一個echo ServerClient系統,即將數據發送到服務器並返回到所有客戶端(廣播)。它在客戶端向服務器發送數據時工作正常。但是,當服務器將數據發送回客戶端時,該幀會凍結。下面是代碼: 客戶:的BufferedReader凍結在JavaFX
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.rajeshpatkar;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
/**
*
* @author Dimpi
*/
public class Client extends Application{
int flag = 999;
public void start(Stage primaryStage) throws Exception {
Connect cnn = new Connect(primaryStage);
cnn.sconnect();
}
public static TextArea Frame(Stage primaryStage, PrintWriter nos, BufferedReader nis) throws IOException {
TextField tf = new TextField();
TextArea ta = new TextArea();
Button btn = new Button();
btn.setText("Click");
btn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
String get = tf.getText();
nos.println(get);
try {
Connect.chat(nis,ta);
} catch (IOException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
BorderPane root = new BorderPane();
root.setCenter(ta);
BorderPane panel = new BorderPane();
root.setBottom(panel);
panel.setCenter(tf);
panel.setRight(btn);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
return ta;
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
class Connect {
Stage primaryStage;
Connect(Stage primaryStage) {
this.primaryStage = primaryStage;
}
public void sconnect() throws IOException {
System.out.println("Client Signing IN");
Socket soc = new Socket("localhost", 9081);
PrintWriter nos = new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(soc.getOutputStream()
)
), true);
BufferedReader nis = new BufferedReader(
new InputStreamReader(soc.getInputStream()
)
);
TextArea ta=Client.Frame(primaryStage, nos, nis);
}
public static void chat(BufferedReader nis,TextArea ta) throws IOException{
String set = nis.readLine();
while (!set.equals("End")) {
ta.appendText(set+"\n");
set = nis.readLine();
}
}
}
Server: /*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.rajeshpatkar;
import static com.rajeshpatkar.Server.a1;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
/**
*
* @author Dimpi
*/
public class Server extends Application {
public static ArrayList<PrintWriter> a1=new ArrayList<PrintWriter>();
@Override
public void start(Stage primaryStage) throws IOException {
System.out.println("Server signing IN");
ServerSocket ss = new ServerSocket(9081);
for (int i = 0; i < 5; i++) {
Socket soc = ss.accept();
Conversation c = new Conversation(soc);
c.start();
}
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
class Conversation extends Thread {
Socket soc;
Conversation(Socket soc) {
this.soc = soc;
}
public void run() {
try {
PrintWriter nos = new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(soc.getOutputStream()
)
), true);
BufferedReader nis = new BufferedReader(
new InputStreamReader(soc.getInputStream()
)
);
Server.a1.add(nos);
String get=nis.readLine();
while(true){
for(PrintWriter p:a1){
System.out.println(get);
p.println(get);
}
get=nis.readLine();
}
} catch (Exception e) {
}
}
}
可能長時間運行的任務(例如採取可能需要幾秒鐘的連接),應該從JavaFX的幽後臺線程來完成應用線程。檢查[this](https://docs.oracle.com/javase/8/javafx/interoperability-tutorial/concurrency.htm)鏈接如何執行此操作。如果你已經實現了這個邏輯,你的應用程序不會凍結。 –