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

发布于 2024-10-08 05:43:10 字数 2886 浏览 1 评论 0原文

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

以下是相关代码片段:

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

发生的情况如下:
初始对话框显示:
我单击“确定”按钮。 主窗口的大小会调整为主应用程序的首选大小,但不会被绘制,它只是透明的(此处显示此页面作为背景,呵呵):
https://i.sstatic.net/8HIWo.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() before 挂在 server.accept() 调用上呢?

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):
https://i.sstatic.net/8HIWo.jpg

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).

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()

Exact same result.

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


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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

物价感观 2024-10-15 05:43:11

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

安徽省

your code seems to work so, maybe you should try to invoke the repaint() methode of you frame after resizing this frame.

Anhuin

深陷 2024-10-15 05:43:10

打开套接字并等待客户端

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

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

openasocketandwaitforaclient

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文