0

私は次のようなアプリを作成しようとしています:
- ダイアログを表示し
ます - ユーザーが [OK] をクリックすると、ダイアログを閉じ、メインアプリに移動します

関連するコード スニペットは次のとおりです。

public class Owari extends JPanel implements ActionListener, MouseListener, Runnable {

// FIELDS
JFrame frame;
JTextField IP;
String IPAddress;

static final int SERVER_MODE = 0;
static final int CLIENT_MODE = 1;
int mode;

OwariBoard board;

  public static void main( String[] args ) {
    SwingUtilities.invokeLater( new Owari() );
  }

  Owari() {
    setPreferredSize( new Dimension( WIDTH, HEIGHT ) );
    board = new OwariBoard();
  }

  void main() {
    this.addMouseListener( this );
    frame.dispose();
    frame = new JFrame( "Owari" );
    frame.setContentPane( this );
    frame.pack();
    frame.setVisible(true);
    if ( mode == SERVER_MODE ) {
      server();
    }
    if ( mode == CLIENT_MODE ) {
      client();
    }
  }

  public void run() {
    frame = new JFrame( "Owari" );
    frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
    JPanel init = new JPanel( new GridBagLayout() );
    frame.setContentPane( init );

    add some components to the init panel including a button with
    this as its actionListener and OK as its command.
    frame.pack();
    frame.setVisible( true );
  }


  public void actionPerformed( ActionEvent e ) {
    if ( e.getActionCommand().equals( "Client" ) ) {
      mode = CLIENT_MODE;
      IP.setVisible( true );
    }
    else if ( e.getActionCommand().equals( "Server" ) ) {
      mode = SERVER_MODE;
      IP.setVisible( false );
    }
    else {
      IPAddress = IP.getText();
      main();
    }
  }

  public void paintComponent( Graphics g ) {
    super.paintComponent( g );
    System.out.println( "painting" );
    do some paintin
  }

  void server() {
    frame.setTitle( "Owari Server" );
    try {
    server = new ServerSocket( 666 );
    socket = server.accept();
    initIO();
    } catch ( IOException e ) {}
    yourTurn = true;
    System.out.println( "Got to end of server()" ); // At this point, the window
                                                       DOES get painted

何が起こるかは次のとおりです:
最初のダイアログが表示されます:
[OK] ボタンをクリックします。メイン ウィンドウは、メイン アプリの推奨サイズにサイズ変更されますが、ペイントされず、単に透明です (このページを背景としてここに表示されています):
http://imgur.com/6Ssij.jpg

「ペイント」がコンソールに出力されないため、paintComponent メソッドが呼び出されていないことがわかります。ただし、「プログラムのこの時点に到達した」は出力されるため、プログラムはハングしていません。それは、paintComponent を呼び出していないだけです。次に、クライアントを起動して接続すると、アプリは最終的に描画され、「描画中」と「クライアントを取得しました」がコンソールに出力されます。また、アプリの後半では、repaint() の呼び出しが遅延します (つまり、実際には、プログラム内で、repaint() の呼び出しが行われたときよりも後で paintComponent が呼び出されます)。

また、次の行に沿って sthing を使用して初期ダイアログを置き換えてみました

public void main
  frame.getRootPane.removeAll()
  frame.setContentPane(this)
  frame.getRootPane().revalidate()
  frame.pack()

まったく同じ結果です。

tl;dr paintcomponent が必要なときに呼び出されません。どうすればよいですか?


いくつかの詳細情報が必要です: repaint() への呼び出しは、sever.accept() への呼び出しの前に行われます

4

2 に答える 2

2

ソケットを開いてクライアントを待つ

コードがイベント ディスパッチ スレッドで実行されているため、ブロッキング ソケットが GUI 自体の再描画を妨げています。

ソケットには別のスレッドを使用する必要があります。説明と解決策については、並行性に関するSwing チュートリアルのセクションを参照してください。

于 2010-12-14T16:57:46.410 に答える
0

このフレームのサイズを変更した後、フレームの repaint() メソッドを呼び出すようにしてください。

アンフイン

于 2010-12-14T16:55:14.723 に答える