简体   繁体   English

无法附加JTextArea

[英]Can't append JTextArea

Hey Everyone I'm trying to program a client-server Tic Tac Toe game and I'm running into some problems. 大家好,我正在尝试编写客户端-服务器Tic Tac Toe游戏,但遇到了一些问题。 I'm really lost and have spent 8 hours trying to figure out what's wrong. 我真的迷路了,花了8个小时试图找出问题所在。 Currently I'm trying to append a message to a JTextArea in my user interface. 目前,我正在尝试在用户界面中将消息追加到JTextArea。 But it doesn't want to add anything to the text area. 但是它不想在文本区域添加任何内容。 Any help would be greatly appreciated. 任何帮助将不胜感激。

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);
    }
}

The next part is a middleman class. 下一部分是中间人课程。 All messages pass through this class for manipulation. 所有消息都通过此类进行操作。

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
    }
}

} }

At first glance... 乍一看...

You start the program by calling... 您通过调用...启动程序。

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);
        }
    });

}

Which calls... 哪个电话...

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

Which calls... 哪个电话...

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;

}

Which about where it all stops... 关于这一切停在哪里...

My first thought was, "you're interacting with UI components outside of the Event Dispatching Thread", but when I back tracked the call stack, I found that you are actually stopping the Event Dispatching Thread from running altogether... 我的第一个想法是,“您正在与事件调度线程之外的UI组件进行交互”,但是当我回溯调用堆栈时,我发现您实际上实际上是在完全停止事件调度线程运行...

Basically. 基本上。 Swing is a single threaded environment, all events are processed by a single thread, known as the Event Dispatching Thread, whose job it is to, obviously, dispatch all the events coming into your application, including paint requests. Swing是一个单线程环境,所有事件都由一个称为事件调度线程的线程处理,显然,它的工作是调度所有进入您应用程序的事件,包括绘制请求。

Any action that stops this thread from running (like infinite while loops and blocking I/O, lock Socket communications) will prevent it from processing any event requests, including, paint requests. 任何阻止该线程运行的操作(例如无限while循环和阻塞I / O,锁定Socket通信)都将阻止其处理任何事件请求,包括绘画请求。

You are also required to ensure that all interactions with the UI are done from within the context of the EDT. 您还需要确保所有与UI的交互都是在EDT的上下文中完成的。 This means you should never try and update or modify any UI component from any thread other then the EDT. 这意味着您不应尝试从EDT以外的任何线程尝试更新或修改任何UI组件。

Based on what it appears you are trying to do, you best bet would be to use something like a SwingWorker . 根据您要尝试执行的操作,最好的选择是使用诸如SwingWorker类的东西。

It has the ability to execute long running tasks in the background (like Socket comms) while providing easy functionality for syncing updates back to the EDT 它具有在后台执行长时间运行的任务(例如Socket通讯)的能力,同时提供了将更新同步回EDT的简便功能。

Take a look at Concurrency in Swing for more details 查看Swing中的并发以了解更多详细信息

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM