1

4つのJButtonとアクションリスナーを備えたメインウィンドウがあり、そのうちの3つが別のウィンドウを呼び出して4つ目の出口があります。2つのウィンドウは正常に機能しますが、何らかの理由で、クライアントの接続を待機しているウィンドウが開き、ウィンドウの境界が表示されますが、ウィンドウの内部は透明です。私はメインクラスから言ってみ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を拡張します、私はjsutが見出しをコピーして貼り付けませんでしたが、次のようになります:public class HostWindow extends JFrame {

Edit2:回答者に感謝します。セレールが別のスレッドで開始するように作成したときに修正されました。

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

接続が確立されるまでウィンドウがペイントされないようにします。接続が確立されると、ウィンドウは破棄されます。

あなたは一読したいかもしれません

「接続」コードをに移動し、そのメソッドをSwingWorker使用してウィンドウを破棄することをお勧めします。done

于 2012-09-03T22:55:11.037 に答える
3

ここでの問題は、UIThread内で長期的なブロッキング操作を実行していることです。

スレッドは、単一のプログラム内で実行されるコマンドの同時シーケンスです(Javaの並行性について調べることをお勧めします)。UI要素の描画を実行し、それらのコードを操作するUIThreadと通常呼ばれるスレッドがあります。

ソケットの作成-リモートホストへの接続は、実行に数秒かかる可能性のあるプロセスを開始していることを意味します。そして、これはUIクラスのコンストラクター内、UIThread内で発生しています。接続が確立されるまで、コンストラクターの残りのコードは実行できません。これは、接続プロセスがブロッキング操作であるためです。ソケット作成後のコードは、ソケット作成が完了するまで実行されません。

したがって、ソケットの作成を別のスレッドに移動する必要があります。

于 2012-09-03T22:55:39.617 に答える