我认为答案是在完成所有初始组件大小调整之后,但请看一下这个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();
}
});
}
}
即使在调整框架大小并使其可见之后添加了组件侦听器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)
对于我的应用程序,我希望在以编程方式设置所有初始大小调整之后添加ComponentListener,而不会触发componentResized(直到用户实际更改框架/组件的大小)。我怎么能这样做?
编辑:我知道有很多方法可以解决这个问题,例如添加一个最初为false的布尔值并在之后设置,以忽略第一个resize事件。然而,这对我来说并不像超级健壮,我只是想知道发生了什么。
答案 0 :(得分: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");
}
});
}
});