2010-04-05 10 views
12

मेरे पास एक पॉपअप है जो उपयोगकर्ता द्वारा बटन पर क्लिक करने पर दिखाया गया है। मैं पॉपअप को छिपाने के लिए चाहते हैं जब निम्न घटनाओं के किसी भी होते हैं:जब आप कहीं और क्लिक करते हैं तो स्विंग पॉपअप को कैसे छिपाते हैं

  1. उपयोगकर्ता आवेदन में कहीं और क्लिक करता है। (उदाहरण के लिए पृष्ठभूमि पैनल)
  2. उपयोगकर्ता एप्लिकेशन को कम करता है।

जेपीओपअपमेनू का यह व्यवहार है, लेकिन मुझे सिर्फ जेमेनू इटम्स से अधिक की आवश्यकता है। निम्नलिखित कोड ब्लॉक वर्तमान उपयोग को प्रदर्शित करने के लिए एक सरलीकृत चित्रण है।

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

public class PopupTester extends JFrame { 
    public static void main(String[] args) { 
    final PopupTester popupTester = new PopupTester(); 
    popupTester.setLayout(new FlowLayout()); 
    popupTester.setSize(300, 100); 
    popupTester.add(new JButton("Click Me") { 
     @Override 
     protected void fireActionPerformed(ActionEvent event) { 
     Point location = getLocationOnScreen(); 
      int y = (int) (location.getY() + getHeight()); 
      int x = (int) location.getX(); 
      JLabel myComponent = new JLabel("Howdy"); 
      Popup popup = PopupFactory.getSharedInstance().getPopup(popupTester, myComponent, x, y); 
      popup.show(); 
     } 
     }); 
     popupTester.add(new JButton("No Click Me")); 
     popupTester.setVisible(true); 
     popupTester.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 
} 

उत्तर

6

जैसा कि पजटन ने पिछली टिप्पणी में उल्लेख किया था, पॉपअप एक जेकंपोनेंट नहीं है जिसके लिए श्रोताओं को आसानी से बाध्य किया जा सकता है। लेकिन, जैसा कि इसके दस्तावेज़ीकरण में कहा गया है, "पॉपअप के कार्यान्वयन उपयोगकर्ता को [विषय]] प्रस्तुत करने के लिए अपने स्वयं के घटक बनाने और बनाए रखने के लिए ज़िम्मेदार हैं।"

तो इसे अपनी प्रस्तुति तंत्र के रूप में उपयोग करने में, आपके पॉपअप को खुद को वास्तविक स्विंग घटक किसी भी तरह के रूप में प्रस्तुत करना होगा। क्या यह उस घटक के लिए स्वयं पंजीकृत है। जब घटक फोकस खो देता है तो इसे स्वयं छिपाएं।

import java.awt.FlowLayout; 
import java.awt.Frame; 
import java.awt.Point; 
import java.awt.event.ActionEvent; 
import java.awt.event.WindowEvent; 
import java.awt.event.WindowFocusListener; 
import javax.swing.JButton; 
import javax.swing.JDialog; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JOptionPane; 
import javax.swing.Popup; 

public class PopupTester extends JFrame { 
    private static class MessagePopup extends Popup 
     implements WindowFocusListener 
    { 
     private final JDialog dialog; 

     public MessagePopup(Frame base, String message) { 
      super(); 
      dialog = new JOptionPane().createDialog(base, "Message"); 
      dialog.setModal(false); 
      dialog.setContentPane(new JLabel(message)); 
     } 
     @Override public void show() { 
      dialog.addWindowFocusListener(this); 
      dialog.setVisible(true); 
     } 
     @Override public void hide() { 
      dialog.setVisible(false); 
      dialog.removeWindowFocusListener(this); 
     } 
     public void windowGainedFocus(WindowEvent e) { 
      // NO-OP 
     } 

     public void windowLostFocus(WindowEvent e) { 
      hide(); 
     } 
    } 

    public static void main(String[] args) { 
    final PopupTester popupTester = new PopupTester(); 
    popupTester.setLayout(new FlowLayout()); 
    popupTester.setSize(300, 100); 
    popupTester.add(new JButton("Click Me") { 
     @Override 
     protected void fireActionPerformed(ActionEvent event) { 
     Point location = getLocationOnScreen(); 
      MessagePopup popup = new MessagePopup(popupTester, "Howdy"); 
      popup.show(); 
     } 
     }); 
     popupTester.add(new JButton("No Click Me")); 
     popupTester.setVisible(true); 
     popupTester.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 
} 
+0

यह एक अच्छा समाधान है। Popup में WindowFocusListener इंटरफ़ेस जोड़ना चाल करता है। मैं एक जेडियोलॉग के बजाय एक जेविंडो का उपयोग कर समाप्त हुआ क्योंकि मैं खिड़की की सजावट नहीं चाहता था। मैं अंतिम समाधान पोस्ट करूंगा। –

2

आप अपनी पृष्ठभूमि के पैनल के लिए MouseListener जोड़ सकते हैं और जब कोई पैनल पर क्लिक करता है पॉपअप छुपा सकते हैं।

आवेदन न्यूनीकरण पर प्रतिक्रिया करने के लिए, WindowListenerJFrame से जुड़ा हुआ उपयोग करें।

आदि, आदि थकाऊ लग सकता है, लेकिन निश्चित रूप से काम करेगा।

+0

अच्छा सुझाव। यह एक बड़े आवेदन के साथ कठिन हो जाता है क्योंकि मैं स्क्रीन पर हर घटक के लिए एक माउस लिस्टर नहीं जोड़ सकता। –

+0

यह एक दयालु बात है कि 'पॉपअप' स्वयं 'JComponent' नहीं है। फिर जब आप फोकस खो देते हैं तो आप घटनाओं को पकड़ने के लिए कुछ श्रोता संलग्न कर सकते हैं। हो सकता है कि 'JDialog' और फिर बस' माउस लिस्टर 'और इसकी' माउस एक्स्साइट() 'विधि का उपयोग करने पर विचार करें। – pajton

+0

जेडियलोग खिड़की की सजावट के सामान के साथ आता है। मैं जेडविंडो का उपयोग करने वाले कुछ को मजाक करने में सक्षम था लेकिन मैन्युअल इवेंट हैंडलिंग का एक टन है और यह अभी भी बहुत क्विर्की समाप्त होता है। क्या पॉपअप वास्तव में मूल रूप से टूट गया है कि यह इस तरह कुछ समर्थन नहीं कर सकता है? –

10

एक JPopupMenu का उपयोग करें। आप मेनू आइटमों के अलावा, इसमें कोई भी घटक जोड़ सकते हैं।

+3

मैं इस दृष्टिकोण को भी काम करने में सक्षम था। यह बहुत आसान होने के समाप्त होता है। जब मेनू मुख्य रूप से शो() विधि पर आवेदक के रूप में मुख्य फ्रेम पास करते हैं तो फोकस खोने पर केवल छिपाने का व्यवहार ही काम करता है। यदि आप सेट विज़िबल (सत्य) का उपयोग करते हैं तो आपको वांछित व्यवहार नहीं मिलेगा। –

+2

मैं यह नियमित रूप से भी करता हूं। बस जेपीओपअपमेनू के लेआउट को सीमा सीमा पर सेट करें और केंद्र की बाधा के साथ अपनी सामग्री जोड़ें। JPopupMenu मनमाने ढंग से स्विंग सामग्री प्रस्तुत करने में कोई समस्या नहीं है। – CarlG

+0

मैंने और अधिक दृष्टिकोण (सीमाहीन JDialog, javax.swing.Popup) की कोशिश की और यह सबसे अच्छा समाधान प्रतीत होता है। –

1

आप अपनी पॉपअप-विंडो में फ़ोकस लिस्टनर जोड़ सकते हैं, और जब इसे फोकस खो देता है तो इसका निपटान करें। हालांकि, इससे आपको कुछ परेशानी होगी क्योंकि फोकस हानि किसी अन्य एप्लिकेशन के कारण होती है (नई खिड़कियां अग्रभूमि में आती हैं, आप वर्चुअल डेस्कटॉप इत्यादि स्विच करते हैं)

लेकिन शायद आप (ए) जानते हैं कि इसमें नहीं हो सकता आपका मामला या (बी) वैसे भी ऐसे मामलों में पॉपअप को बंद करना चाहते हैं, फोकस-आधारित दृष्टिकोण अभी भी आपके लिए दिलचस्प हो सकता है।

2

धन्यवाद पैजटन और नोएल एंग मुझे सही दिशा में इंगित करने के लिए धन्यवाद! यहां वह समाधान है जिसके साथ मैं समाप्त हुआ। मैं इसे यहां शामिल कर रहा हूं ताकि अन्य इससे लाभ उठा सकें।

मैं एक जेविंडो के साथ जा रहा था क्योंकि इसे खिड़की की सजावट नहीं मिलती है लेकिन फोकस घटनाएं मिलती हैं।

import java.awt.*; 
import java.awt.event.*; 

import javax.swing.*; 

public class PopupTester extends JFrame { 
    private static class MessagePopup extends Popup implements WindowFocusListener { 
    private final JWindow dialog; 

    public MessagePopup(Frame base, JLabel component, int x, int y) { 
     super(); 
     dialog = new JWindow(base); 
     dialog.setFocusable(true); 
     dialog.setLocation(x, y); 
     dialog.setContentPane(component); 
     component.setBorder(new JPopupMenu().getBorder()); 
     dialog.setSize(component.getPreferredSize()); 
     dialog.addKeyListener(new KeyAdapter() { 
     @Override 
     public void keyPressed(KeyEvent e) { 
      if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { 
      dialog.setVisible(false); 
      } 
     } 
     }); 
    } 

    @Override 
    public void show() { 
     dialog.addWindowFocusListener(this); 
     dialog.setVisible(true); 
    } 

    @Override 
    public void hide() { 
     dialog.setVisible(false); 
     dialog.removeWindowFocusListener(this); 
    } 

    public void windowGainedFocus(WindowEvent e) { 
     // NO-OP 
    } 

    public void windowLostFocus(WindowEvent e) { 
     hide(); 
    } 
    } 

    public static void main(String[] args) { 
    final PopupTester popupTester = new PopupTester(); 
    popupTester.setLayout(new FlowLayout()); 
    popupTester.setSize(300, 100); 
    popupTester.add(new JButton("Click Me") { 
     @Override 
     protected void fireActionPerformed(ActionEvent event) { 
     Point location = getLocationOnScreen(); 
     int x = (int) location.getX(); 
     int y = (int) (location.getY() + getHeight()); 
     JLabel myComponent = new JLabel("Howdy"); 

     MessagePopup popup = new MessagePopup(popupTester, myComponent, x, y); 
     popup.show(); 
     } 
    }); 
    popupTester.add(new JButton("No Click Me")); 
    popupTester.setVisible(true); 
    popupTester.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 
} 
संबंधित मुद्दे

 संबंधित मुद्दे