我有一个带有4个JButton和一个动作侦听器的主窗口,其中三个调用另一个窗口,第四个退出。我的两个窗口可以正常工作,但是由于某种原因,等待客户端连接的窗口会打开,您可以看到窗口的边界,但是窗口的内部是透明的。
我尝试从我的主要班级说new HostWindow(),效果很好;只是当我从StartWindow类调用它时,它不起作用。
码:

起始窗口:

public class StartWindow extends JFrame{
private JPanel pane;
private JButton host;
private JButton join;
private JButton comp;
private JButton exit;

public StartWindow()
{
    this.setSize(220, 110);
    this.setTitle("Closed Arena");
    pane = new JPanel();
    this.add(pane);
    host = new JButton("Host Match");
    host.addActionListener(new myButtonListener());
    join = new JButton("Join Match");
    join.addActionListener(new myButtonListener());
    comp = new JButton("Play Computer");
    comp.addActionListener(new myButtonListener());
    exit = new JButton("Exit");
    exit.addActionListener(new myButtonListener());
    pane.add(host);
    pane.add(join);
    pane.add(comp);
    pane.add(exit);
    this.setResizable(false);
    pane.setVisible(true);
    this.setVisible(true);
    this.setDefaultCloseOperation(EXIT_ON_CLOSE);

    //If I make a new Hostwindow here it displays properly
    //new HostWindow();
}

private class myButtonListener implements ActionListener
{

    @Override
    public void actionPerformed(ActionEvent e)
    {
        Object source = e.getSource();
        if(source.equals(host))
        {
            close();
            //But here it displays improperly.
            new HostWindow();
        }
        if(source.equals(join))
        {
            close();
            new JoinWindow();
        }
        if(source.equals(comp))
        {
            close();
            new Arena();
        }
        if(source.equals(exit))
        {
            close();
        }
    }
}
public void close()
{
    this.dispose();
}
}


主机窗口:

private JPanel panel;
private JLabel text;
private JButton stop;
private LabelEditor edit;
private Thread editThread;
private ServerSocket server;
private Socket mySocket;

public HostWindow()
{
    panel = new JPanel();

    text = new JLabel("Waiting for client");
    stop = new JButton("Stop");
    stop.addActionListener(new buttonList());

    panel.add(text);
    panel.add(stop);
    this.add(panel);

    this.setResizable(false);
    this.setSize(160, 90);
    this.setTitle("Server");

    this.setVisible(true);
    this.setDefaultCloseOperation(EXIT_ON_CLOSE);

    edit = new LabelEditor(text, "Waiting for client", 700);
    editThread = new Thread(edit);
    editThread.start();

    try
    {
        server = new ServerSocket(4011);
        mySocket = server.accept();
        server.close();
        new Arena(mySocket, true);
    }
    catch (IOException e) {
        System.out.print("Failed to set up server!");
    }
    editThread.interrupt();
    this.dispose();
}


编辑:HostWindow确实扩展了JFrame,我jsut并未复制粘贴标题,但它看起来像这样:
    公共类HostWindow扩展了JFrame {

Edit2:谢谢回答者,当我这样做时它已修复,以便serer在单独的线程中启动:

if(source.equals(host))
        {
            close();
            HostWindow hoster = new HostWindow();
            Thread hosterThread = new Thread(hoster);
            hosterThread.start();
        }


并在hostwindow中:
我将服务器中的内容移到运行中。

public void run() {
    try
    {
        server = new ServerSocket(4011);
        mySocket = server.accept();
        server.close();
        new Arena(mySocket, true);
    }
    catch (IOException e) {
        System.out.print("Failed to set up server!");
    }
    editThread.interrupt();
    this.dispose();
}

最佳答案

这里的问题是您正在UIThread内部执行持久的阻塞操作。

线程是在单个程序中运行的命令的同时序列(我建议在Java concurrency上阅读)。通常有一个线程被称为UIThread,它执行UI元素的绘制并与其代码一起工作。

创建套接字-与远程主机的连接意味着您正在启动一个过程,该过程可能需要花费几秒钟的时间。这发生在UIThread的UI类的构造函数内部。在建立连接之前,构造函数中的其余代码无法运行。这是因为连接过程是一个阻塞操作-套接字创建后的代码要等到套接字创建完成后才能运行。

因此,您应该将套接字创建移至其他线程。

09-06 22:18