我正在编写一个简单的加密即时消息,它涉及两个项目:服务器和客户端。我让这两个工作得很好,但决定在客户端添加一个提示,要求提供服务器IP地址和端口号。在用户按下按钮后,我为其添加了一个动作侦听器,以创建即时消息类的实例,该实例扩展了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();
}
});
然而,这确实有效(同一类):
public static void main(String args[]){
Client c = new Client(serverIP, port);
c.startRunning();
}
我所做的一切,就是改变Client类的创建位置,从类构造函数(称为Prompt,它创建一个JFrame以请求IP和端口)到main方法。我尝试使用main方法从一个新类创建一个Client实例,它似乎工作正常。
正如我之前所说,JFrame已经创建并且打开正常,它甚至可以成功连接到服务器,但是没有任何组件存在(只是一个空白区域)。这很奇怪,因为在main方法中创建它时不是这种情况。
我不知道为什么会这样,所以如果有人能解释原因,那就太棒了。
感谢。
编辑:我感谢我可能没有添加足够的信息。这是Client构造函数:
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聊天方法:
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"));
}
dispose()关闭JFrame以提示用户。 Prompt类仅用于从用户那里获取有关IP地址和端口的信息,然后将其关闭,以便打开客户端。
答案 0 :(得分:0)
管理Swing组件的所有代码(例如绘画,监听器等等)都发生在一个线程上:事件调度线程(EDT)。 startRunning方法调用whileChatting,它包含一个不立即退出的do / while循环。两种情景中会发生什么:
如果您希望执行长时间运行的任务,则应考虑使用Thread。