Hey Community,
Ich möchte für mein Programm eine Möglichkeit einbauen, dass wenn ich ein bestimmtes Objekt mit der rechten Maustaste anklicke, sich ein JPanel (zentriert zur Klick-Stelle) öffnet.
Das Fenster, welches sich öffnet soll erst wieder geschlossen werden, wenn ich die rechte Maustaste loslasse oder wenn die Maus das Fenster verlässt.
Zusätzlich sind auf dem Fenster, welches sich öffnet 2 Labels. Wenn die Maus in einem der beiden Labels losgelassen wird, soll es eine Funktion aufrufen.
Dazu habe ich nun folgende Funktion geschrieben:
Code
[spoiler]``` private void showMenu(int x, int y){ //wird bei einem Klick auf das gewünschte Object aufgerufen, mit dem x-/y-Abstand
if(panel == null){
panel = new JPanel();
panel.setLayout(null);
JLabel autoeat = new JLabel();
autoeat.setIcon(new ImageIcon(getClass().getResource("Menu/autoeat.png")));
autoeat.setBounds(18,19,214,51);
autoeat.addMouseListener(new MouseAdapter() {
public void mouseReleased(MouseEvent arg0) {
//rufe eine Funktion auf
}
});
panel.add(autoeat);
JLabel stopeat = new JLabel();
stopeat.setIcon(new ImageIcon(getClass().getResource("Menu/stopeat.png")));
stopeat.setBounds(18,80,214,51);
stopeat.addMouseListener(new MouseAdapter() {
public void mouseReleased(MouseEvent arg0) {
//rufe eine Funktion auf
}
});
panel.add(stopeat);
JLabel label = new JLabel();
label.setBounds(0,0,250,150);
label.setIcon(new ImageIcon(getClass().getResource("Menu/Menu.png")));
label.addMouseListener(new MouseListener(){
public void mousePressed(MouseEvent argo0){
}
public void mouseExited(MouseEvent arg0) {
panel.setVisible(false);
}
public void mouseReleased(MouseEvent arg0){
panel.setVisible(false);
}
public void mouseClicked(MouseEvent arg0) {
}
public void mouseEntered(MouseEvent arg0) {
}
});
panel.add(label);
screen.addMenu(panel);
}```[/spoiler]
Leider habe ich jetzt 2 Probleme:
Wenn ich klicke öffnet sich das Fenster zwar, aber wenn ich dann wieder loslasse schließt es sich nicht. Erst wenn ich dann nochmal auf das Fenster klicke und wieder loslasse schließt es sich.
Wenn ich mit der Maus auf eins der beiden Labels gehe, wird das schon als mouseExited() gewertet, und das Fenster schliesst sich.
[INDENT]-> das Problem könnte ich jedoch einfach lösen, wenn ich nicht einen zusätzlichen Mouselistener ins „Button“-Label hinzufüge, sondern einfach nur prüfe ob die das Mausevent auf dem JPanel an der Stelle eines der Label ist[/INDENT]
Wenn du dich damit abfinden kannst, dass sich das dann so verhält, wie jedes andere Popup-Menu auch, könntest du ein JPopupMenu verwenden: http://docs.oracle.com/javase/tutorial/uiswing/components/menu.html#popup (das würde ich empfehlen, solche eigenen Basteleien sind meist deutlich aufwändiger zu implementieren, und Abweichungen von Konventionen dem Benutzer oft schwer zu vermitteln)
Ich habe diese Funktion schon einmal in einem Spiel gesehen. (Mit Rechtsklick öffnete sich ein Menu, in dem dann mehrere Auswahlmöglichkeiten waren - BeispielVideo)
Die Version ist in dem Video zu komplex für mich, aber so ähnlich würde ich sie gerne übernehmen, da diese Möglichkeit eine schnelle Auswahl schafft.
Also das sind ja zwei Dinge. Einmal das Aussehen des Menüs und einmal die Art und Weise wie es erscheint.
Zum Aussehen: Da wirst du nicht drumherum kommen selbst was zu machen. JPopupMenu ist halt das standardmäßige Menu-Popup als Liste mit Abgrenzungen.
Zum Triggern: Das kannst du durchaus an deine Bedürfnisse anpassen. Du musst ja ohnehin MouseListener implementieren um zu definieren wann das Menü auftaucht. Wenn du willst, dass es nur dann da ist, wenn du die rechte Taste gedrückt hältst, dann implementier es doch so. Musst eben dann darauf achten, dass sich gemerkt wird worauf die Auswahl der Maus lag, wenn du willst, dass ohne weiteren Klick der Menüeintrag des Kontextmenüs aufgerufen wird.
*** Edit ***
Jaja, die eigene Neugier konnte ich mal wieder nicht einfangen.
Also fürs Erscheinen/Verschwinden sollte schon ein Listener wie der hier genügen:
JPopupMenu popup;
PopupListener(JPopupMenu popupMenu) {
popup = popupMenu;
}
public void mousePressed(MouseEvent e) {
popup.show(e.getComponent(), e.getX(), e.getY());
}
public void mouseReleased(MouseEvent e) {
popup.setVisible(false);
}
}```
Kannst du natürlich beliebig anpassen, wenn du kein JPopupMenu willst. Das ganze Beispiel (abgewandelte Version des offiziellen JPopupMenu-Beispiels):
```import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ModifiedPopupMenuDemo implements ActionListener {
JTextArea output;
JScrollPane scrollPane;
String newline = "
";
public Container createContentPane() {
// Create the content-pane-to-be.
JPanel contentPane = new JPanel(new BorderLayout());
contentPane.setOpaque(true);
// Create a scrolled text area.
output = new JTextArea(5, 30);
output.setEditable(false);
scrollPane = new JScrollPane(output);
// Add the text area to the content pane.
contentPane.add(scrollPane, BorderLayout.CENTER);
return contentPane;
}
public void createPopupMenu() {
JMenuItem menuItem;
// Create the popup menu.
JPopupMenu popup = new JPopupMenu();
menuItem = new JMenuItem("#1");
menuItem.addActionListener(this);
popup.add(menuItem);
menuItem = new JMenuItem("Numero 2");
menuItem.addActionListener(this);
popup.add(menuItem);
// Add listener to the text area so the popup menu can come up.
MouseListener popupListener = new PopupListener(popup);
output.addMouseListener(popupListener);
}
public void actionPerformed(ActionEvent e) {
JMenuItem source = (JMenuItem) (e.getSource());
String s = "Open menu: " + source.getText();
output.append(s + newline);
output.setCaretPosition(output.getDocument().getLength());
}
private static void createAndShowGUI() {
// Create and set up the window.
JFrame frame = new JFrame("PopupMenuDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Create/set menu bar and content pane.
ModifiedPopupMenuDemo demo = new ModifiedPopupMenuDemo();
frame.setContentPane(demo.createContentPane());
// Create and set up the popup menu.
demo.createPopupMenu();
// Display the window.
frame.setSize(450, 260);
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
class PopupListener extends MouseAdapter {
JPopupMenu popup;
PopupListener(JPopupMenu popupMenu) {
popup = popupMenu;
}
public void mousePressed(MouseEvent e) {
popup.show(e.getComponent(), e.getX(), e.getY());
}
public void mouseReleased(MouseEvent e) {
popup.setVisible(false);
}
}
}```
*** Edit ***
In meinem Beispiel wird übrigens nicht zwischen Rechtsklick, Linksklick oder sonstwas unterschieden. Das kannst du natürlich je nach Bedarf noch anpassen bei dir. ;)
[QUOTE=Gonzo]Also das sind ja zwei Dinge. Einmal das Aussehen des Menüs und einmal die Art und Weise wie es erscheint.
[…]
In meinem Beispiel wird übrigens nicht zwischen Rechtsklick, Linksklick oder sonstwas unterschieden. Das kannst du natürlich je nach Bedarf noch anpassen bei dir. ;)[/QUOTE]
WoW
Dass sieht richtig gut aus.
Ich werde jetzt versuchen das so in mein Projekt einzubauen.
Hoffe es klappe ^-^
Vielen Dank !
EDIT [19:01 12.09.2013]: Ich habe es jetzt in mein Projekt eingebaut und alles Funktioniert #solved