2

I seem to be having some issues when using the JOptionPane.showMessageDialog() method. When I use the method the only thing that is set up correctly is the dialogs title. It doesn't want to display the text that I provide.

Here's the code that I'm using to try and create an alert:

 JOptionPane.showMessageDialog(null, "alert", "alert", JOptionPane.ERROR_MESSAGE);

The code above provides the image below:

Output I get

If someone could tell me what I'm doing wrong or if there is a different method that I'm supposed to be using, I would much appreciate it.

Edit:

My main class: This creates a GUI where the user enters information "Host" and "DisplayName". When they click "Connect" a new thread is created (the ClientConnectSocket).

public class Main extends JFrame {

public static JPanel contentPane;
private JTextField hostTxt;
public static JTextField displayNameTxt;

JLabel lblDisplayName = new JLabel("Display Name:");
JButton btnConnect = new JButton("Connect");
JLabel lblHost = new JLabel("Host:");


public static String username = "None :(";
public static String host = "localhost";

public static boolean connected = false;

/**
 * Launch the application.
 */
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                Main frame = new Main();
                frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the frame.
 */
public Main() {
    setType(Type.UTILITY);
    setTitle("Java Chat Client - v0.1");
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 390, 200);
    contentPane = new JPanel();
    this.setResizable(false);
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    setContentPane(contentPane);
    contentPane.setLayout(null);


    lblHost.setBounds(60, 11, 56, 19);
    contentPane.add(lblHost);

    hostTxt = new JTextField();
    hostTxt.setBounds(165, 10, 103, 20);
    contentPane.add(hostTxt);
    hostTxt.setColumns(10);


    btnConnect.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
            if (hostTxt.getText() == null || displayNameTxt.getText() == null){

            }else{
                Thread ccs = new ClientConnectSocket(hostTxt.getText(), displayNameTxt.getText());
                ccs.start();
                while (!connected){
                    //System.out.println("Not connected yet..");
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("Yey, connected");
                username = displayNameTxt.getText();
                host = hostTxt.getText();

                EventQueue.invokeLater(new Runnable() {
                    public void run() {
                        try {
                            Chat frame = new Chat();
                            frame.setVisible(true);

                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                });
                dispose();

            }
        }
    });
    btnConnect.setBounds((this.getWidth()/2)- 70, 76, 89, 23);

    contentPane.add(btnConnect);

    displayNameTxt = new JTextField();
    displayNameTxt.setColumns(10);
    displayNameTxt.setBounds(165, 45, 103, 20);
    contentPane.add(displayNameTxt);


    lblDisplayName.setBounds(60, 41, 95, 29);
    contentPane.add(lblDisplayName);

    this.getRootPane().setDefaultButton(btnConnect);
}   

ClientConnectSocket class:

public class ClientConnectSocket extends Thread{

String host;
String name;

public ClientConnectSocket(String host, String displayName){
    this.host = host;
    this.name = displayName;
}

boolean b = true;

public void run(){
    try{
        while (b){
            Socket server = new Socket(host, 6969);
            System.out.println("Sending info to try and connect.");

            BufferedWriter out = new BufferedWriter(new OutputStreamWriter(server.getOutputStream()));
            out.write("method=connect:displayName="+ name);
            out.flush();

            Thread.sleep(500);

            InputStream in = server.getInputStream();

            StringBuffer sb = new StringBuffer();
            byte[] buffer = new byte[1024];
            int buf;
            while ((buf = in.read(buffer)) != -1){
                String line = new String(buffer, 0, buf);

                sb.append(line);
            }
            in.close();
            System.out.println(sb.toString() + " || " + sb.toString().equalsIgnoreCase("connect"));

            if (sb.toString().equalsIgnoreCase("connect")){
                //Allow them to connect
                Main.connected = true;
            }else if(sb.toString().equalsIgnoreCase("invalid:Username")){
                //Tell them they have username already taken;
                 JOptionPane.showMessageDialog(null, "alert", "alert", JOptionPane.ERROR_MESSAGE);
                b = false;
            }

            server.close();
            out.close();
            in.close();

            b = false;
        }
    }catch (Exception e){
        System.exit(2);
        e.printStackTrace();
    }
}

1 Answers1

6

Your posted code snippet suggests that you're running into a Swing threading issue. If your program is a Swing GUI, then most of the above code needs to be called off of the Swing EDT or Event Dispatch Thread, while any Swing calls, including displaying the JOptionPane should be called on the EDT. For more specific help, consider telling and showing more about your code and your use of background threading.


Edit
OK, so that code is in a background thread. So now you must take care to show your JOptionPane on the EDT. Consider making these changes:

} else if(sb.toString().equalsIgnoreCase("invalid:Username")) {

    b = false;

    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            JOptionPane.showMessageDialog(null, "alert", "alert", 
               JOptionPane.ERROR_MESSAGE);          
        }
    });
}

Note: code not tested by compiling or by running. Please be wary of typos.


Edit 2
As an aside, you've got other issues including that the connected variable should not be static. You also have threading issues:

 btnConnect.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent arg0) {
        if (hostTxt.getText() == null || displayNameTxt.getText() == null) {

        } else {

           // .........

           // ********** you should not have this type of code on the EDT
           while (!connected) {
              // ........
           }

           // ...............
        }
     }
   });
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • 2
    +1 [for example (but valid only for Java6, in Java7 aren't no longer a Thread Safe Methods)](http://stackoverflow.com/a/12643642/714968) – mKorbel Sep 01 '14 at 21:16
  • Thank you so much. I took what you said into consideration and came up with the following solution (Please do tell me if I could make this better/more efficient): I created a static method in the "Main" class that I call if the connection is successful (This creates the next window for the user). This is called by the background thread (The "ClientConnectSocket" class) if the connection is successful taking out the need for the "while (!connected)". If the connection isn't successful then first edit you provided is called (In the background thread) to show the error message. It all works. –  Sep 02 '14 at 16:11
  • @TGRHavoc: yeah, I'm going to have to ding you on the use of static anything in this situation. It isn't needed, and it makes enhancing and testing your code **very** difficult. – Hovercraft Full Of Eels Sep 02 '14 at 16:14
  • Could you please elaborate? I've only started coding Java programs recently and my teacher has never mentioned that using static anything could cause the issues you're talking about. –  Sep 02 '14 at 16:17
  • That's fine. I've been reading some other developers posts and they all seem to come to the same conclusion as you. So I've decided to reference my main class and use the variables through the reference. Would this be an aqueduct solution? –  Sep 02 '14 at 17:40