在初始化期间,我可以添加ComponentListener,以便它不会触发componentResized吗?

dan*_*ter 2 java swing resize componentlistener

我想,答案是在完成所有初始组件大小调整之后,但请看一下这个SSCCE:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Test2 {

  private static void createAndShowGUI2() {

    final JFrame frame = new JFrame("Test2");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JButton addSecondListener = new JButton("Click me to add a second listener");
    addSecondListener.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        frame.addComponentListener(new ComponentAdapter() {
          public void componentResized(ComponentEvent e) {
            System.out.println("Component Listener 2");
          }
        });
      }
    });

    frame.getContentPane().add(addSecondListener);

    frame.setSize(200, 200);
    frame.setVisible(true);

    frame.addComponentListener(new ComponentAdapter() {
      public void componentResized(ComponentEvent e) {
        System.out.println("Component Listener 1");
        //throw new NullPointerException("Just getting traceback...");
      }
    });

  }

  public static void main(String[] args) {
    //Schedule a job for the event-dispatching thread:
    //creating and showing this application's GUI.
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        createAndShowGUI2();
      }
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

即使调整框架大小并使其可见添加了Component Listener 1,也会启动时调用resize事件java Test2; 它将打印出Component Listener 1第一件事.

这最初让我相信添加一个组件监听器总是会导致resize事件立即触发.然而,这种情况并非如此.如果按下框架组件内的JButton,将添加侦听器2,并且您将不会像看到它那样看到它的打印Component Listener 2,而只会在调整框架大小时触发.

是什么导致组件侦听器在帧被调整之后才被触发甚至被设置为可见?我在那里抛出一个异常,看看追溯(目前已注释掉)给我一些提示:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException: Just getting traceback...
    at Test2$2.componentResized(Test2.java:31)
    at java.awt.Component.processComponentEvent(Component.java:5960)
    at java.awt.Component.processEvent(Component.java:5914)
    at java.awt.Container.processEvent(Container.java:2023)
    at java.awt.Window.processEvent(Window.java:1816)
    at java.awt.Component.dispatchEventImpl(Component.java:4501)
    at java.awt.Container.dispatchEventImpl(Container.java:2081)
    at java.awt.Window.dispatchEventImpl(Window.java:2458)
    at java.awt.Component.dispatchEvent(Component.java:4331)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
Run Code Online (Sandbox Code Playgroud)

对于我的应用程序,我想在以编程方式设置所有初始大小调整后添加ComponentListener,而不会触发componentResized(直到用户实际更改框架/组件的大小).我怎样才能做到这一点?

编辑:我知道有很多方法可以解决这个问题,例如添加一个最初为false的布尔值并在之后设置,以忽略第一个resize事件.然而,在我看来这并不是超级健壮的,我只是想知道发生了什么.

Luk*_*ter 5

你可以在里面添加监听器SwingUtilities.invokeLater(),以确保在添加监听器之前首先调整框架大小(我不认为这会被认为是一种解决方法):

SwingUtilities.invokeLater(new Runnable() {
    public void run() {
        frame.addComponentListener(new ComponentAdapter() {
            public void componentResized(ComponentEvent e) {
                System.out.println("Component Listener 1");
            }
        });
    }
});
Run Code Online (Sandbox Code Playgroud)