在正确的时间未调用paintComponent [英] paintComponent not being called at the right time

查看:203
本文介绍了在正确的时间未调用paintComponent的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个类似这样的应用程序:
-显示对话框
-当用户单击确定"时,关闭对话框,转到主应用程序

I'm trying to write an app that goes something like this:
- Display a dialog
- When user clicks OK, close dialog, go to main app

以下是相关的代码段:

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

会发生以下情况:
初始对话框显示:
我单击确定按钮. 主窗口将调整为主应用程序的首选大小,但不会被绘制,它只是透明的(此处显示此页面为背景,呵呵):
http://imgur.com/6Ssij.jpg

What happens is the following:
The initial dialog displays:
I click the OK button. The main window gets resized to the preferred size of the main app but it doesn't get painted, it's just transparent (shown here with this page as the background, heh):
http://imgur.com/6Ssij.jpg

我可以说未调用paintComponent方法,因为绘画"未打印到控制台. 但是,打印到程序的这一点"确实会被打印出来,所以程序没有挂起,只是没有调用paintComponent. 然后,当我启动客户端并进行连接时,该应用程序最终被绘制,并且绘制"和获得客户端"被打印到控制台. 同样在应用程序的后面,延迟了对repaint()的调用(即,比在进行repaint()的调用时,在程序中实际上调用了paintComponent.)

I can tell the paintComponent method hasn't been called because "painting" isn't printed to the console. However, "got to this point in the program" DOES get printed, so the program isn't hanging, it's just not calling paintComponent. Then when I launch a client and connect, the app finally gets painted, and "painting" and "got a client" get printed to the console. Also later on in the app, calls to repaint() are delayed (ie paintComponent is actually called later in the program than when the call to repaint() is made).

我还尝试使用sth代替

I also tried replacing the initial dialog using sthing along the lines of

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

完全相同的结果.

tl; dr paintcomponent不在我想要的时候被调用,怎么办?

tl;dr paintcomponent isn't being called when i want it to, what do?

碰撞以获得更多信息:repaint()的调用是在sever.accept()的调用之前完成的,那么为什么为什么不之前在服务器上挂起而未repaint()呢?打电话吗?

Bumping for some more info: the call to repaint() is done before the call to sever.accept() So why does it not repaint() before hanging at the server.accept() call?

推荐答案

openasocketandwaitforaclient

openasocketandwaitforaclient

您的代码正在事件调度线程中执行,因此阻塞套接字正在阻止GUI重新绘制自身.

Your code is executing in the Event Dispatch Thread so the blocking socket is preventing the GUI from repainting itself.

您需要为套接字使用单独的线程.阅读Swing教程中并发的部分,以获得解释和解决方案.

YOu need to use a separate Thread for the socket. Read the section from the Swing tutorial on Concurrency for an explanation and a solution.

这篇关于在正确的时间未调用paintComponent的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆