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

时间:2016-04-24 14:47:53

标签: 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,一个小文本域和两个带有监听器的按钮。

如果我不得不猜测它们互相讨厌的按钮上的服务器循环和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;
}

Picture of what it looks like in both runs after pressing the start button and trying to connect to the socket, debug mode to the right.

1 个答案:

答案 0 :(得分:1)

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

在这样做的时候,我我找到了答案:关闭大括号 public MainServer() {和来自start.addActionListener(new ActionListener()的第一轮括号的关闭与其他人错误地交叉。

这就是你所拥有的:

    public MainServer() {
        ...
        start.addActionListener(new ActionListener() {
            ...                
        }
    });

这就是我认为你应该拥有的东西:

    public MainServer() {
        ...
        start.addActionListener(new ActionListener() {
            ...                
        });
    }

我想要吸取教训:

  • 代码格式很重要 - 您在尝试在代码格式中保持一致时也发现了错误
  • 将标签和空格混合用于缩进不是一个好主意
  • 空格更适合缩进 - 对StackOverflow编辑器更友好:)