Как добавить текст в TextArea с помощью ObservableList - PullRequest
0 голосов
/ 25 марта 2019

Я пытаюсь реализовать клиент-серверное приложение 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 перестал работать».Что может вызвать это?

enter image description here

ОБНОВЛЕНИЕ 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 перестал работать».

1 Ответ

1 голос
/ 26 марта 2019

Одна возможная проблема, которую я могу заметить, это то, что вы каждый раз создаете новый наблюдаемый список для нового сообщения и устанавливаете список в свой observableList с помощью setAll. Таким образом, в этой реализации никогда не будет observableList, чтобы иметь более 1 элемента.

Вам нужно создать экземпляр observableList снаружи и использовать addAll () или добавить сообщение непосредственно в observableList.

private ObservableList<String> observableLogMessages = FXCollections.observableArrayList();    
public void setLogMessages(String logMessage) {
       ArrayList<String> messagesList = new ArrayList<>();
       messagesList.add(logMessage);
       observableLogMessages.addAll(messagesList);
    }

или

private ObservableList<String> observableLogMessages = FXCollections.observableArrayList();
public void setLogMessages(String logMessage) {
   observableLogMessages.add(logMessage);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...