2013-08-07 5 views
0

Я делаю простой 1v1 «частный чат», используя TCP в java. В настоящее время у меня проблема, когда я использую JButtons. Это моя первая попытка использовать JButtons и ActionListeners, поэтому я не уверен на 100%, что происходит здесь.При ударе JButton для подключения к серверу программа зависает

У меня есть два отдельных проекта для Сервера и Клиента. Чтобы скомпилировать их, это должны были быть два отдельных проекта.

Проблема возникает, когда я пытаюсь нажать кнопку либо на A: Запустить сервер B: Подключиться к серверу.

Кнопка зависает, как если бы она находилась в нажатом состоянии. Во время запуска сервера и нажатия кнопки, чтобы «убрать» кнопку, клиент должен попытаться подключиться. Сервер отправляет MOTD клиенту, и клиент должен распечатать его в текстовое окно. Он печатает MOTD только после закрытия сервера. Опять же, не знаю, почему

Серверный код:

package net.valid4life.chat; 

import java.awt.Component; 

public class Chat implements ActionListener { 

private static final long serialVersionUID = 1L; 

private static JFrame mainFrame; 
private static JPanel contentPane; 

private static JTextArea chatWindow; 
private static JTextArea serverWindow; 

private static JTextField chatBox; 
private static JTextField portBox; 

private static JLabel currentStatusL; 
private static JLabel portl; 
private static JLabel status; 

private static JButton startServerButton; 

private static int port = 1234; 
public static final int NOT_STARTED = 0; 
public static final int WAITING_FOR_CLIENT = 1; 
public static final int CONNECTED = 2; 
private static int currentStatus = NOT_STARTED; 

public static String newLine = "\n"; 

public static boolean started = false; 

static ServerSocket listener = null; 

public static void initGUI() { 

    mainFrame = new JFrame("Chat Server"); 

    mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    mainFrame.setBounds(100, 100, 450, 300); 
    contentPane = new JPanel(); 
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); 
    mainFrame.setContentPane(contentPane); 
    contentPane.setLayout(null); 

    chatWindow = new JTextArea(); 
    chatWindow.setLineWrap(true); 
    chatWindow.setEditable(false); 
    chatWindow.setBounds(220, 15, 200, 215); 
    chatWindow.setAlignmentY(Component.BOTTOM_ALIGNMENT); 
    contentPane.add(chatWindow); 

    serverWindow = new JTextArea(); 
    serverWindow.setLineWrap(true); 
    serverWindow.setEditable(false); 
    serverWindow.setBounds(10, 150, 201, 80); 
    contentPane.add(serverWindow); 

    chatBox = new JTextField(); 
    chatBox.setBounds(221, 236, 199, 20); 
    contentPane.add(chatBox); 
    chatBox.setColumns(10); 

    portBox = new JTextField("1234"); 
    portBox.setBounds(68, 37, 86, 25); 
    portBox.setActionCommand("portEnter"); 
    portBox.setColumns(10); 
    contentPane.add(portBox); 

    portl = new JLabel("Port:"); 
    portl.setFont(new Font("Times New Roman", Font.PLAIN, 16)); 
    portl.setBounds(95, 20, 64, 14); 
    contentPane.add(portl); 

    status = new JLabel("Status:"); 
    status.setFont(new Font("Times New Roman", Font.PLAIN, 16)); 
    status.setBounds(15, 239, 46, 14); 
    contentPane.add(status); 

    currentStatusL = new JLabel(changeStatus(NOT_STARTED)); 
    currentStatusL.setFont(new Font("Times New Roman", Font.PLAIN, 16)); 
    currentStatusL.setBounds(60, 239, 151, 14); 
    contentPane.add(currentStatusL); 

    startServerButton = new JButton("Start Server"); 
    startServerButton.setFont(new Font("Times New Roman", Font.PLAIN, 13)); 
    startServerButton.setBounds(60, 96, 100, 40); 
    startServerButton.setActionCommand("start"); 
    startServerButton.addActionListener(new Chat()); 
    contentPane.add(startServerButton); 

    mainFrame.setVisible(true); 

} 

public static void main(String[] args) throws IOException { 

    initGUI(); 

} 

public void actionPerformed(ActionEvent e) { 

    if ("start".equals(e.getActionCommand())) { 

     try { 
      port = Integer.parseInt(portBox.getText()); 

      startServerButton.setEnabled(false); 

      listener = new ServerSocket(port); 
      changeStatus(WAITING_FOR_CLIENT); 
      serverWindow.append("The server has started on " 
        + listener.getLocalPort()); 


     } catch (IOException e1) { 
      e1.printStackTrace(); 
     } finally { 
      try { 
       startServer(); 
      } catch (IOException e1) { 
       e1.printStackTrace(); 
      } 
     } 




    }else 
     System.out.println("YOU BROKE IT"); 

} 

public static void startServer() throws IOException { 
    try { 

     System.out.println("Looking for client"); 
     new ServerThread(listener.accept()).start(); 
     System.out.println("Found client"); 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } finally { 
     listener.close(); 
    } 
} 

public static String changeStatus(int newStatus) { 
    String newStatusText; 
    switch (newStatus) { 
    case 0: 
     newStatusText = "Server not started."; 
     break; 
    case 1: 
     newStatusText = "Waiting for client."; 
     break; 
    case 2: 
     newStatusText = "Connected to client."; 
     break; 
    default: 
     newStatusText = "Broken"; 
    } 

    currentStatus = newStatus; 
    return newStatusText; 
} 

public static class ServerThread extends Thread { 
    private Socket socket; 

    public ServerThread(Socket socket) { 
     this.socket = socket; 
     Chat.serverWindow.append("New Connection from:" 
       + socket.getInetAddress() + Chat.newLine); 
     Chat.changeStatus(CONNECTED); 
    } 

    public void run() { 
     try { 

      BufferedReader in = new BufferedReader(new InputStreamReader(
        socket.getInputStream())); 
      PrintWriter out = new PrintWriter(socket.getOutputStream(), 
        true); 

      out.println("MOTD:Welcome to the testing phase of this chat!"); 
      out.println("To view commands simply type /help"); 

      while (true) { 
       String input = in.readLine(); 
       if (input == null || input.equals(".")) { 
        break; 
       } 
       out.println(input); 
      } 
     } catch (IOException e) { 
      Chat.serverWindow.append("Error handling client"); 
     } finally { 
      try { 
       socket.close(); 
      } catch (IOException e) { 
       Chat.serverWindow 
         .append("Couldn't close a socket, what's going on?"); 
      } 
      Chat.serverWindow.append("Connection with client closed"); 
     } 
    } 

} 
} 

Код клиента:

 package net.valid4life.chat; 

import java.awt.Component; 
import java.awt.Font; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.PrintWriter; 
import java.net.Socket; 

import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JTextArea; 
import javax.swing.JTextField; 
import javax.swing.border.EmptyBorder; 

public class Chat implements ActionListener { 

private static JFrame mainFrame; 
private static JPanel contentPane; 

private static JTextArea chatWindow; 

private static JTextField chatBox; 
private static JTextField portBox; 

private static JLabel currentStatusL; 
private static JLabel portl; 
private static JLabel status; 

private static JButton connectButton; 

private static int port = 1234; 
private static String hostIP = "127.0.0.1"; 

public static final int NOT_STARTED = 0; 
public static final int WAITING_FOR_SERVER = 1; 
public static final int CONNECTED = 2; 
private static int currentStatus = NOT_STARTED; 

public static boolean serverStarted = false; 
private static JTextField IPField; 
private static JLabel IPL; 

private static BufferedReader in; 
private static PrintWriter out; 

public static void initGUI() { 

public static void connectToServer() throws Exception { 

    port = Integer.parseInt(portBox.getText()); 
    hostIP = IPField.getText(); 

    Socket socket = new Socket("127.0.0.1", 1234); 

    in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
    out = new PrintWriter(socket.getOutputStream(), true); 

    for (int i = 0; i < 3; i++) { 
     chatWindow.append(in.readLine() + "\n"); 
    } 
    // connectButton.setEnabled(false); 
} 


public static void main(String[] args) throws Exception { 
    initGUI(); 
    connectToServer(); 
} 

public void actionPerformed(ActionEvent e) { 
    if ("start".equals(e.getActionCommand())) { 
     try { 
      connectToServer(); 
     } catch (Exception e1) { 
      e1.printStackTrace(); 
     } 
    } else {System.out.println("ASDASD");} 

    } 


public static String changeStatus(int newStatus) { 
    String newStatusText; 
    switch (newStatus) { 
    case 0: 
     newStatusText = "Server not started."; 
     break; 
    case 1: 
     newStatusText = "Waiting for client."; 
     break; 
    case 2: 
     newStatusText = "Connected to client."; 
     break; 
    default: 
     newStatusText = "Broken"; 
    } 

    currentStatus = newStatus; 
    return newStatusText; 
} 

} 

Заранее спасибо за помощь!

ответ

1

Ваш код сервера работает хорошо, но ваш клиент блокирует событие Dispatching Thread при вызове connectToServer.

Диспетчерская тема событий отвечает за, среди прочего, обработку запросов на перерисовку и новых событий ввода. Если вы заблокируете этот поток по каким-либо причинам, то нет никакого способа, чтобы Event Dispatching Thread мог обрабатывать любые новые события ...

Все блокирующие или длительные задачи должны выполняться вне контекста Event Dispatching Thread ,

Посмотрите Concurrency in Swing для получения более подробной информации