JMenu submenu mouse listener didn't listen; action listener did--why? - java

I just began using JMenu. To ease into it, I decided to use Netbeans form design tool, which has worked great for all components in this app.
Clicking a top-level menu item works great.
For one menu item, I made a submenu with 3 items, each with a mouse click listener.
Here's relevant code for one of the 3 submenus:
private JMenuItem mnuEditDicAddAllScratch;
mnuEditDicAddAllScratch = new JMenuItem();
private void mnuEditDicAddAllScratchMouseClicked(MouseEvent evt) {
new WordsToAdd(); // never happened
}
mnuEditDicAddAllScratch.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent evt) {
mnuEditDicAddAllScratchMouseClicked(evt);
}
});
mnuEdit.add(mnuEditDicAddAllScratch);
It didn't work. Clicks ignored.
So I tried an Action listener:
private void mnuEditDicAddAllScratchActionPerformed(ActionEvent evt) {
new WordsToAdd(); // WORKED
}
mnuEditDicAddAllScratch.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
mnuEditDicAddAllScratchActionPerformed(evt);
}
});
And it worked.
So a question is, "Why didn't mouse click listener listen?"
Also, "If I should stay away from mouse click events, why or under what circumstances?"
(And, pre-emptive strike: I should stay away from Netbeans form designer.)

You should use the best tool for the job at hand. This means that for JMenuItems and for JButtons, you should use ActionListeners, not MouseListeners (exceptions notwithstanding). For instance if you disable a button, you want the button to not work, right? This works with ActionListeners but not with MouseListeners.
For the best information on this type of stuff, go to the source: Swing Tutorials.

mnuEditDicAddAllScratch.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
mnuEditDicAddAllScratchActionPerformed();
}
});

Related

How to "close" a JMenu in an Event Handler - Java

I have a simple MouseAdapter that I add to a JMenu. I want the menu to show its contents when moused over, react when clicked on, and hide its contents when the mouse leaves it. Here's where I add the listener:
public final void addGuiReaction(Runnable clickReaction) {
JMenu THIS = this;
this.addMouseListener(new MouseAdapter() {
final Runnable reaction = clickReaction;
final JMenu source = THIS;
#Override
public void mouseClicked(MouseEvent arg0) {reaction.run();}
#Override
public void mouseEntered(MouseEvent arg0) {source.doClick();} // Opens the menu
#Override
public void mouseExited(MouseEvent arg0) {/* Need to "close" the menu */}
});
}
This works just fine for both the reaction and the open when moused over functionality, but I can't figure out how to close it. Tried both setSelected(false) and setPopupMenuVisible(false) but the issue with both is that the menu doesn't open again the next time I mouse over it.
Anyone knows a nice way of closing the menu?
Answering to "How to close the JMenu..."
In place of this:
/* Need to "close" the menu */
You can put this:
source.dispatchEvent(new KeyEvent(source, KeyEvent.KEY_PRESSED, 0, 0, KeyEvent.VK_ESCAPE));
Hence simulate the ESC key press which will trigger the respective Action from the ActionMap of the JMenuBar.
However this will not fully solve your problem as while the keyboard arrow keys will work, you will not be able to use the mouse to select any of the items of the JMenu as trying to enter any of them will trigger the JMenu mouseExited event. You may need to attach a proper mouse event listener to the menu items as well.

Netbeans JPopupMenu Issues

I made a popup menu in Netbeans and I want to make a menu item that sends me to another GUI when I press it, but I don't know how.
I have to do something like a restaurant menu and when someone presses the button from the menu to send them to a specific type of food.
I made it only to popup when I right click it.
private void formMousePressed(java.awt.event.MouseEvent evt) {
if(evt.isPopupTrigger()){
jPopupMenu1.show(evt.getComponent(),evt.getX(),evt.getY());
}
}
private void formMouseReleased(java.awt.event.MouseEvent evt) {
if(evt.isPopupTrigger()){
jPopupMenu1.show(evt.getComponent(),evt.getX(),evt.getY());
}
}
"I want to make a menu item that sends me to another GUI when I press it, but I don't know how."
I'm, not sure how the drag and drop works with GUI Builder for JPopupMenu. I tried to to drap and drop it, but it won't show the display, so I couldn't just drag and drop JMenuItems to it. So I had to hand code it.
I dragged a JPopupMenu to the frame (jPopupmenu1);
In the constructor, I added a JMenuItem to it.
I added an ActionListener to the JMenuItem
Just show instantiate the second GUI , and maybe dispose of the second, depending on your preference
public NewJFrame() {
initComponents();
JMenuItem item1 = new JMenuItem("Open GUI2");
jPopupMenu1.add(item1);
item1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
new GUI2();
}
});
}
....
private void formMousePressed(java.awt.event.MouseEvent evt) {
if (evt.isPopupTrigger()) {
jPopupMenu1.show(evt.getComponent(), evt.getX(), evt.getY());
}
}
private void formMouseReleased(java.awt.event.MouseEvent evt) {
if (evt.isPopupTrigger()) {
jPopupMenu1.show(evt.getComponent(), evt.getX(), evt.getY());
}
}
It works fine for me

About JPanels and menus the best away

I am planning to make a program that in the top of the contentPane has a menubar.
Under this menubar another JPanel, here is what I did (it works), but I don't know if this is the best way:
I made a lot of JPanels with different buttons, I want that a JMenuItem changes the screen(JPanel)
So what I did for each JMenuItem that set the specific JPanel(all panels are in the same position in the GridBagLayout, but all start with .setVisible(false);)
jemnuitem1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
jpanelItem1.setVisible(true);
jpanelItem2.setVisible(false);
jpanelItem3.setVisible(false);
}
});
jemnuitem2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
jpanelItem1.setVisible(false);
jpanelItem2.setVisible(true);
jpanelItem3.setVisible(false);
}
});
jemnuitem3.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
jpanelItem1.setVisible(false);
jpanelItem2.setVisible(false);
jpanelItem3.setVisible(true);
}
});
This works, but I want to know if there is a way better to do this, or can I have a big problem doing this, because if this works, its fine for me work in this way, but I want the help of others that already made something similar.
You should use CardLayout. Then you can switch the visible panel instead of writing clumsy code like you have now.

Why is a WindowBuilder event not getting called?

I created a Java app in WindowBuilder for Eclipse. I built a menu and on one of the menu items I added the mouseclicked event.
JMenuItem mitemAbout = new JMenuItem("About");
mitemAbout.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent arg0) {
JOptionPane.showInternalMessageDialog( form, "Message", "title", JOptionPane.PLAIN_MESSAGE);
}
});
mitemHelp.add(mitemAbout);
I put a breakpoint on the JOptionPane line and when I click on the menu item in debug mode it doesn't even get to it.
Am I completely missing a step here?
Although JMenuItem components offer the addMouseListener method (inherited from java.awt.Component) MouseEvents are only processed for the MenuElements own functional use, i.e. any external MouseEvents will have no effect.
For JMenuItem components, use an ActionListener rather than a MouseListener to listen for user events:
mitemAbout.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
...
}
});
or use:
mitemAbout.setAction(myAction);

stackoverflow error when I add a glasspane to my frame

I am trying to add a universal right click to textfields in my application. I came across a solution where I could add a glass pane on top my frame, make it invisible and register that as a universal mouse listener. If the component is a text field I show the pop up menu, otherwise I redispatch the event. I have pasted the code below...
This example works fine. But when I use this with my application though, I get a stackoverflow error at
Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError
at apple.awt.CWindow._getLocationOnScreen(Native Method)
at apple.awt.CWindow.getLocationOnScreen(CWindow.java:878)
at java.awt.Component.getLocationOnScreen_NoTreeLock(Component.java:1960)
at java.awt.Component.getLocationOnScreen(Component.java:1938)
at javax.swing.SwingUtilities.convertPointToScreen(SwingUtilities.java:364)
at javax.swing.SwingUtilities.convertPoint(SwingUtilities.java:165)
at com.aesthete.csmart.ui.common.components.RightClickGlassPane.redispatchMouseEvent(RightClickGlassPane.java:79)
at com.aesthete.csmart.ui.common.components.RightClickGlassPane.mouseEntered(RightClickGlassPane.java:61)
I understand that every time the mouse is entered on a component the glass pane receives the event and then redispatches. But why is it getting converted into a recursive call?
EDIT:
Just wanted to show everyone how I solved it with Camickr suggestion:
SwingUtilities.invokeLater(new Runnable() {
public void run() {
final JPopupMenu popup = new JPopupMenu();
JMenuItem mnItemCopy = new JMenuItem("Copy", CommonUI.getScaledImage(13, 13, "/images/copy.png"));
JMenuItem mnItemCut = new JMenuItem("Cut", CommonUI.getScaledImage(13, 13, "/images/cut.png"));
JMenuItem mnItemPaste = new JMenuItem("Paste", CommonUI.getScaledImage(13, 13, "/images/paste.png"));
popup.add(mnItemCopy);
popup.add(mnItemCut);
popup.add(mnItemPaste);
Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
#Override
public void eventDispatched(AWTEvent event) {
if(event instanceof MouseEvent) {
MouseEvent mouseevent=(MouseEvent)event;
if(mouseevent.isPopupTrigger()) {
if (mouseevent.getComponent() instanceof JTextField) {
popup.show(mouseevent.getComponent(), mouseevent.getX(), mouseevent.getY());
}
}
}
}
}, AWTEvent.MOUSE_EVENT_MASK);
}
});
I am trying to add a universal right click to textfields in my application.
Check out Global Event LIsteners. Just check the source of the event and do processing as required. No need to redispatch events.
Note, you should NOT assume a right click is the LAF way to display a popup. Read the section from the Swing tutorial on Bringing Up a Popup Menu for a better solution.

Categories

Resources