【问题标题】:Java SWING GUI leaves to console after running threadJava SWING GUI 在运行线程后离开控制台
【发布时间】:2019-04-09 13:50:21
【问题描述】:

所以我有一个名为 ChatClient 的类,它与 ChatServer 类一起作为多聊天加密信使。所以我有一些如下所示的 Swing 组件,并在我的 ChatClient 构造函数中初始化它们: 公共静态 ChatClient 客户端;

// GUI ELEMENTS
BufferedReader in;
PrintWriter out;
JFrame frame; 
public static JTextArea userText;
JTextArea DisplayMessage;
JLabel connectInfo;
JToggleButton tglbtnConnect;
JToggleButton tglbtnDisconnect;
JLayeredPane layeredPane;
JLayeredPane layeredPane_1;
JRadioButton rdbtnAes;
JRadioButton rdbtnDes;
JRadioButton rdbtnCbs;
JRadioButton rdbtnOfb;
JPanel panel;
JLabel lblServer;
JLabel lblText;
JLabel lblCryptText;
JTextArea encryptedText;
JToggleButton tglbtnNewToggleButton;
JToggleButton tglbtnNewToggleButton_1;

然后我有 run() 方法来提供消息。我的问题是,当我使用下面的 main 方法时,当框架打开(最初它询问用户名)时,我在我的连接按钮中运行 run() 方法,并且我希望它在连接后运行该方法按钮:

public static void main(String[] args) throws Exception {
       client = new ChatClient();
       client.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       client.frame.setVisible(true);
    }

tglbtnConnect = new JToggleButton("Connect"); tglbtnConnect.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                try {
                    client.run();
                    connectInfo.setText("Connected");
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }
        });
        tglbtnConnect.setBounds(12, 36, 106, 25);

问题是当我点击连接时,它会询问用户名,然后它会离开 gui,因此我无法使用任何组件。任何帮助或提示表示赞赏。你可以在下面找到我的全班:https://pastebin.com/N7Ncz7yk

你可以在下面找到我的运行方法:

private void run() throws Exception {

        // Make connection and initialize streams
        String serverAddress = "localhost";
        Socket socket = new Socket(serverAddress, 9001);
        in = new BufferedReader(new InputStreamReader(
            socket.getInputStream()));
        out = new PrintWriter(socket.getOutputStream(), true);

        // Process all messages from server, according to the protocol.
        while (true) {
            String line = in.readLine();
            if (line.startsWith("SUBMITNAME")) {
                out.println(getName());
            } else if (line.startsWith("NAMEACCEPTED")) {
                userText.setEditable(true);
            } else if (line.startsWith("MESSAGE")) {
                int idx = line.lastIndexOf(">");
                String mssg = line.substring(idx + 1);
                if(rdbtnAes.isSelected() && rdbtnCbs.isSelected()){
                     String key="MZygpewJsCpRrfOr";
                    byte[] encryptionKey = "MZygpewJsCpRrfOr".getBytes();
                    //byte[] plainText = input.getBytes();
                    AES advancedEncryptionStandard = new AES(encryptionKey);
                    byte[] cipherText = advancedEncryptionStandard.encrypt(mssg,key,0);
                    String decryptedCipherText = advancedEncryptionStandard.decrypt(cipherText,key,0);
                    String encrytepdText=new String(cipherText);

                    // APPEND MESSAGE
                     DisplayMessage.append(encrytepdText + "\n" + line.substring(8,idx + 1) + decryptedCipherText + "\n");

                }
                else if(rdbtnAes.isSelected() && rdbtnOfb.isSelected()){
                    String key="MZygpewJsCpRrfOr";
                    byte[] encryptionKey = "MZygpewJsCpRrfOr".getBytes();
                    //byte[] plainText = input.getBytes();
                    AES advancedEncryptionStandard = new AES(encryptionKey);
                    byte[] cipherText = advancedEncryptionStandard.encrypt(mssg,key,1);
                    String decryptedCipherText = advancedEncryptionStandard.decrypt(cipherText,key,1);
                    String encrytepdText=new String(cipherText);

                    // APPEND MESSAGE
                     DisplayMessage.append(encrytepdText + "\n" + line.substring(8,idx + 1) + decryptedCipherText + "\n");

                }
                else if(rdbtnDes.isSelected()&& rdbtnCbs.isSelected()){
                    DES desEncryption=new DES(mssg,0);
                     DisplayMessage.append(desEncryption.encryptedData + "\n" + line.substring(8,idx + 1) + desEncryption.decryptedMessage + "\n");
                }
                else if(rdbtnDes.isSelected() && rdbtnOfb.isSelected()){
                    DES desEncryption=new DES(mssg,1);
                    DisplayMessage.append(desEncryption.encryptedData + "\n" + line.substring(8,idx + 1) + desEncryption.decryptedMessage + "\n");
                }


            }
        }
    }

【问题讨论】:

  • 我看不到 pastebin 代码。您是否正在关闭 ChatClient.frame 以便程序退出(请参阅选项 EXIT_ON_CLOSE)?
  • 请发布 MVP。有数百行难以理解。
  • @michaek 它是可见的。是的,就像关闭时退出一样,这是默认设置。跟这个有关系吗?
  • 除了建议:小心使用静态。阅读有关 MVC(模型视图控制器)和关注点分离的内容并尝试更改代码。它的编写方式是一堂课。此外,client.frame 很可能是一个发现,因为不应在此级别访问框架。
  • “它离开 gui”是什么意思...?

标签: java multithreading swing user-interface chat


【解决方案1】:

在您的client.run() 方法中,您可以通过编写while (true) 而不使用breakreturn 创建一个无限循环。因为此方法是从 ActionListener 的 UI 线程调用的,所以您的 UI 卡住/没有响应“不可用”。

解决方案:创建一个新的Thread,它运行服务器监听代码并从此线程更新 UI。 Connect 应该只使用thread.start() 启动该线程,然后返回。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-05
    • 1970-01-01
    • 1970-01-01
    • 2011-02-17
    • 2011-05-24
    • 2022-11-17
    相关资源
    最近更新 更多