[英]Can't append JTextArea
大家好,我正在嘗試編寫客戶端-服務器Tic Tac Toe游戲,但遇到了一些問題。 我真的迷路了,花了8個小時試圖找出問題所在。 目前,我正在嘗試在用戶界面中將消息追加到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
}
}
}
乍一看...
您通過調用...啟動程序。
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;
}
關於這一切停在哪里...
我的第一個想法是,“您正在與事件調度線程之外的UI組件進行交互”,但是當我回溯調用堆棧時,我發現您實際上實際上是在完全停止事件調度線程運行...
基本上。 Swing是一個單線程環境,所有事件都由一個稱為事件調度線程的線程處理,顯然,它的工作是調度所有進入您應用程序的事件,包括繪制請求。
任何阻止該線程運行的操作(例如無限while
循環和阻塞I / O,鎖定Socket
通信)都將阻止其處理任何事件請求,包括繪畫請求。
您還需要確保所有與UI的交互都是在EDT的上下文中完成的。 這意味着您不應嘗試從EDT以外的任何線程嘗試更新或修改任何UI組件。
根據您要嘗試執行的操作,最好的選擇是使用諸如SwingWorker
類的東西。
它具有在后台執行長時間運行的任務(例如Socket
通訊)的能力,同時提供了將更新同步回EDT的簡便功能。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.