【问题标题】:paintComponent not being called at the right time没有在正确的时间调用paintComponent
【发布时间】:2011-05-25 09:51:18
【问题描述】:

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

以下是相关代码sn-ps:

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

我可以看出paintComponent 方法没有被调用,因为“绘画”没有打印到控制台。 但是,“程序中的这一点”确实被打印出来了,所以程序没有挂起,它只是没有调用paintComponent。 然后,当我启动客户端并连接时,应用程序最终被绘制,并且“绘制”和“获得客户端”被打印到控制台。 稍后在应用程序中,对 repaint() 的调用也会延迟(即在程序中实际调用paintComponent 的时间比调用 repaint() 的时间要晚)。

我还尝试使用类似的东西替换初始对话框

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

完全相同的结果。

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


更多信息:对 repaint() 的调用是在调用 sever.accept() 之前完成的 那么为什么它不 repaint() 挂在 server.accept() 之前打电话?

【问题讨论】:

  • 记得在 EDT 上运行所有 Swing/AWT 代码,但不要阻止它。 / 啊两个电源。 openasocketandwaitforaclient 在 EDT 中,这是一件坏事。

标签: java swing paintcomponent


【解决方案1】:

打开套接字并等待客户端

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

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

【讨论】:

  • 非常感谢。我知道所有的挥杆绘画都必须在事件调度线程中完成,但不是非绘画的东西必须在它之外完成。
  • 获取更多信息:对 repaint() 的调用是在调用 sever.accept() 之前完成的 那么为什么它在等待连接时挂起之前不 repaint() 呢?
  • repaint() 不会导致组件立即被绘制。它调用重绘管理器,该管理器可能合并多个重绘请求,然后将它们添加回 EDT 末尾的末尾以进行绘制。
【解决方案2】:

您的代码似乎可以正常工作,也许您应该在调整此框架的大小后尝试调用框架的 repaint() 方法。

安徽

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-26
    相关资源
    最近更新 更多