# JPopupMenu per Klick schließen und gleichzeitig ActionEvent auf JButton?



## MasterChristian (9. Feb 2012)

Ich habe folgendes Problem:

Ich habe mehrere JButtons. Wenn ich über diese Fahre öffnet sich neben den Buttons per MouseListener ein JPopUpMenu das wieder verschwindet wenn ich den Button oder das Menu verlasse.

Nun ist es ja standartmäßig so, dass das Popup auch per Mausklick schließt. Leider führt dies aber dazu, dass ich den Button nur aktivieren kann wenn ich zweimal klicke, da beim ersten Klick lediglich das JPopUp Menu schließt aber nicht das Event auf dem Button ausgeführt wird. Kann man das irgendwie ändern?

MfG MasterChristain


----------



## HelgeW (9. Feb 2012)

Wenn ich Dich richtig verstanden habe, dann klickst Du einen Menüpunkt innerhalb des Popups an, richtig?
Wenn dem so ist, dann würde ich sowohl für den Button als auch für das Menu die selbe Action hinterlegen und somit würde in beiden Fällen das gleiche passieren.

Gruss Helge


----------



## MasterChristian (9. Feb 2012)

Nein, das Popup öffnet wenn der Mauszeiger den Button betritt neben dem Mauszeiger. Wenn ich nun aber nicht ins Popup möchte sondern den Button normal drücken, dann muss ich dies zweimal tun da mit dem ersten Klick lediglich das PopuP schließt.

MfG MasterChristian


----------



## Michael... (9. Feb 2012)

Warum ein Popup über einem Button?
Wie ist das ganze implementiert? Kannst Du Bsp Code posten?


----------



## MasterChristian (9. Feb 2012)

Ist einfach per MouseListener gelöst (bParamControl ist der Button):

bParamControl.addMouseListener(new MouseAdapter() {

			public void mouseEntered(MouseEvent e) {				
				popParamControl.show(Main_FL.this, e.getXOnScreen() - Main_FL.this.getX() , e.getYOnScreen() - Main_FL.this.getY());	
			}

Es geht darum, dass beim Klick auf den Button eine TabbedPane mit mehreren Tabs aufgeht. Wahlweise soll man über das PopUp Menü direkt zu einem speziellen Tab springen können.

MfG MasterChristian


----------



## Michael... (9. Feb 2012)

Bei mir (Windows XP) kann ich das nicht nachvollziehen. Beim ersten Klick wird das Popup ausgeblendet und der Button gedrückt.

```
public static void main(final String[] args) {
		JFrame frame = new JFrame();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setBounds(0, 0, 300, 300);
		
		final JButton button = new JButton("PRESS");
		final JPopupMenu menu = new JPopupMenu();
		menu.add(new JMenuItem("SSS"));
		menu.add(new JMenuItem("SSS"));
		menu.add(new JMenuItem("SSS"));
		frame.add(button, BorderLayout.SOUTH);
		frame.setVisible(true);

		button.addMouseListener(new MouseAdapter() {
			public void mouseEntered(MouseEvent e) {
				if (!menu.isVisible())
					menu.show(button, e.getX(), e.getY());
			}
		});
		button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				System.out.println("Button pressed");
			}
		});
	}
```


----------



## Andi_CH (9. Feb 2012)

Leider sieht man den Mauszeiger auf den Sreenscots nicht.
Bei reinfahren in den Button kommt das gewünshte. Wenn ich reinklicke kommt es gleich wieder, einfach leicht verschoben.

Eigentlich hätte ich keine Chance den Button anzuklicken, wenn der nicht grösser als das PopUp wäre.

EDIT: Das stimmt so nicht, das ist der Fall wenn ich einen Eintrag anklicke, der genau über dem Button liegt. PopUp weg = MausEnter Event und Anzeige des Popups ...

Win7 64Bit aus Eclipse gestartet.


----------



## Michael... (9. Feb 2012)

Andi_CH hat gesagt.:


> Bei reinfahren in den Button kommt das gewünshte. Wenn ich reinklicke kommt es gleich wieder, einfach leicht verschoben.


Das ist klar. Hier ist ja auch noch kein Algorithmus hinterlegt, der verhindert, dass das Popup wieder erscheint, wenn man einen Eintrag in diesem anklickt. Schließlich wird - sofern sich das Popup über dem Button befindet - wieder mouseEntered ausgelöst. U.a. aus diesem Grund frage ich ja die ganze Zeit nach der genauen Implementierung.
Hiermit ging es nur darum zu zeigen, dass wenn ich neben dem Popup auf den Button klicke das Popup verschwindet und der Button gleichzeitig gedrückt wird. Also keine zwei Klicks notwendig sind.


----------



## bERt0r (9. Feb 2012)

Aber ist es nicht höchst unkonventionell ein Popupmenü anzuzeigen, nur weil man über einen Button fährt? Normalerweise öffnet man Popupmenüs per Rechtklick, im MouseEvent kannst du mit isPopupTrigger() abfragen ob du ein Popupmenü anzeigen sollst.


----------



## MasterChristian (10. Feb 2012)

Mag sein das es unkonventionell ist, aber es soll ja eigendlich einen klick sparen und daher ohne rechtsklick erscheinen.
Warum es bei dir funktioniert verstehe ich leider nicht. Hab es mehrmals getestet und bei mir wird das Event nur ausgeführt, wenn das Popup geschlossen ist.

MfG MasterChristian


----------



## MasterChristian (10. Feb 2012)

Solange das JPopUp Menu offen ist wird bei mir trotz Klick keinerlei Event ausgelöst, sondern nur das PopUp geschlossen. Hab das mal so getestet:


```
public void actionPerformed(ActionEvent e) {

		System.out.println("TEST EVENT");
```

Der Klick findet aber immer über dem Button statt, da ich es so eingestellt habe, dass das PopUp automatisch verschwindet, wenn die Maus den Button verlässt.


----------



## Michael... (10. Feb 2012)

Funktioniert es den mit meinem Testcode bei Dir?


----------



## MasterChristian (10. Feb 2012)

Ja der Funktioniert. Ich find aber den Unterschied einfach nicht, hab schon alles mögliche versucht.

MfG MasterChristian


----------



## Michael... (10. Feb 2012)

MasterChristian hat gesagt.:


> Ja der Funktioniert. Ich find aber den Unterschied einfach nicht, hab schon alles mögliche versucht.


Deswegen mein ständiges Fragen: Wie schaut die Implementierung bei Dir aus? Nach Möglichkeit auf den relevanten Code kürzen oder ein komplierbares Bsp posten.


----------



## truesoul (10. Feb 2012)

Also Michaels Beispiel funktioniert doch tadellos. 
Zu deinem Problem kann ich nichts sagen, warum das so ist, wie es ist, da ich nur Code von Michael hier sehe. Also solltest du evtl. ein bissl Code zeigen


----------



## MasterChristian (10. Feb 2012)

```
public void addComponentsMouseListener() {
		
		//Param Control
		bParamControl.addMouseListener(new MouseAdapter() {
			
			public void mouseEntered(MouseEvent e) {				
					popParamControl.show(Main_FL.this, e.getXOnScreen() - Main_FL.this.getX() , e.getYOnScreen() - Main_FL.this.getY());	
			}
			
			public void mouseExited(MouseEvent e) {	
				popupMenuCloseCheckButtonExit(popParamControl, e);				
			}
		});
		popParamControl.addMouseListener(new MouseAdapter() {
			public void mouseExited(MouseEvent e) {
				popupMenuCloseCheckPopupExit(popParamControl, e);
			}
		});
```

Zur Erklärung: bParamControl ist der Button und popParamControl das JPopUpMenu. Main_FL ist ein Frame.

in der Funktion popupMenuCloseCheckButtonExit (Ok komischer Name) überprüfe ich ob sich der Mauszeiger beim verlassen des Buttons über dem PopUp befindet. Ist dies nicht der Fall wird das Popup auf Visible = false gesetzt.
Das gleiche macht die Funktion popupMenuCloseCheckPopupExit. Nur das Hier geprüft wird ob der Mauszeiger nach verlassen des Popups über dem Button ist. So kann ich mit der Maus zwischen Button und PopUp hin und herfahren ohne das das PopuP verschwindet. Verlasse ich aber den Button oder das PopuP ohne in die jeweils andere Componente zu fahren, schließt das Popup.


```
public void popupMenuCloseCheckButtonExit(JPopupMenu popup, MouseEvent e)
	{
		if(popup.isShowing())
		{
			if((popup.getLocationOnScreen().x > e.getLocationOnScreen().x))
				popup.setVisible(false);
			else if((popup.getLocationOnScreen().x <= e.getLocationOnScreen().x
					&& popup.getLocationOnScreen().y > e.getLocationOnScreen().y))
				popup.setVisible(false);
		}
	}
	
	public void popupMenuCloseCheckPopupExit(JPopupMenu popup, MouseEvent e)
	{
		if(popup.isShowing())
		{
			if(e.getLocationOnScreen().x <= popup.getLocationOnScreen().x ||
					   e.getLocationOnScreen().x >= (popup.getLocationOnScreen().x + popup.getWidth()) ||
					   e.getLocationOnScreen().y <= popup.getLocationOnScreen().y ||
					   e.getLocationOnScreen().y >= popup.getLocationOnScreen().y + popup.getHeight())
			{					
				popup.setVisible(false);	
			}
		}
	}
```


----------

