2016-04-26 11 views
3

Hier ist (eine eingeschränkte Version von) was ich habe. (Ich fand den Code auf diese Weise):JPopupMenu Aktion nicht ausgelöst

class CustomPopup extends JPopupMenu { 
    public CustomPopup() {} 

    @Override 
    public void setVisible(boolean visible) 
    { 
     // Case 1: 
     //if (visible) super.setVisible(visible); 
     // Case 2: 
     super.setVisible(visible); 
    } 
} 

class CustomPanel extends JPanel { 
    // .../... 
    public CustomPanel() { 
     setSize(200, 200); 
     addMouseListener(new MouseAdapter(){ 
      @Override 
      public void mousePressed(MouseEvent e){ 
       onMousePressed(e); 
      } 
     }); 

    } 

    public void onMousePressed(MouseEvent e) 
    { 
     JPopupMenu pop = new JPopupMenu(); 

     pop.add(new AbstractAction("foo") 
     { 
      @Override 
      public void actionPerformed(ActionEvent e) 
      { 
       // do stuff 
       System.out.println("this is executed"); 
      } 
     }); 
     pop.show(e.getComponent(), e.getX(), e.getY()); 
    } 
} 

public class TestPopup extends JFrame { 
    CustomPanel _pp; 
    CustomPopup _cpop; 

    public TestPopup() { 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 
     setSize(333, 333); 
     _cpop = new CustomPopup(); 
     _pp = new CustomPanel(); 
     _cpop.add(_pp); 

     addMouseListener(new MouseAdapter(){ 
      @Override 
      public void mousePressed(MouseEvent e){ 
       _cpop.show(e.getComponent(), 0, 0); 
      } 
     }); 
    } 
    public static void main(String[] args) { 
     java.awt.EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       (new TestPopup()).setVisible(true); 
      } 
     }); 
    } 
} 

Ein Popup-Menü zeigt ein benutzerdefiniertes Bedienfeld an. Bei der Interaktion zeigt es ein klassisches Popup-Menü mit einer Auswahlliste.

Mein Problem ist, dass die CustomPopup schließt sich nicht so, wie es sollte. Der Übeltäter ist offensichtlich die Überschreibung von setVisible, aber wenn ich die override-Methode entfernen (oder die Bedingung auskommentieren) habe ich ein anderes Problem: die actionPerformed Methode, die auf pop hinzugefügt wird, wird nie aufgerufen.

Im ersten Fall:

  1. CustomPopup öffnet
  2. ich auf etwas klicken darin
  3. Die JPopupMenu öffnet und die CustomPopup sichtbar bleibt
  4. ich auf ein Element des neuen klicken Menü
  5. Die Action wird ausgelöst

Im zweiten Fall:

  1. CustomPopup öffnet
  2. ich in der es auf etwas klicken
  3. Die JPopupMenu öffnet und die CustomPopup versteckt
  4. I der auf ein Element klicken neues Menü
  5. Die Action ist n ot ausgelöst

Meine Schlussfolgerung ist, dass die CustomPopup sichtbar sein muss, damit die Aktion auszulösen, auch wenn ich nicht wirklich verstehen, warum. Also meine Frage ist: wie man CustomPopup offen in einer Weise, die nicht bricht die Standard JPopupMenu Verhalten ODER wie die Aktion auslösen ordnungsgemäß mit CustomPopup versteckt?

+1

Warum nicht 'JComponent :: setComponentPopupMenu()'? – trashgod

+0

10 @trashgod kannst du mir mehr erzählen? Wie löst es das Problem? – gregseth

+0

Ich weiß nicht, dass es so wäre. Was passiert, wenn Sie es versuchen? Beachten Sie auch, dass ['isPopupTrigger()'] (https://docs.oracle.com/javase/tutorial/uiswing/components/menu.html#popup) überprüft werden muss, da "Popup-Menüs auf verschiedenen Systemen unterschiedlich ausgelöst werden. " – trashgod

Antwort

2

Es sieht so aus, dass das Eltern-Popup für die Auslösung von Aktionen sichtbar sein muss (klingt für mich plausibel). Also hast du alles gemacht, um es zum Laufen zu bringen, außer dem letzten Schritt: schließe das benutzerdefinierte Popup von selbst. Hier ist der Code:

class CustomPopup extends JPopupMenu { 
    public CustomPopup() {} 

    @Override 
    public void setVisible(boolean visible) 
    { 
     // Case 1: 
     if (visible) super.setVisible(visible); 
     // Case 2: 
//  super.setVisible(visible); 
    } 
    public void makeInvisible() { 
     super.setVisible(false); 
    } 
} 

class CustomPanel extends JPanel { 
    // .../... 
    public CustomPanel() { 
     setSize(200, 200); 
     addMouseListener(new MouseAdapter(){ 
      @Override 
      public void mousePressed(MouseEvent e){ 
       onMousePressed(e); 
      } 
     }); 

    } 

    public void onMousePressed(MouseEvent e) 
    { 
     JPopupMenu pop = new JPopupMenu(); 

     pop.add(new AbstractAction("foo") 
     { 
      @Override 
      public void actionPerformed(ActionEvent e) 
      { 
       // do stuff 
       System.out.println("this is executed"); 
       Component comp = (Component) e.getSource(); 
       if (comp != null && comp.getParent() instanceof JPopupMenu) { 
        JPopupMenu popupMenu = (JPopupMenu) comp.getParent(); 
        if (popupMenu.getInvoker() instanceof CustomPanel) { 
         CustomPopup cpop = (CustomPopup) popupMenu.getInvoker().getParent(); 
         cpop.makeInvisible(); 
        } 
       } 
      } 
     }); 
     pop.show(e.getComponent(), e.getX(), e.getY()); 
    } 
} 

public class TestPopup extends JFrame { 
    CustomPanel _pp; 
    CustomPopup _cpop; 

    public TestPopup() { 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 
     setSize(333, 333); 
     _cpop = new CustomPopup(); 
     _pp = new CustomPanel(); 
     _cpop.add(_pp); 

     addMouseListener(new MouseAdapter(){ 
      @Override 
      public void mousePressed(MouseEvent e){ 
       _cpop.show(e.getComponent(), e.getX(), e.getY()); 
      } 
     }); 
    } 
    public static void main(String[] args) { 
     java.awt.EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       (new TestPopup()).setVisible(true); 
      } 
     }); 
    } 
} 
Verwandte Themen