2009-11-04 29 views
5

Tôi có một JDialog phương thức chưa được định dạng mà tôi muốn setVisible (false) khi người dùng nhấp vào bên ngoài hộp thoại phương thức.Làm thế nào để đóng một JDialog phương thức khi người dùng nhấp chuột bên ngoài JDialog?

Điều này có thể thực hiện được trong Swing không?

Điều tôi đang làm là bật trình chỉnh sửa tùy chỉnh cho trường văn bản như công cụ chọn ngày. Có cách nào dễ hơn để làm những gì tôi muốn không?

EDIT

Hãy nhớ rằng khối modal về cuộc gọi đến setVisible (true), do đó bạn không thể chỉ nói "không sử dụng một hộp thoại modal"

Và tôi đã cố gắng tập trung người nghe trên hộp thoại, họ không kích hoạt khi phương thức của nó.

+0

Bạn đã thử phương pháp addAWTEventListener chưa, điều này sẽ cung cấp cho bạn các sự kiện cho tất cả các loại sự kiện được chỉ định, ví dụ: trong ví dụ tôi đưa ra dưới đây sẽ là tất cả các sự kiện chuột. – vickirk

+0

Tôi biết bạn đã nói "vì vậy bạn không thể chỉ nói" không sử dụng hộp thoại phương thức "", có lẽ điều này là do bạn có mã thực hiện ngay sau cuộc gọi setVisible? Bạn có thể không di chuyển điều này vào có thể là một người nghe cho khi hộp thoại được đóng lại? Nếu không biết chi tiết về ứng dụng, nó có thể cung cấp một thiết kế rõ ràng hơn, đặc biệt là khi thử nghiệm đơn vị, tôi muốn chuyển các hộp thoại thành chiến lược để nhận phản hồi của người dùng. không đầu hoặc không cần phải gây rối với việc tạo ra các sự kiện theo chương trình. – vickirk

Trả lời

3

Đây không phải là hộp thoại phương thức nếu bạn có thể nhấp vào bên ngoài và "điều gì đó" xảy ra. Tất cả các câu trả lời là chính xác, bạn nên tạo một hộp thoại không có phương thức và sau đó xử lý với trường hợp sử dụng của bạn thông qua một FocusListener.

+0

Đây là câu trả lời gần nhất cho "Không". Đó là tất cả những gì tôi đã hỏi. Không phải làm thế nào tôi có thể đạt được điều này mà không có một hộp thoại phi phương thức. – Pyrolistical

0

Không thực sự là một hộp thoại modal sau đó nếu nhấn khác nơi đóng nó, có thể bạn muốn setAlwaysOnTop

Tuy nhiên, giống như sau nên làm các trick (chưa được kiểm tra). Lưu ý, tôi sẽ khuyên bạn nên di chuyển mã vào một cái gì đó tốt hơn được thiết kế hơn là sử dụng như được cung cấp.

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); 
+0

Tôi vừa thử nghiệm điều này và có vẻ như loại người nghe này cũng không nhận được bất kỳ sự kiện chuột nào từ bên ngoài hộp thoại phương thức. – Zalumon

0

Có thể thêm FocusListener và ẩn hộp thoại khi nó mất tiêu điểm. Có thể khó khăn nếu một số yếu tố trong hộp thoại có thể tập trung. Dù sao, thử nghiệm với nó.

+0

Có thể một hộp thoại phương thức (và các thành phần con) mất tập trung cho bất kỳ điều gì khác ngoài việc chuyển sang ứng dụng khác không? – vickirk

+0

Ah, hiểu ý bạn là gì, thay vào đó là một hộp thoại phương thức! Không biết tại sao điều này đã được bỏ phiếu xuống – vickirk

10

EDIT:Đã thay đổi để sử dụng WindowFocusListener thay vì FocusListener, cũng như kiểm tra các thành phần giảm dần trên tiêu điểm bị mất để không ẩn nếu thành phần con giành tiêu điểm.

Cách đơn giản là thêm trình nghe tập trung vào cửa sổ trên hộp thoại ẩn nó khi tiêu điểm bị mất. Tôi không thấy sự cần thiết về phương thức trong trường hợp này. Ví dụ:

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);     
      } 
     }); 
    } 
} 
+0

Mất tiêu điểm sẽ phải đảm bảo thành phần đạt được tiêu điểm không phải là thành phần con của hộp thoại, do đó bạn sẽ cần phải tìm kiếm cấu trúc phân cấp thành phần thông qua 'getParent()' – vickirk

+0

@vickirk - - điểm tốt. Tôi đã thay đổi ví dụ trên để kiểm tra các thành phần con cháu (được cho là một trường hợp cạnh, nhưng tôi đã tăng cường ví dụ để cho phép tạo một cửa sổ con của hộp thoại). Tôi cũng đã thay đổi nó để sử dụng trình nghe tập trung vào cửa sổ. –

+0

Có, tôi hoàn toàn hiểu làm thế nào người ta có thể làm điều này mà không có một hộp thoại phương thức, nhưng điểm của câu hỏi là nếu nó có thể làm điều đó với một hộp thoại phương thức. Ưu điểm chính của việc sử dụng hộp thoại phương thức là nó chặn khi setVisible (true). Mục tiêu của tôi là không cần phải cơ cấu lại chương trình để sử dụng một hộp thoại không có phương thức hoặc viết một tiện ích để mô phỏng tính chất chặn trong một hộp thoại không có phương thức. – Pyrolistical

0

Sử dụng WindowListener và xử lý cửa sổĐã tắt() sự kiện.

+0

Tôi chỉ thử nghiệm điều này và đối với tôi phương pháp này dường như chỉ hoạt động khi nhấp hoàn toàn bên ngoài ứng dụng java, nhưng không phải khi cố gắng nhấp vào khung chính java đã sinh ra hộp thoại phương thức. – Zalumon

+0

@Zalumon, tôi đoán câu trả lời này không rõ ràng lắm. Đây là một gợi ý KHÔNG sử dụng JDialog phương thức. Khi bạn sử dụng JDialog phương thức làm cửa sổ bật lên, bạn không thể đóng hộp thoại nếu bạn nhấp vào bên ngoài hộp thoại. Đây là một giải pháp để cho phép bạn đóng một hộp thoại 'không phương thức 'khi bạn bấm vào bên ngoài vùng hộp thoại, do đó," hộp thoại bật lên "được đóng lại. – camickr

1

Không cần thiết phải là một hộp thoại phương thức (phương thức có nghĩa là nó ngăn bạn sử dụng cửa sổ chủ sở hữu cho đến khi bạn ẩn hộp thoại). Tốt hơn hãy thử điều này:

final JDialog dlg ... 
dlg.setModal(false); 

dlg.addWindowFocusListener(new WindowFocusListener() {    
    public void windowLostFocus(WindowEvent e) { 
     dlg.setVisible(false); 
    }    
    public void windowGainedFocus(WindowEvent e) { 
    } 
}); 
1

Cố gắng đặt phương thức thành false, sau đó sử dụng windowsDeactivated() cho hộp thoại close de (dialog.dispose()), hoạt động cho tôi.

Các vấn đề liên quan