Java 爪哇Swing&;套接字通讯器堆栈溢出错误
我正在使用套接字和JSwing制作一个简单的客户机-服务器messenger对,最近遇到了一个StackOverflow错误。我知道(或至少认为)它是由一个递归函数(我认为我没有,但我可能有)引起的,该函数没有正确的终止条件(这是否意味着类似于switch语句中的Java 爪哇Swing&;套接字通讯器堆栈溢出错误,java,swing,sockets,stack-overflow,Java,Swing,Sockets,Stack Overflow,我正在使用套接字和JSwing制作一个简单的客户机-服务器messenger对,最近遇到了一个StackOverflow错误。我知道(或至少认为)它是由一个递归函数(我认为我没有,但我可能有)引起的,该函数没有正确的终止条件(这是否意味着类似于switch语句中的返回;) 下面是一些错误(因为这是堆栈溢出,当然它会重复自身) } ClientSwing: public class ClientSwing extends JFrame implements Runnable { public So
返回;
)
下面是一些错误(因为这是堆栈溢出,当然它会重复自身)
}
ClientSwing:
public class ClientSwing extends JFrame implements Runnable {
public SocketManager socketmanager = new SocketManager();
public final int NULL = 0;
public final int DISCONNECTED = 1;
public final int DISCONNECTING = 2;
public final int BEGIN_CONNECT = 3;
public final int CONNECTED = 4;
public int connectionStatus = socketmanager.connectionStatus;
public JPanel panel, statusBar;
public JTextArea textArea;
public JTextField textField, statusColor, usernameField;
public JLabel statusField;
public JMenuBar menuBar;
public JButton connectButton, disconectButton;
public int WIDTH = 640;
public int HEIGHT = 480;
public ClientSwing() {
super("Client");
panel = new JPanel();
panel.setLayout(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setSize(WIDTH, HEIGHT);
setResizable(true);
setJMenuBar(menuBar);
}
@Override
public void run() {
switch(connectionStatus) {
case DISCONNECTED:
break;
case DISCONNECTING:
break;
case CONNECTED:
break;
case BEGIN_CONNECT:
break;
}
}
public void invoke(Runnable runnable) {
SwingUtilities.invokeLater(runnable);
}
}
SocketManager:
public class SocketManager extends JFrame implements Runnable {
public ClientSwing cs = new ClientSwing();
public final int NULL = 0;
public final int DISCONNECTED = 1;
public final int DISCONNECTING = 2;
public final int BEGIN_CONNECT = 3;
public final int CONNECTED = 4;
public final String statusMessages[] = {
" Error! Could not connect", " Disconnected",
" Disconnecting...", " Connceting...", " Connected"
};
public final String END_CHAT_SESSION = new Character((char)0).toString();
public String hostIP = "localhost";
public int port = 2484;
public int connectionStatus = DISCONNECTED;
public StringBuffer toAppend = new StringBuffer("");
public StringBuffer toSend = new StringBuffer("");
public String statusString = statusMessages[connectionStatus];
public Socket socket;
public BufferedReader in;
public PrintWriter out;
public String error;
//Make a method that gets the username from the username field
public String username = "username";
public void changeStatusNTS(int newConnectStatus, boolean noError) {
if(newConnectStatus != NULL) {
connectionStatus = newConnectStatus;
}
if(noError) {
statusString = statusMessages[connectionStatus];
} else {
statusString = statusMessages[NULL];
}
SwingUtilities.invokeLater(cs);
}
public void changeStatusTS(int newConnectStatus, boolean noError) {
if(newConnectStatus != NULL) {
connectionStatus = newConnectStatus;
}
if(noError) {
statusString = statusMessages[connectionStatus];
} else {
statusString = statusMessages[NULL];
}
cs.run();
}
public void cleanUp() {
}
private void appendToChatBox(String s) {
synchronized(toAppend) {
toAppend.append(s);
}
}
private void sendString(String s) {
}
@Override
public void run() {
while(true) {
try {
Thread.sleep(10);
} catch(InterruptedException e) {
error = e.toString();
//Append the error to the textArea
}
switch(connectionStatus) {
case BEGIN_CONNECT:
try {
socket = new Socket(hostIP, port);
in = new BufferedReader(new InputStreamReader(socket.getInputStream())); //I AM RIGHT HERE
out = new PrintWriter(socket.getOutputStream(), true);
changeStatusTS(CONNECTED, true);
} catch(Exception e) {
cleanUp();
changeStatusTS(DISCONNECTED, false);
error = e.toString();
}
break;
case CONNECTED:
try {
if(toSend.length() != 0) {
out.print(toSend);
out.flush();
toSend.setLength(0);
changeStatusTS(NULL, true);
}
if(in.ready()) {
String input = in.readLine();
if((input != null) && (input.length() != 0)) {
if(input.equals(END_CHAT_SESSION)) {
changeStatusTS(DISCONNECTING, true);
} else {
appendToChatBox(username + ": " + input + "\n");
}
}
}
} catch(IOException e) {
cleanUp();
changeStatusTS(DISCONNECTED, false);
error = e.toString();
}
break;
case DISCONNECTING:
out.print(END_CHAT_SESSION);
out.flush();
cleanUp();
changeStatusTS(DISCONNECTED, true);
break;
default: break; //do nothing
}
}
}
class ActionAdapter implements ActionListener {
public void actionPerformed(ActionEvent e) {}
}
}正因为如此,您将获得一个
堆栈溢出
public class SocketManager extends JFrame implements Runnable {
public ClientSwing cs = new ClientSwing();
....
public class ClientSwing extends JFrame implements Runnable {
public SocketManager socketmanager = new SocketManager();
您正在创建一个ClientSwing
,它创建一个SocketManager
,它创建一个ClientSwing
,它创建一个ClientSwing
,它创建一个SocketManager
,它创建一个ClientSwing
,它创建一个SocketManager
,创建ClientSwing
,创建SocketManager
,创建ClientSwing
,创建SocketManager
,创建ClientSwing
,创建SocketManager
,创建ClientSwing
,创建SocketManager
,这创造了一个堆栈溢出
明白了吗
- 如果您想要访问另一个类,不要实例化它。可以将一个类作为引用传递给另一个类。并为要访问的字段提供适当的getter和setter
- 或者,您可以创建MVC设计,这是在类之间共享数据的更合适的方式
- 看看
编辑 像这样的事情将是明确的可能性。不是实例化,而是按值传递
public class ClientSwing ...{
SocketManager socketManager;
public ClientManger(SocketManager socketManger) {
this.socketManage = socketManager;
}
}
非常感谢您的快速回复!我不是想表现得粗鲁,我真的很感谢你的帮助,但是我如何使用多个JFrames/它如何适用于这种情况?当然,无论如何我都在读这篇文章。还有,解决我问题的方法是什么?我想把我必须从其中一个类调用的变量作为静态变量,这样我就不必实例化(正确使用这个词?)SocketManager类,我只需执行
SocketManager.connectionStatus
。这样行吗?再次感谢您的帮助查看我的更新。此外,您正在使用多个JFrame
s,但这不是问题所在。正如你所看到的,这只是一个旁注。只是一个友好的建议。当你指的是JFrames时,你不是在说JPanels,对吧?我实际上指的是ClientMain
,ClientSwing
和SocketManager
哦,我明白你的意思了。我拥有这些扩展JFrame的唯一原因是,我可以在SocketManager类中使用SwingUtilities.invokeLater()
。有更好的方法吗?
public class SocketManager extends JFrame implements Runnable {
public ClientSwing cs = new ClientSwing();
....
public class ClientSwing extends JFrame implements Runnable {
public SocketManager socketmanager = new SocketManager();
public class ClientSwing ...{
SocketManager socketManager;
public ClientManger(SocketManager socketManger) {
this.socketManage = socketManager;
}
}