почему кадр будет перепутан !! [:-)] - PullRequest
0 голосов
/ 15 января 2010

это мои классы. Когда я запускаю свой класс MainClient, будет показан один кадр, который получает текст от клиента, а затем отправляет его на сервер. При первом нажатии кнопки «Отправить» он будет работать правильно и отправьте данные на сервер, но вдруг кадр будет сбит с толку, и я не могу ничего сделать, как написать или нажать на кнопку !!, пожалуйста, помогите мне.

Класс MainClient:

//these are in the main(String[] args)

MainFrame farme = new MainFrame();
farme.setVisible(true);
c = new Socket("localhost", 5050);

os = new PrintWriter(c.getOutputStream(), true);
is = new BufferedReader(new InputStreamReader(c.getInputStream()));

//this method is not in the main(String[] args)
public static void active() {

    String teXt = MainClient.getText();
    System.out.println(teXt);
    os.println(teXt);
    String line = is.readLine();
    System.out.println("Text received: " + line);
}

мой класс графического интерфейса, который получает текст от клиента и, нажав на кнопку отправки, отправит этот текст на сервер: (выполнено действие кнопки отправки)

 public ChatFrame(InformationClass client) {
    initComponents();


    jButton1.setEnabled(false);
    this.client = client;
    jTextArea2.setText("");

}

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
    submit();
    clear();
}
private void submit() {
    String text = jTextArea1.getText();

    jTextArea2.append(client.getCurrentName() + " : " + text + "\n");
    MainClient.setText(client.getCurrentName() + " : " + text + "\n");
    MainClient.active();
}

private void clear() {
    jTextArea1.setText("");
}

Ответы [ 2 ]

3 голосов
/ 15 января 2010

Вызов MainClient.active () блокирует ожидание ответа сокета. Поскольку он вызывается в ActionListener, он блокирует поток диспетчеризации событий Swing, в котором запускаются все события пользовательского интерфейса. Это приводит к тому, что пользовательский интерфейс не отвечает.

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

http://java.sun.com/javase/6/docs/api/javax/swing/SwingWorker.html

Если SwingWorker недоступен, вы можете сделать это примерно так:

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
    new Thread(new Runnable() {
        @Override
        public void run() {
            // This gets run in a background thread
            String text = jTextArea1.getText();
            jTextArea2.append(client.getCurrentName() + " : " + text + "\n");
            MainClient.setText(client.getCurrentName() + " : " + text + "\n");
            MainClient.active();
        }
    }).start();
}

Это ужасный способ сделать это, но он также самый короткий и будет работать на любой версии Java, имеющей Swing.

Редактировать: метод clear должен вызываться в потоке диспетчеризации событий, когда он обращается к компоненту пользовательского интерфейса - jTextArea1.setText (""). Чтобы запустить его на EDT, сделайте следующее:

SwingUtilities.invokeLater(new Runnable() { 
    @Override 
    public void run() { 
        clear();
    } 
});

Анонимные внутренние классы ужасны, особенно когда они находятся внутри других анонимных внутренних классов, но они удобны для примеров кода. В вашей реальной реализации вы должны создать класс, который реализует Runnable для выполнения исходной фоновой задачи, чтобы сделать код более читабельным.

Замыкания в Java 7 должны сделать эту задачу намного менее загроможденной.

0 голосов
/ 15 января 2010

Держу пари, что ваша проблема связана со всеми объектами ввода-вывода, которые вы не закрывали. Попробуйте очистить и закрыть объекты Reader и Writer.

os.Flush();
os.Close();
is.Flush();
is.Close();

Кроме того, закройте ваше гнездо.

c.Close();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...