2013-11-26 2 views
0

Привет всем Я пытаюсь запрограммировать клиентскую версию Tic Tac Toe, и у меня возникают проблемы. Я действительно потерялся и потратил 8 часов, пытаясь понять, что случилось. В настоящее время я пытаюсь добавить сообщение в JTextArea в свой пользовательский интерфейс. Но он не хочет ничего добавлять в текстовую область. Любая помощь будет принята с благодарностью.Не удается добавить JTextArea

public class GameUI extends javax.swing.JFrame{ 
    /** 
    * The circle icon 
    */ 
    private ImageIcon circle = new ImageIcon("data/tile-05.png"); 

    /** 
    * The cross icon 
    */ 
    private ImageIcon cross = new ImageIcon("data/tile-03.png"); 

    /** 
    * keeps track of whose turn it is 
    */ 
    private int turn = 1; 

    /** 
    * Where the hear of the game runs 
    */ 
    private Client game; 

    /** 
    * This is an 2d array that stores all the buttons 
    */ 
    JButton[][] buttons = new JButton[3][3]; 

    /** 
    * Class constructor Creates new form GameUI 
    */ 
    public GameUI() { 
     startGame("Tic Tac"); 
     storeButtons(); 
    } 

    public void connectionError(String message) { 
     JOptionPane.showMessageDialog(rootPane, message, "Tic Tac Toe", 0); 
    } 

    private void startGame(String message) { 
     String host, login; 
     int temp = 0; 

     JTextField hostText = new JTextField(); 
     JTextField loginText = new JTextField(); 

     Object[] info = {"Host: ", hostText, "login ID: ", loginText}; 

     temp = JOptionPane.showConfirmDialog(rootPane, info, message, JOptionPane.OK_CANCEL_OPTION); 

     while (true) { 
      try { 
       if (temp == JOptionPane.OK_OPTION) { 
        host = hostText.getText(); 
        login = loginText.getText(); 

        game = new Client(login, host, 5555, this); //Initializes the game 
        initComponents(); 
        break; 
       } else if (temp == JOptionPane.CANCEL_OPTION || temp == JOptionPane.CLOSED_OPTION) { 
        System.exit(0); 
       } 
      } catch (IOException e2) { 
       connectionError("Can't connect to the game server!"); 
       System.exit(0); 
      } 
     } 
     //Scrubs memory for more RAM :) 
     login = null; 
     host = null; 

    } 

    private void storeButtons() { 
     buttons[0][0] = btnTicTac1; 
     buttons[0][1] = btnTicTac2; 
     buttons[0][2] = btnTicTac3; 
     buttons[1][0] = btnTicTac4; 
     buttons[1][1] = btnTicTac5; 
     buttons[1][2] = btnTicTac6; 
     buttons[2][0] = btnTicTac7; 
     buttons[2][1] = btnTicTac8; 
     buttons[2][2] = btnTicTac9; 
    } 

    private void btnOpponentSendActionPerformed(java.awt.event.ActionEvent evt) {             
     String message = txtOpponentMessage.getText(); 
     game.handleMessageFromGameUI("#Opponent " + message); //Specified the game text area 
     txtOpponentMessage.setText(""); 
    }            

    private void btnLobbySendActionPerformed(java.awt.event.ActionEvent evt) {            
     String message = txtLobbyMessage.getText(); 
     game.handleMessageFromGameUI("#lobby " + message); //Specified the lobby text area 
     txtLobbyMessage.setText(""); 
    }             

    public void setTurn(int value) { 
     turn = value; 
    } 

    public void appendLobbyArea(String message) { 
     txtLobbyTextArea.append(message); 
    } 

    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String args[]) { 
     /* Create and display the form */ 
     java.awt.EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 

       GameUI cgui = new GameUI(); 
       cgui.setVisible(true); 
      } 
     }); 

    } 

    // Variables declaration - do not modify      
    private javax.swing.JButton btnLobbySend; 
    private javax.swing.JButton btnOpponentSend; 
    private javax.swing.JButton btnTicTac1; 
    private javax.swing.JButton btnTicTac2; 
    private javax.swing.JButton btnTicTac3; 
    private javax.swing.JButton btnTicTac4; 
    private javax.swing.JButton btnTicTac5; 
    private javax.swing.JButton btnTicTac6; 
    private javax.swing.JButton btnTicTac7; 
    private javax.swing.JButton btnTicTac8; 
    private javax.swing.JButton btnTicTac9; 
    private javax.swing.JComboBox jComboBox1; 
    private javax.swing.JLabel jLabel1; 
    private javax.swing.JLabel jLabel2; 
    private javax.swing.JLabel jLabel3; 
    private javax.swing.JScrollPane jScrollPane1; 
    private javax.swing.JScrollPane jScrollPane2; 
    private javax.swing.JScrollPane jScrollPane4; 
    private javax.swing.JLabel lblOpponentSelect; 
    private javax.swing.JList txtClientList; 
    private javax.swing.JTextArea txtGameTextArea; 
    private javax.swing.JTextField txtLobbyMessage; 
    private javax.swing.JTextArea txtLobbyTextArea; 
    private javax.swing.JTextField txtOpponentMessage; 
    // End of variables declaration     

    public void display(String message) { 
     System.out.println(message); 
    } 
} 

Следующая часть - средний класс. Все сообщения проходят через этот класс для манипуляций.

public class Client extends AbstractClient { 

/** 
* GameUI Object. Used to communicate from the game to the end user 
*/ 
private GameUI gameUI; 

/** 
* This keeps track of whose turn it is. Defaults to x. 
*/ 
private int turn = 1; 

public Client(String userID, String host, int port, GameUI gameUI) throws IOException { 
    super(host, port); 
    this.gameUI = gameUI; 
    openConnection(); 
    sendToServer("#login " + "<" + userID + ">"); 
} 

@Override 
public void handleMessageFromServer(Object msg) { 
    while (isConnected()) { 
     if (msg.toString().startsWith("#")) { 
      doFunction(msg); 
     } else { 

     } 
    } 
} 

public void handleMessageFromGameUI(String message) { 
    try { 
    sendToServer(message); 
    } catch (IOException e) { 
     gameUI.display("Can't send message to server"); 
     System.exit(0); 
    } 
} 

private void doFunction(Object msg) { 
    if (msg.toString().startsWith("#connectedClient")) { 
     gameUI.appendLobbyArea(msg.toString().substring(17) + " connected"); 
    } else if (msg.toString().startsWith("#disconnectedClient")) { 
     gameUI.appendLobbyArea(msg.toString().substring(20) + " disconnected"); 
    } else if (msg.toString().startsWith("#lobby")) { 
     gameUI.appendLobbyArea(msg.toString().substring(7)); //Add client username 
    } 
} 

}

+0

Для лучшей помощи скорее, опубликуйте [SSCCE] (http://sscce.org/). –

ответ

1

На первый взгляд ...

Вы начинаете программу по телефону ...

public static void main(String args[]) { 
    /* Create and display the form */ 
    java.awt.EventQueue.invokeLater(new Runnable() { 
     @Override 
     public void run() { 

      GameUI cgui = new GameUI(); 
      cgui.setVisible(true); 
     } 
    }); 

} 

Который называет ...

public GameUI() { 
    startGame("Tic Tac"); 
    storeButtons(); 
} 

Что вызывает ...

private void startGame(String message) { 
    String host, login; 
    int temp = 0; 

    JTextField hostText = new JTextField(); 
    JTextField loginText = new JTextField(); 

    Object[] info = {"Host: ", hostText, "login ID: ", loginText}; 

    temp = JOptionPane.showConfirmDialog(rootPane, info, message, JOptionPane.OK_CANCEL_OPTION); 

    while (true) { 
     try { 
      if (temp == JOptionPane.OK_OPTION) { 
       host = hostText.getText(); 
       login = loginText.getText(); 

       game = new Client(login, host, 5555, this); //Initializes the game 
       initComponents(); 
       break; 
      } else if (temp == JOptionPane.CANCEL_OPTION || temp == JOptionPane.CLOSED_OPTION) { 
       System.exit(0); 
      } 
     } catch (IOException e2) { 
      connectionError("Can't connect to the game server!"); 
      System.exit(0); 
     } 
    } 
    //Scrubs memory for more RAM :) 
    login = null; 
    host = null; 

} 

Что о том, где все это останавливает ...

Моя первая мысль была, «вы взаимодействуете с компонентами пользовательского интерфейса за пределами Event диспетчерские тему», но когда я снова отслеживаются стек вызовов, Я обнаружил, что вы фактически прекращаете запуск Event Dispatching Thread ...

В принципе. Swing - это однопоточная среда, все события обрабатываются одним потоком, известным как «Диспетчер событий», задачей которого является, очевидно, отправка всех событий, поступающих в ваше приложение, включая запросы на рисование.

Любое действие, которое останавливает выполнение этого потока (например, бесконечные while циклов и блокирование ввода-вывода, блокировка связи Socket), не позволит ему обрабатывать любые запросы на события, в том числе запросы на краску.

Вы также обязаны обеспечить, чтобы все взаимодействия с пользовательским интерфейсом выполнялись из контекста EDT. Это означает, что вы никогда не должны пытаться обновлять или изменять какой-либо компонент пользовательского интерфейса из любого потока, кроме EDT.

Основываясь на том, что вы пытаетесь сделать, вам лучше всего использовать что-то вроде SwingWorker.

Он имеет возможность выполнять длительные задачи в фоновом режиме (как Socket Comms), обеспечивая легкую функциональность для синхронизации обновлений обратно в EDT

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

+0

Итак, если я правильно понимаю это, я должен использовать SwingWorker для моего метода startGame (String message), чтобы EDT мог продолжить работу без прерывания моего цикла while (true)? –

+0

Вам также необходимо изменить способ работы программы, так как вы никогда не должны вносить изменения в интерфейс пользователя вне EDT. Это означает, что вы не можете просто перемещать содержимое 'startGame' в' SwingWorker', так как это создаст больше проблем.Вам нужно подумать о том, как преодолеть разрыв между потоком ('SwingWorker') и UI – MadProgrammer

+0

+1, как долго я не видел здесь CANCEL_OPTION/CLOSED_OPTION – mKorbel

Смежные вопросы