1

我有一个带有 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,我只是没有复制粘贴标题,但它看起来像这样: public class HostWindow extends JFrame {

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

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

在主机窗口中:我将服务器的东西移到运行中。

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

2 回答 2

3

首先,我认为您的示例不正确HostWindow并没有延伸到任何东西,但是您似乎将其视为窗口...

第二

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

将阻止窗口被绘制,直到建立连接,此时您以任何方式处理窗口。

你可能想通读一遍

我建议将“连接”代码移动到 aSwingWorker并使用它的done方法来处理窗口。

于 2012-09-03T22:55:11.037 回答
3

这里的问题是你在 UIThread 中执行了一个持久的阻塞操作。

线程是在单个程序中同时运行的命令序列(我建议阅读Java 并发)。有一个线程通常称为 UIThread,它执行 UI 元素的绘制并使用它们的代码。

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

因此,您应该将套接字创建移动到不同的线程。

于 2012-09-03T22:55:39.617 回答