代码之家  ›  专栏  ›  技术社区  ›  Pyrolistical

当用户单击JDialog外部时,如何关闭模式JDialog?

  •  5
  • Pyrolistical  · 技术社区  · 15 年前

    我有一个未修饰的模式jdialog,当用户单击模式对话框外部时,我想将其设置为可见(false)。

    这在摇摆中是可能的吗?

    我要做的是为文本字段弹出一个自定义编辑器,比如日期选择器。有没有更简单的方法来做我想做的?

    编辑

    记住调用setVisible(true)时的模式块,因此不能只说“不要使用模式对话框”。

    我试过将听众集中在对话上,他们不会在对话的模式中触发。

    7 回复  |  直到 13 年前
        1
  •  4
  •   taftster    15 年前

    如果你能点击它的外部并发生“某些事情”,它就不是一个模式对话框。所有的答案都是正确的,您应该创建一个非模态对话框,然后通过FocusListener处理您的用例。

        2
  •  11
  •   Chris B.    15 年前

    编辑: 更改为使用WindowFocusListener而不是FocusListener,并检查丢失焦点上的降序组件,以便在子组件获得焦点时不隐藏。

    一个简单的方法是在对话框上添加一个窗口焦点监听器,当焦点丢失时隐藏它。我不认为在这种情况下需要模态。例如:

    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.WindowEvent;
    import java.awt.event.WindowFocusListener;
    import java.awt.event.ActionListener;
    import java.awt.event.ActionEvent;
    
    public class ClickAwayDialog extends JDialog {
    
        public ClickAwayDialog(final Frame owner) {
            super(owner);
            JPanel pnl = new JPanel(new BorderLayout());
            pnl.add(new JLabel("Click outside this dialog in the parent frame to close it"), BorderLayout.NORTH);
            JButton btn = new JButton("Click Me");
            btn.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    JOptionPane.showMessageDialog(ClickAwayDialog.this, "New Child Window");
                }
            });
            pnl.add(btn, BorderLayout.CENTER);
            this.setContentPane(pnl);
            this.pack();
            this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
            this.setLocationRelativeTo(owner);
            this.setAlwaysOnTop(true);
            this.addWindowFocusListener(new WindowFocusListener() {
    
                public void windowGainedFocus(WindowEvent e) {
                    //do nothing
                }
    
                public void windowLostFocus(WindowEvent e) {
                    if (SwingUtilities.isDescendingFrom(e.getOppositeWindow(), ClickAwayDialog.this)) {
                        return;
                    }
                    ClickAwayDialog.this.setVisible(false);
                }
    
            });
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    JFrame parent = new JFrame();
                    parent.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
                    parent.setSize(300, 300);
                    parent.setLocationByPlatform(true);
                    parent.setVisible(true);
                    ClickAwayDialog dlg = new ClickAwayDialog(parent);
                    dlg.setVisible(true);                
                }
            });
        }
    }
    
        3
  •  1
  •   Gill    15 年前

    不必是模式对话框(模式意味着在隐藏对话框之前,它会阻止您使用所有者窗口)。最好试试这个:

    final JDialog dlg ...
    dlg.setModal(false);
    
    dlg.addWindowFocusListener(new WindowFocusListener() {            
        public void windowLostFocus(WindowEvent e) {
            dlg.setVisible(false);
        }            
        public void windowGainedFocus(WindowEvent e) {
        }
    });
    
        4
  •  1
  •   Edgar Colmenares    13 年前

    尝试将模式设置为false,然后对close de dialog(dialog.dispose())使用windowsdeactivated(),对我有效。

        5
  •  0
  •   vickirk    15 年前

    不是一个模态对话框,如果单击其他关闭它的位置,也许你想要 setAlwaysOnTop

    但是,类似下面这样的事情应该可以实现这个技巧(未经测试)。注意,我建议将代码移动到比所提供的更好的设计中。

    static JDialog dialog = ...
    
    Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
        public void eventDispatched(AWTEvent e) {
            dialog.setVisible(false);
    
            SwingUtils.invokeLater(new Runnable(){
                public void run(){
                    Toolkit.getDefaultToolkit().removeAWTEventListener(this);
                }
            });        
        }
    }, AWTEvent.MOUSE_EVENT_MASK);
    
    dialog.setVisible(true);
    
        6
  •  0
  •   Denis Tulskiy    15 年前

    可能添加一个 FocusListener 当对话框失去焦点时隐藏它。如果对话框中的某些元素具有焦点,则可能比较棘手。无论如何,试试看。

        7
  •  0
  •   camickr    15 年前

    使用WindowListener并处理WindowDeactivated()事件。