I am really confused by this: some of my code does not work when I run my program, usually in eclipse, but it works when I run each step separately, using debug mode.
code:
public void showConnectDialog() { ConnectDialog connectDialog = new ConnectDialog(); connectDialog.setVisible(true); //Until here, code runs while(! connectDialog.getConnected()) {}; //The next line does only run in debug JOptionPane.showMessageDialog(connectDialog, "Connected", "Connected", JOptionPane.INFORMATION_MESSAGE); }
Connector (starts (as a thread) as soon as the user clicks "connect" in the dialog box):
private class ServerConnector implements ActionListener, Runnable { @Override public void actionPerformed(ActionEvent e) { if (! IP_field.getText().equals("")) { if (! isConnecting) { new Thread(new ServerConnector(), "ServerConnector").start(); } } else { JOptionPane.showMessageDialog(dialog, "Enter an IP address", "Enter IP", JOptionPane.WARNING_MESSAGE); } } @Override public void run() { try { setConnecting(true); Socket socket = connect(); if (socket != null) { ObjectOutputStream oOut = new ObjectOutputStream(socket.getOutputStream()); ObjectInputStream oIn = new ObjectInputStream(socket.getInputStream()); if (login(oOut, oIn)) { isConnected = true; setConnecting(false); } else { socket.close(); } setConnecting(false); } } catch (RSPException e) { e.printStackTrace(); System.exit(1); } catch (Exception e) { //If an exception occurs, setConnecting() will be true. This //not good, so it has to be set to false e.printStackTrace(); setConnecting(false); } } private boolean login(ObjectOutputStream oOut, ObjectInputStream oIn) throws ClassNotFoundException, IOException, RSPException { //Send login request action: oOut.writeObject(new LoginAction(ActionSender.CLIENT, getID(), getPassword())); Object obj = oIn.readObject(); if (obj instanceof LoginActionResult) { LoginActionResult result = (LoginActionResult) obj; if (result.getResult() == LoginResults.SUCCES) { return true; } else if (result.getResult() == LoginResults.FAIL_ON_ID) { JOptionPane.showMessageDialog(dialog, "Invalid password or ID", "Can't login", JOptionPane.ERROR_MESSAGE); return false; } else if (result.getResult() == LoginResults.FAIL_ON_PASSWORD) { JOptionPane.showMessageDialog(dialog, "Invalid password or ID", "Can't login", JOptionPane.ERROR_MESSAGE); return false; } else if (result.getResult() == LoginResults.SERVER_FULL) { JOptionPane.showMessageDialog(dialog, "Couldn't connect: \n" + "Server is full", "Failed to connect", JOptionPane.WARNING_MESSAGE); return false; } else { return false; } } else { System.out.println(obj); throw new RSPException("Server is not following the protocol."); } } private void setConnecting(boolean connecting) { if (connecting) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { connectButton.setEnabled(false); } }); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { connectButton.setText("Connecting..."); } }); } else { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { connectButton.setText("Connect"); } }); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { connectButton.setEnabled(true); } }); } isConnecting = connecting; } private String getAddressFromTextField() { return IP_field.getText(); } private InetAddress getInetAddress(String fullAddress) { try { if (fullAddress.contains(":")) { String[] splitAddress = fullAddress.split(":"); return InetAddress.getByName(splitAddress[0]); } else { return InetAddress.getByName(fullAddress); } } catch (UnknownHostException e) { return null; } } private int getPort(String fullAddress) { try { String[] splittedAddress = fullAddress.split(":"); return Integer.valueOf(splittedAddress[1]); } catch (NumberFormatException ex) { return -1; } catch (NullPointerException | ArrayIndexOutOfBoundsException | PatternSyntaxException ex) { //Returning default port value: 25566, because no port was given return 25566; } } @SuppressWarnings("resource") private Socket connect() { Socket socket = null; InetAddress address = null; if ((address = getInetAddress(getAddressFromTextField())) == null) { return null; } int port = getPort(getAddressFromTextField()); try { socket = new Socket(address, port); } catch (ConnectException e ) { Socket retrySocket = null; if ((retrySocket = retryConnect(address, port)) == null) { JOptionPane.showMessageDialog(dialog, "Connection timed out", "Failed to connect", JOptionPane.ERROR_MESSAGE); setConnecting(false); } else { socket = retrySocket; } } catch(IOException e) { e.printStackTrace(); } return socket; } private Socket retryConnect(InetAddress address, int port) { Thread waitThread = new Thread(new Runnable() { @Override public void run() { try { //Will wait 15(000) (milli)seconds before stopping with //trying to connect. //One second (1000 millis) is for debugging and testing Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } }); waitThread.start(); while (waitThread.isAlive()) { try { return new Socket(address, port); } catch (ConnectException e) { //Do nothing, will re-attempt to connect. } catch (IOException e) { e.printStackTrace(); } } return null; } private String getID() { return ID_field.getText(); } private String getPassword() { if (getID().equals("master")) { return "masterPassword"; } else { return new String(passwordField.getPassword()); } } }
getConnected() returns true as soon as it connects to the server. The connector runs on a separate thread.
EDIT : I tried putting the code in the getConnected() while block, and then it works. Why does it work then and not otherwise?