【问题标题】:JOptionPane.showMessageDialog not showing textJOptionPane.showMessageDialog 不显示文本
【发布时间】:2014-10-26 01:33:39
【问题描述】:

我在使用 JOptionPane.showMessageDialog() 方法时似乎遇到了一些问题。 当我使用该方法时,唯一正确设置的是对话框标题。它不想显示我提供的文本。

这是我用来尝试创建警报的代码:

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

上面的代码提供了下图:

如果有人能告诉我我做错了什么,或者我应该使用其他方法,我将不胜感激。

编辑:

我的主要课程: 这将创建一个 GUI,用户在其中输入信息“Host”和“DisplayName”。当他们单击“连接”时,会创建一个新线程(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 类:

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();
    }
}

【问题讨论】:

  • 您的计算机没有使用 nVidea 视频卡,是吗?如果没有,请考虑创建并发布minimal example program
  • 它确实使用了 nVidia 显卡。这个问题似乎只在我使用对话框时出现,因为 JFrame 工作正常。
  • 看看here
  • 所以如果更改显卡设置后没有文字,那么考虑创建并发布minimal example program
  • 请参阅编辑回答。

标签: java swing dialog jpanel


【解决方案1】:

您发布的代码 sn-p 表明您遇到了 Swing 线程问题。如果你的程序是一个 Swing GUI,那么上面的大部分代码都需要从 Swing EDT 或 Event Dispatch T 中调用hread,而任何 Swing 调用,包括显示 JOptionPane 都应该在 on EDT 上调用。如需更具体的帮助,请考虑详细介绍和展示您的代码以及您对后台线程的使用。


编辑
好的,所以代码在后台线程中。所以现在您必须注意在 EDT 上显示您的 JOptionPane。考虑进行这些更改:

} 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);          
        }
    });
}

注意:代码未经编译或运行测试。请注意错别字。


编辑 2
顺便说一句,您还有其他问题,包括连接的变量不应该是静态的。您还有线程问题:

 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) {
              // ........
           }

           // ...............
        }
     }
   });

【讨论】:

  • 非常感谢。我考虑了您所说的并提出了以下解决方案(请告诉我是否可以使其更好/更有效):我在“Main”类中创建了一个静态方法,如果连接成功,我将调用该方法(这会为用户创建下一个窗口)。如果连接成功,则由后台线程(“ClientConnectSocket”类)调用,以消除对“while (!connected)”的需求。如果连接不成功,则调用您提供的第一个编辑(在后台线程中)以显示错误消息。一切正常。
  • @TGRHavoc:是的,我将不得不在这种情况下使用静态任何东西。它不是必需的,它使增强和测试您的代码非常变得困难。
  • 您能详细说明一下吗?我最近才开始编写 Java 程序,而我的老师从未提到使用静态的任何东西都会导致您所说的问题。
  • 没关系。我一直在阅读其他一些开发人员的帖子,他们似乎都得出了与您相同的结论。所以我决定引用我的主类并通过引用使用变量。这会是渡槽解决方案吗?
猜你喜欢
  • 1970-01-01
  • 2015-01-19
  • 2017-01-04
  • 2019-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-26
  • 2019-03-27
相关资源
最近更新 更多