我有一个带有4个JButton和一个动作监听器的主窗口,其中三个调用另一个窗口,第四个退出。我的两个窗口工作正常,但由于某种原因我的窗口等待客户端连接打开,你可以看到窗口的边界,但窗口的内部是透明的。
我试着从我的班级说new HostWindow()
,这很好用;只是当我从我的StartWindow类调用它时它不起作用。
代码:
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();
}
}
HostWindow:
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,我没有复制粘贴标题,但它看起来像这样: 公共类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();
}
答案 0 :(得分: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!");
}
在完成连接之前,将阻止窗口被绘制,此时您将以任何方式处理窗口。
您可能想要阅读
我建议将“连接”代码移动到SwingWorker
并使用done
方法处理窗口。
答案 1 :(得分:3)
这里的问题是你在UIThread中执行持久的阻塞操作。
线程是在单个程序中运行的同时命令序列(我建议阅读Java concurrency)。有一个线程通常被称为UIThread,它执行UI元素的绘制并使用它们的代码。
创建套接字 - 与远程主机的连接意味着您正在启动一个可能需要几秒钟才能执行的进程。这发生在UI类的构造函数内部,在UIThread中。在建立连接之前,构造函数中的其余代码无法运行。这是因为连接过程是一个阻塞操作 - 套接字创建后的代码在套接字创建完成之前不会运行。
因此,您应该将套接字创建移动到另一个线程。