简体   繁体   English

paintComponent没有在正确的时间被调用

[英]paintComponent not being called at the right time

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 -当用户单击确定时,关闭对话框,转到主应用

Here are the relevant code snippets: 以下是相关的代码段:

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

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 http://imgur.com/6Ssij.jpg

I can tell the paintComponent method hasn't been called because "painting" isn't printed to the console. 我可以告诉paintComponent方法没有被调用,因为“绘画”没有打印到控制台。 However, "got to this point in the program" DOES get printed, so the program isn't hanging, it's just not calling paintComponent. 但是,“打印到程序的这一点”确实会被打印出来,所以程序没有挂起,只是没有调用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). 稍后在应用程序中,对repaint()的调用也会延迟(即paintComponent实际上是在程序中稍后调用,而不是在调用repaint()时调用)。

I also tried replacing the initial dialog using sthing along the lines of 我也尝试使用sthing来替换初始对话框

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

Exact same result. 完全相同的结果。

tl;dr paintcomponent isn't being called when i want it to, what do? tl; dr paintcomponent在我想要的时候没有被调用,怎么办?


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? 碰到一些更多的信息:repaint()的调用是在sever.accept()的调用之前完成的,那么为什么不挂在server.accept()的调用之前就不repaint()呢?

openasocketandwaitforaclient openasocketandwaitforaclient

Your code is executing in the Event Dispatch Thread so the blocking socket is preventing the GUI from repainting itself. 您的代码正在事件分发线程中执行,因此阻塞套接字正在阻止GUI重新绘制自身。

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. 阅读Swing教程关于并发的部分以获得解释和解决方案。

your code seems to work so, maybe you should try to invoke the repaint() methode of you frame after resizing this frame. 您的代码似乎可以正常工作,也许您应该在调整框架大小后尝试调用框架的repaint()方法。

Anhuin Anhuin

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM