这是一个有趣的问题,在我构建最后一个JDialog时没有出现,即使这个问题比这更复杂。无论如何,这里是导致问题的代码。
public class Test extends JDialog{
private final JButton cancel, ok;
private final JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 50, 5));
public Test(JFrame parent) {
//Initialize the JDialog
super(parent, "Select Chapters");
setLayout(new BorderLayout());
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
setModalityType(JDialog.ModalityType.APPLICATION_MODAL);
setSize(300, 300);
setLocationRelativeTo(null);
cancel = new JButton("Cancel");
ok = new JButton("OK");
buttonPanel.add(cancel);
buttonPanel.add(ok);
getContentPane().add(buttonPanel, BorderLayout.SOUTH);
setVisible(true);
cancel.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
dispose();
}
});
}}
主要方法
Test test = new Test(new JFrame());
我将事件监听器放在构造函数中进行测试,但实际的实现应该在另一个类中进行。这就是为什么这是一个问题。如果我把动作监听器放在setVisible(true)之前,那么一切都按原样运行。但我不能这样做,因为事件处理程序将在另一个类中实现。是什么导致了这个问题,我该如何解决?
答案 0 :(得分:3)
如果在setVisible(true)之后放置JDialog中的事件处理程序
正确,因为JDialog是模态的,所以在对话框关闭之前不会执行setVisible()之后的语句。
在对话框可见之前,没有理由不能将ActionListener添加到按钮。代码在一个单独的类中并不重要。您只需在创建按钮的类的构造函数中创建该类的实例。
在实现侦听器
后,我将setVisible()放在另一个类中
你还在做错事。 setVisible()应该在您的主类中,您可以在其中设置对话框属性并创建所有组件并将组件添加到对话框中。
我不确定你为什么这么做。您的代码可以是:
cancel = new JButton("Cancel");
cancel.addActionListener( new SomeActionListenerClass() );
...
setVisible( true );
答案 1 :(得分:2)
您需要在构造函数的末尾放置setVisible(true),因为对话框是模态的,在这种情况下,setVisible(true)将不会返回,直到您调用setVisible(false)。
引用Java doc:https://docs.oracle.com/javase/7/docs/api/java/awt/Dialog.html#setVisible(boolean)
模态对话框的注释。
setVisible(true):如果对话框尚未显示,则此调用将会显示 在通过调用setVisible(false)或隐藏对话框之前不会返回 处置。
setVisible(false):隐藏对话框,然后返回 setVisible(true)如果它当前被阻止。
可以这样称呼 事件调度线程的方法因为工具包确保了 阻止此方法时,其他事件不会被阻止。