Не могу добавить в JTextArea - PullRequest
       7

Не могу добавить в JTextArea

0 голосов
/ 23 октября 2018

Я пытаюсь создать текстовый чат с Java.У меня есть сервер и клиент, которые соединяются друг с другом с помощью потоков и отправляют данные с использованием objectInputStream и objectOutputStream.

У меня есть графический интерфейс как для клиента, так и для сервера.Я создал эти графические интерфейсы, используя форму графического интерфейса intellij.

Изображение графического интерфейса сервера

Проблема, с которой я столкнулся, заключается в том, что я пытаюсь отобразить текст в графическом интерфейсе сервера.,Я могу добавить к графическому интерфейсу, если я вызываю свой метод relayToAll из actionlistener JTextField, который затем отправляет сообщение всем клиентам и распечатывает его в графическом интерфейсе сервера.

Если я пытаюсь вызвать тот же метод изгде я получаю ввод, тогда добавление к текстовой области не работает.

Может кто-нибудь сказать мне, почему не добавляется?

Спасибо

public class ServerTest {
private JTextField textField1;
private JTextArea textArea1;
private JPanel Panel;
static private ObjectOutputStream objectOutputStream;
static private ObjectInputStream objectInputStream;
static private Socket client;
static private ArrayList<Socket> clients = new ArrayList<Socket>();
static private ArrayList<ObjectOutputStream> objectOutputStreams = new ArrayList<>();

public void relayToAll(String message){
    try {
        for(int i = 0; i < clients.size(); i++) {
            ObjectOutputStream output = objectOutputStreams.get(i);
            output.writeObject(message);
            output.flush();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    appendTextArea(message);
}

public void appendTextArea(String text){
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            System.out.println("This should go to the Server GUI: " + text);
            textArea1.append(text + "\n");
        }
    });
}

public ServerTest() {

    textField1.addActionListener(e -> {
        System.out.println(e.getActionCommand());
        relayToAll(e.getActionCommand());
        textField1.setText("");
    });
}

public void ReadInput(ObjectInputStream input, int port){
    try {
        String oldMessage = "";
        while (true) {
            String message = (String) input.readObject();
            if (message != oldMessage){
                System.out.println(port + ": " + message);
                oldMessage = message;
                relayToAll(port + ": " + message);
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
}


public void IOSetup(){
    try {
        ServerSocket serverSocket = new ServerSocket( 6969 );

        ExecutorService executor = Executors.newFixedThreadPool(5);

        System.out.println("server on\n");
        for (int i = 0; i < 5; i++){

            client = serverSocket.accept();
            clients.add(client);
            System.out.println("Connection from: "+ client.getPort());

            objectOutputStream = new ObjectOutputStream(client.getOutputStream());
            objectOutputStreams.add(objectOutputStream);

            objectInputStream = new ObjectInputStream(clients.get(i).getInputStream());


            executor.submit(() -> {
                ReadInput(objectInputStream, client.getPort());
            });
        }


    } catch (IOException e) {
        e.printStackTrace();
    }

}

public static void main(String[] args) {

    JFrame frame = new JFrame("Server");
    frame.setContentPane(new ServerTest().Panel);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
    frame.setVisible(true);

    ServerTest application = new ServerTest();


    application.IOSetup();

}

1 Ответ

0 голосов
/ 23 октября 2018

На самом деле у вас какая-то глупая ошибка.Пожалуйста, проверьте строки (A) и (B) ниже:

public static void main(String[] args) {
    JFrame frame = new JFrame("Server");
    frame.setContentPane(new ServerTest().Panel); //  *************** (A)
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
    frame.setVisible(true);
    ServerTest application = new ServerTest();  //  *************** (B)
    application.IOSetup();
}

Вы видите проблему?Вы создаете TWO ServerTest объекты, один из которых имеет переменную Panel, добавленную в JFrame и которая отображается, а другой настроен для обмена данными ввода-вывода.ActionListener изменяет состояние отображаемой JTextArea, в то время как обмен данными ввода-вывода изменяет состояние JTextArea, которое находится во втором экземпляре ServerTest, который не отображается.

Одним из улучшений является создание только одного экземпляра:

public static void main(String[] args) {

    ServerTest application = new ServerTest();  // create one instance

    JFrame frame = new JFrame("Server");
    // frame.setContentPane(new ServerTest().Panel);

    frame.setContentPane(application.Panel);     // and use in both places

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
    frame.setVisible(true);

    //ServerTest application = new ServerTest();
    application.IOSetup();                 // and use in both places
}

Другие проблемы:

  • У вас есть долго работающий код, долго работающий и блокирующий вфоновый поток, и это потенциально опасно, и единственная причина, по которой ваш графический интерфейс не зависает, заключается в том, что вы запускаете графический интерфейс (неправильно) в главном потоке и отключаете поток событий Swing.Более подробно об этом вы можете прочитать о параллелизме Swing: Урок: параллелизм в Swing
  • Вы захотите изучить и использовать Соглашения об именах Java .Имена переменных должны начинаться со строчной буквы, а имена классов - с заглавной.Изучение этого и последующее позволит нам лучше понять ваш код и позволит вам лучше понять код других.
...