Java 无法在main之外成功创建JFrame类的实例

Java 无法在main之外成功创建JFrame类的实例,java,swing,class,jframe,main,Java,Swing,Class,Jframe,Main,我正在编写一个简单的加密即时通讯程序,它涉及两个项目:服务器和客户端。我让这两个工作得很好,但决定在客户端添加一个提示,询问服务器IP地址和端口号。当用户按下按钮时,我为其添加了一个操作侦听器,以创建instant messenger类的实例,该类扩展了JFrame 当从这个动作监听器内部(或者在一个单独的方法中,我已经尝试过)执行此操作时,它会创建客户机JFrame,但内部不存在任何组件。客户端正常连接到服务器 但是,当在main方法中创建客户机时,程序正常工作 以下是有效与无效的区别: ok

我正在编写一个简单的加密即时通讯程序,它涉及两个项目:服务器和客户端。我让这两个工作得很好,但决定在客户端添加一个提示,询问服务器IP地址和端口号。当用户按下按钮时,我为其添加了一个操作侦听器,以创建instant messenger类的实例,该类扩展了JFrame

当从这个动作监听器内部(或者在一个单独的方法中,我已经尝试过)执行此操作时,它会创建客户机JFrame,但内部不存在任何组件。客户端正常连接到服务器

但是,当在main方法中创建客户机时,程序正常工作

以下是有效与无效的区别:

okay.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            try{
                port = Integer.parseInt(portField.getText());
            }catch(NumberFormatException e){
                return;
            }
            serverIP = serverIPField.getText();
            dispose();
            Client c = new Client(serverIP, port);
            c.startRunning();
        }
    });
这不起作用:

okay.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            try{
                port = Integer.parseInt(portField.getText());
            }catch(NumberFormatException e){
                return;
            }
            serverIP = serverIPField.getText();
            dispose();
            Client c = new Client(serverIP, port);
            c.startRunning();
        }
    });
但是,这确实有效(同一类):

我所做的只是更改创建客户机类的位置,从类构造函数内部(称为Prompt,它创建一个JFrame来请求IP和端口)更改为main方法。我已经尝试从一个新类中创建一个客户机实例,在中使用main方法,这似乎很好

正如我前面所说的,JFrame已经创建,并且可以正常打开,它甚至成功地连接到服务器,但是没有任何组件存在(只是一个空白区域)。这很奇怪,因为在主方法内部创建时,情况并非如此

我不知道为什么会发生这种情况,所以如果有人能解释原因,那就太棒了

谢谢

编辑:我很感激我可能没有添加足够的信息。以下是客户端构造函数:

public Client(String host, int port){
    super("Instant Messenger - Client");
    this.port = port;
    serverIP = host;
    initComponents();
    Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
    setLocation(dim.width/2-this.getSize().width/2, dim.height/2-this.getSize().height/2);
    setVisible(true);
    keys = new EncryptionKeys(1024);

}
启动运行方法:

public void startRunning(){

    try{
        connectToServer();
        setupStreams();
        exchangeKeys();
        whileChatting();
    }catch(EOFException eofEx){
        showMessage("\nClient Terminated connection");
    }catch(IOException ioEx){
        showMessage("\nCould not connect to server.");
    }finally{
        closeDown();
    }
}
以及startRunning()调用的while chating方法:


dispose()关闭JFrame以提示用户。类提示符仅用于从用户获取有关IP地址和端口的信息,然后关闭,以便打开客户端。

管理Swing组件(例如绘制、侦听器等)的所有代码都发生在单个线程上:事件调度线程(EDT)。startRunning方法调用whileChatting,其中包含一个不会立即退出的do/while循环。在这两种情况下会发生什么:

  • 在main中创建客户机时,它是在主线程上创建的。这允许while循环在主线程上运行,从而允许EDT并行运行。(注意:您应该使用SwingUtilities在EDT上创建GUI)
  • 当客户机在EDT上创建时(在actionPerformed中),非终止循环将在EDT上发生,有效地锁定它,并且在它终止之前不允许它执行任何任务(换句话说,在EDT空闲之前,JFrame中的组件无法绘制、更新或反应)

  • 如果你希望执行一个长时间运行的任务,那么你应该考虑使用.< /p>什么是那个处置();方法startRunning()和客户端构造函数做什么?我猜在somwhere中有一个无限循环。你能给我们展示一下客户端的构造函数吗。1)请看2)要更快获得更好的帮助,请发布一个(最小完整的可验证示例)或(简短、自包含、正确的示例)。哈。。仍然不是MCVE的编辑。投票结束…谢谢你提供的信息!你介意解释一下我将如何向这个类添加一个线程吗?

    private void whileChatting() throws IOException{
        ableToType(true);
        do{
            try{
                message = (String) input.readObject();
                if(!keysSent){
                    if(message.substring(0, 1).equals("n")){
                        try{
                        keys.nForeign = new BigInteger(message.substring(1, message.length()));
                        }catch(NumberFormatException nfEx){
                            showMessage("Error sending keys");
                        }
                    }
                    else if(message.substring(0, 1).equals("e")){
                        try{
                        keys.eForeign = new BigInteger(message.substring(1, message.length()));
                        keysSent = true;
    
                        }catch(NumberFormatException nfEx){
                            showMessage("Error sending keys");
                        }
                    }
                    continue;
                }
                showEncryptedMessage(message);
            }catch(ClassNotFoundException cnfEx){
                showMessage("\nUser Sending error");
            }
        }while(!message.equals("SERVER - END"));
    }