为什么带有JFrame的java服务器在调试模式下工作,而不是在正常执行模式下工作?

为什么带有JFrame的java服务器在调试模式下工作,而不是在正常执行模式下工作?,java,swing,sockets,debugging,server,Java,Swing,Sockets,Debugging,Server,当我在调试模式下单步执行下面的主服务器循环时,它可以完美地工作: 当按下开始按钮时,服务器将使用用户在文本字段中写入的套接字启动,并且开始按钮被禁用 当服务器启动时,会在大文本区域显示一条消息,指示服务器运行的端口和地址 当客户端连接到它时,将显示一条消息,指示已建立连接 服务器不会陷入除主循环之外的任何其他循环中,主循环只有在用户选择退出时才会退出 但当我在正常模式下运行程序并按下启动按钮时,所发生的一切是: “开始”按钮被禁用 不显示任何消息 客户端无法连接到指定的套接字 谢谢你的帮

当我在调试模式下单步执行下面的主服务器循环时,它可以完美地工作:

  • 当按下开始按钮时,服务器将使用用户在文本字段中写入的套接字启动,并且开始按钮被禁用
  • 当服务器启动时,会在大文本区域显示一条消息,指示服务器运行的端口和地址
  • 当客户端连接到它时,将显示一条消息,指示已建立连接
  • 服务器不会陷入除主循环之外的任何其他循环中,主循环只有在用户选择退出时才会退出
但当我在正常模式下运行程序并按下启动按钮时,所发生的一切是:

  • “开始”按钮被禁用
  • 不显示任何消息
  • 客户端无法连接到指定的套接字
谢谢你的帮助

public class ServerLoop {
    static boolean running;
    static int currentState=0;
    static int port;
    static ServerSocket server = null;

    public static void main (String[] args) throws IOException {
        MainServer main = new MainServer();
        while (true) {
            currentState = main.getCurrentState();
            switch (currentState) {
            case 1:
                port = main.getPortnumber();
                JTextArea text = main.getTextArea();
                String temp = text.getText();
                temp = temp + "Portnumber: "+ port +"\n" + 
                    "Server ip-address: " + main.getIpAddress()+ "\n";
                main.updateText(temp);
                server = new ServerSocket(port);
                currentState++;
                break;

            case 2:
                Socket clientConnection = server.accept();
                text = main.getTextArea();
                temp = text.getText();
                temp = temp + "Connection with: " +
                    clientConnection.getInetAddress().getHostName() +
                    "established. \n";
                main.updateText(temp);
                new ClientConnected(clientConnection);
                break;

            case 3:
                text = main.getTextArea();
                temp = text.getText();
                temp = temp + "Server shutting down...\n";
                main.updateText(temp);
                server.close();
                text = main.getTextArea();
                temp = text.getText();
                temp = temp + "Server shutdown\n";
                main.updateText(temp);
                main.setIdle(true);
                currentState=0;
                break;

            default:
                break;
            }
        }
    }
}
这个类为服务器创建了一个接口,它只是一个简单的接口,有一个大的textarea,一个小的textfield和两个带侦听器的按钮

如果我不得不猜测按钮上的服务器循环和actionlisteners是相互憎恨的,但我不明白为什么它在调试模式下工作

public class MainServer extends JFrame {
    JTextArea mainTextfield;
    String k = "";
    JTextField portnumber;
    JFrame frame;
    JButton start,close;
    int currentState = 0;
    int porten;
    boolean idle = true;

    public MainServer() {
        frame = new JFrame("ArenanServer v1.0");
        frame.setLayout(new FlowLayout());
        frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
        frame.setSize(600, 550);
        frame.setResizable(false);
        frame.setBackground(Color.LIGHT_GRAY);

        mainTextfield = new JTextArea();
        mainTextfield.setPreferredSize(new Dimension(585,450));
        mainTextfield.setBackground(Color.WHITE);
        mainTextfield.setOpaque(true);
        mainTextfield.setBorder(BorderFactory.createLoweredBevelBorder());
        mainTextfield.setEditable(false);
        JScrollPane scroll = new JScrollPane(mainTextfield)
        frame.add(scroll);

        JLabel port = new JLabel();
        port.setText("Port: ");
        frame.add(port);

        portnumber = new JTextField();
        portnumber.setBorder(BorderFactory.createLoweredBevelBorder());
        portnumber.setPreferredSize(new Dimension(100,25));
        portnumber.setDocument(new JTextFieldLimit(5));
        frame.add(portnumber);

        ////I think this might be a problem with the actionlisteners on buttons//
        start = new JButton("Start server");
        close = new JButton("Close server");

        start.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                if (portnumber.getText().length()>0) {
                    porten = Integer.parseInt(portnumber.getText());
                    start.setEnabled(false);
                    close.setEnabled(true);
                    currentState = 1;
                    idle=false;
                } 
                else {
                    k = mainTextfield.getText();
                    k = k + "Please enter a port number.\n";
                    updateText(k);
                }
            }
         });

    close.setEnabled(false);
    close.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent arg0) {
            currentState = 3;
            start.setEnabled(true);
            close.setEnabled(false);
        }
    });

    frame.add(start);
    frame.add(close);
    frame.setVisible(true);
}
这些函数用于增加主循环和接口之间的通信,它们与接口放在同一个类中

protected JButton getStartButton() {
    return start;
}
protected JButton getCloseButton() {
    return close;
}
protected int getPortnumber() {
    return porten;
}

protected JTextArea getTextArea() {
    return mainTextfield;
}
protected JFrame getFrame() {
    return frame;
}
protected boolean updateText(String l) {
    mainTextfield.setText(l);
    frame.repaint();
    if (mainTextfield.getText().equals(l)) {
        return true;
    } else {
        return false;
    }
}
protected boolean updateview() {
    frame.repaint();
    return true;
}
protected int getCurrentState() {
    if (idle) {
        return 0;
    } else {
        if (currentState != 1) {
            return currentState;
        } else {
            currentState++;
            return 1;
        }
    }
}
protected void setIdle(boolean t) {
    idle = t;
}

在查看您的问题时,我对其进行了编辑,以提高其可读性。我不得不重新格式化你的代码,因为制表符和空格的混合以及不一致的缩进搞砸了StackOverflow代码解析器

在这样做的时候,我想我找到了答案:从
public MainServer(){
start.addActionListener(new ActionListener()
中第一轮括号的结束错误地相互交叉

这就是你所拥有的:

    public MainServer() {
        ...
        start.addActionListener(new ActionListener() {
            ...                
        }
    });
这就是我认为你应该拥有的:

    public MainServer() {
        ...
        start.addActionListener(new ActionListener() {
            ...                
        });
    }
我想应该吸取的教训是:

  • 代码格式很重要-在尝试保持代码格式一致时,您也会发现错误
  • 混合制表符和空格进行缩进不是一个好主意
  • 空格更适合缩进-对StackOverflow编辑器更友好:)

您好,谢谢您的回答,这是我第一次使用stackoverflow,我只是将eclipse中的代码复制/粘贴到编辑器中,然后在每一行中添加空格。也许这不是最好的方式。但是感谢您编辑我的问题,看起来好多了。对于您的回答,如果我理解正确,您的意思是“}”)在开始时应为“};”。AddActionListener?还是我对你的理解有误?:)如果我尝试,我会犯很多错误。你还有其他想法吗?:)谢谢我澄清了答案我现在明白你的意思了。在eclipse中,你所建议的就是我所拥有的。我发现在你提到的时候有一对多“}”。我把它删掉了。你还有其他想法吗?可能是什么问题?