Я пытаюсь реализовать клиент-серверное приложение JavaFx, которое обменивается сообщениями.Я пытаюсь добавить текст (на стороне сервера) в TextArea из потока, который обрабатывает клиентские запросы, проходящие через методы, помещенные в модель, которая взаимодействует с контроллером.
Например: Впоток, который обрабатывает клиентские запросы, если пользователь успешно вошел в систему -> , я вызываю метод setLogMessages ("пользователь вошел в систему"), который находится в модели, и устанавливаю мой observableList -> Строки отправляются в контроллер, который должен добавить их в TextArea.
Я написал этот код:
Модель сервера
public class ServerModel {
private ObservableList<String> observableLogMessages;
//other code
/**
* This method starts the server connection.
*/
public void startServerConnection() {
serverRequests.serverConnection();
}
public void setLogMessages(String logMessage) {
observableLogMessages = FXCollections.observableArrayList();
ArrayList<String> messagesList = new ArrayList<>();
messagesList.add(logMessage);
observableLogMessages.setAll(messagesList);
}
public ObservableList<String> getLogMessages() {
return observableLogMessages;
}
public void changeObserver(ListChangeListener<String>messagesChangeListener) {
observableLogMessages.addListener(messagesChangeListener);
}
// other code
}
Контроллер сервера
public class LogController {
private final ServerModel serverModel = ServerModel.builServerModel();
@FXML
private ResourceBundle resources;
@FXML
private URL location;
@FXML
private AnchorPane logAnchorPane;
@FXML
public TextArea logTextArea;
@FXML
private JFXButton logClearButton;
@FXML
void initialize() {
logTextArea.setEditable(false);
serverModel.changeObserver((ListChangeListener.Change<? extends String> messagesChange) -> {
if (messagesChange.next() && messagesChange.wasAdded()) {
ObservableList<String> logMessages = serverModel.getLogMessages();
for (int i = 0; i < logMessages.size(); i++) {
logTextArea.appendText(logMessages.get(i));
}
}
});
}
}
Поток, обрабатывающий клиентские запросы
public class ServerRequests {
//other code
public void serverConnection() {
ServerSocket serverSocket = null;
try {
//initialize the Server Socket class
serverSocket = new ServerSocket(PORT);
} catch (IOException e) {
System.out.println("I/O error: " + e);
}
while (true) {
System.out.println("waiting for clients...");
try {
clientSocket = serverSocket.accept();
ClientRequest clientRequest = new ClientRequest(clientSocket);
Runnable runnable = clientRequest;
Thread thread = new Thread(runnable);
thread.setDaemon(true);
thread.start();
} catch (IOException e) {
System.out.println("I/O error: " + e);
} catch (ClassNotFoundException ex) {
Logger.getLogger(ServerRequests.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public class ClientRequest extends Thread {
// other code
public ClientRequest(Socket socket) throws ClassNotFoundException {
// other code
}
@Override
public void run() {
// if user successfully login add, this message to the TextArea.
serverModel.setLogMessages("User successfully connected.");
}
// other code
}
}
Если я запускаю этот код,сообщение "Пользователь успешно подключен." не добавляется в TextArea , и я также пытался напечатать в модели размер observableList, который всегда остается равным 1, даже если я пытаюсь добавить несколько сообщений.Я прочитал много подобных вопросов здесь и попытался исправить с помощью Platform.runLater (), но с TextArea ничего не произошло, и я не могу понять, почему!
ОБНОВЛЕНИЕ
Я попытался добавить кнопку в свой журнал, просто чтобы увидеть, если при нажатии она вернет сообщение.Я обнаружил, что не могу даже щелкнуть по нему, потому что все зависает (на стороне сервера), и появляется сообщение об ошибке «Двоичный файл Java (TM) Platform SE перестал работать».Что может вызвать это?
ОБНОВЛЕНИЕ LogController ПОСЛЕ ПРЕДЛОЖЕНИЙ
public class LogController {
//serverModel
ObservableList<String> logMessages;
@FXML
private AnchorPane logAnchorPane;
@FXML
private TextArea logTextArea;
@FXML
private Label serverLogLabel;
@FXML
private JFXButton logClearButton;
@FXML
void initialize() {
logTextArea.setEditable(false);
logTextArea.appendText("Appending"); //This append text correctly
Platform.runLater(() -> {
serverModel.changeObserver((ListChangeListener.Change<? extends String> messagesChange) -> {
if (messagesChange.next() && messagesChange.wasAdded()) {
ObservableList<String> logMessages = serverModel.getLogMessages();
for (int i = 0; i < logMessages.size(); i++) {
logTextArea.appendText(logMessages.get(i));
}
}
});
});
logClearButton.setOnAction((ActionEvent event) -> {
System.out.println("Clear clicked");
});
}
}
Все еще не печатает в TextArea и все еще застревает при открытии + сообщение об ошибке «Java (TM) Platform SE перестал работать».