Giving Jmenuitem's Name to It's Actionlistener

Giving JMenuItem's name to it's ActionListener

Why aren't you calling setActionCommand on the menuitem. Instead of using setName, if you call setActionCommand, you should get what you expect when you call getActionCommand

Also, its label, not lable.

Adding an ActionListener to JMenuItem

What it looks to me is you have

JMenuBar menuBar = new JMenuBar();

JMenu file = new JMenu("File");
JMenuItem exitItem = new JMenuItem("Exit");
exitItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ev) {
System.exit(0);
}
});

JMenu headMenu = new JMenu("Heads");

outside of any method definition and there is no way to call that code.

Try this:

public class Main extends JFrame{

//initialize integer height/width values along with declaring
//Swing component variables
private final int W = 500,
H = 500;

private JMenu file, headMenu, bgMenu;
private JMenuBar menuBar;
private JMenuItem exitItem;

//constructor
public Main(){
setTitle("Move the Head");
setSize(W, H);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);

initializeElements();

}

//Initializes the elements, this part is missing from your code above.
public void initializeElements(){

menuBar = new JMenuBar();
file = new JMenu("File");
exitItem = new JMenuItem("Exit");

exitItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ev) {
System.exit(0);
}
});

headMenu = new JMenu("Heads");
bgMenu = new JMenu("Backgrounds");

}

public static void main( String[] args ) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
Main f = new Main();
f.setVisible(true);
}
});
}
}

The ActionListener of the JMenuItem is not working

Remove the getParent Method from PopUpMenu

public class PopUpMenu extends JPopupMenu {
private Container parent;

public PopUpMenu(MenuItem[] menuItems) {
super();
for (MenuItem item : menuItems) {
add(item);
}
}

public void setParent(Container parent) {
this.parent = parent;
parent.addMouseListener(new PopUpListener(this));
}

}

This method will override the getParent defined in java.awt.Component.getParent(). I guess this leads to the unexpected behavior.

EDIT

I'm overriding that method on purpose. But I still tried to remove it to see if that would fix the problem. Unfortunately, it did not.

You can override the method but you must ensure the Component.getParent method's contract.

The PopUpMenu is not a child of the container parent. I mean that if the PopUpMenu returns the container parent the container should also know that the PopUpMenu is it's child. E.g. Container.getCompnents() should contain the PopUpMenu. That's the contract.

But it will not help inyour situation since what don't really want to create a component parent/child relationship. You just want to hold a reference to some Object that you want to invoke some method.invoke(container);.

This example is based on your code with the fix I suggessted above. I've put everything in one compilation unit to provide a MVCE:

import java.awt.*;
import java.awt.event.*;
import java.lang.reflect.*;
import javax.swing.*;

public class Main {

public static void main(String[] args) {
JFrame frame = createFrame();

MenuItem menuItem1 = new MenuItem("getForeground", "Foreground Color");
MenuItem menuItem2 = new MenuItem("getBackground", "Background Color");
PopUpMenu popUpMenu = new PopUpMenu(new MenuItem[] { menuItem1, menuItem2 });
popUpMenu.setParent(frame);

frame.setVisible(true);
}

private static JFrame createFrame() {
JFrame frame = new JFrame();
frame.setSize(1000, 800);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
return frame;
}

}

class PopUpMenu extends JPopupMenu {

private Container parent;

public PopUpMenu(MenuItem[] menuItems) {
super();
for (MenuItem item : menuItems) {
add(item);
}
}

public Container getParentComponent() {
// another name because I don't want to override getParent()
// Try to rename this method to getParent to see
// that it will not work
return parent;
}

public void setParent(Container parent) {
this.parent = parent;
parent.addMouseListener(new PopUpListener(this));
}

}

class MenuItemListener extends IListener {

protected void action(ActionEvent event) {
Object source = event.getSource();
if (source instanceof MenuItem) {
MenuItem item = (MenuItem) source;
Container parent = item.getParent();
if (parent instanceof PopUpMenu) {
PopUpMenu menu = (PopUpMenu) parent;
Container container = menu.getParentComponent();
try {
String name = item.getMethodName();
Method method = container.getClass().getMethod(name);
Object invoke = method.invoke(container);
JOptionPane.showMessageDialog(container, invoke);
} catch (Exception e) {
}
}
}
}

}

abstract class IListener implements ActionListener {
private boolean keyboardSensitive;

public IListener() {
setKeyboardSensitive(false);
}

@Override
public void actionPerformed(ActionEvent event) {
if ((event.getModifiers() != 0) || isKeyboardSensitive()) {
action(event);
}
}

protected abstract void action(ActionEvent event);

public boolean isKeyboardSensitive() {
return keyboardSensitive;
}

public void setKeyboardSensitive(boolean keyboardSensitive) {
this.keyboardSensitive = keyboardSensitive;
}

}

class MenuItem extends JMenuItem {
private String methodName;

public MenuItem(String methodName, String text) {
super(text);
setMethodName(methodName);
setFocusable(true);
addActionListener(new MenuItemListener());
}

public String getMethodName() {
return methodName;
}

public void setMethodName(String methodName) {
this.methodName = methodName;
}

}

class PopUpListener extends MouseAdapter {
private PopUpMenu menu;

public PopUpListener(PopUpMenu menu) {
setMenu(menu);
}

@Override
public void mousePressed(MouseEvent event) {
if (event.isPopupTrigger()) {
menu.show(event.getComponent(), event.getX(), event.getY());
}

}

public void mouseReleased(MouseEvent event) {
if (event.isPopupTrigger()) {
menu.show(event.getComponent(), event.getX(), event.getY());
}
}

public PopUpMenu getMenu() {
return menu;
}

public void setMenu(PopUpMenu menu) {
this.menu = menu;
}

}

Here is a refactored version of the same logic that doesn't need a lot of specialized (extended) classes like PopUPMenu or MenuItem.

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.lang.reflect.*;
import java.text.MessageFormat;

import javax.swing.*;

public class Main {

public static void main(String[] args) {
JFrame frame = createFrame();

JMenuItem foregroundMenuItem = createMenuItem(frame, "getForeground", "Foreground Color");
JMenuItem backgroundMenuItem = createMenuItem(frame, "getBackground", "Background Color");

JPopupMenu popupMenu = new JPopupMenu();

popupMenu.add(foregroundMenuItem);
popupMenu.add(backgroundMenuItem);

PopUpListener popUpListener = new PopUpListener(popupMenu);
frame.addMouseListener(popUpListener);

frame.setVisible(true);
}

private static JMenuItem createMenuItem(Object invocationTarget, String methodName, String actionName) {
MethodInvocationAction methodInvocationAction = new MethodInvocationAction(invocationTarget, methodName);
methodInvocationAction.putValue(Action.NAME, actionName);

JMenuItem menuItem = new JMenuItem(methodInvocationAction);
return menuItem;
}

private static JFrame createFrame() {
JFrame frame = new JFrame();
frame.setSize(1000, 800);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
return frame;
}

}

class MethodInvocationAction extends AbstractAction {

private Object targetObj;
private Method targetMethod;

private boolean keyboardSensitive;

public MethodInvocationAction(Object targetObj, String methodName) {
this.targetObj = targetObj;
try {
targetMethod = targetObj.getClass().getMethod(methodName);
} catch (NoSuchMethodException | SecurityException e) {
String msg = MessageFormat.format("{0} does not have a method named {1}", targetObj, methodName);
throw new RuntimeException(msg, e);
}
}

public boolean isKeyboardSensitive() {
return keyboardSensitive;
}

public void setKeyboardSensitive(boolean keyboardSensitive) {
this.keyboardSensitive = keyboardSensitive;
}

@Override
public void actionPerformed(ActionEvent event) {
if ((event.getModifiers() != 0) || isKeyboardSensitive()) {
performAction(event);
}
}

public void performAction(ActionEvent e) {
try {
Object invoke = targetMethod.invoke(targetObj);
JOptionPane.showMessageDialog(null, invoke);
} catch (Exception exception) {
showException(exception);
}
}

private void showException(Exception e1) {
StringWriter exceptionStackTraceWriter = new StringWriter();
e1.printStackTrace(new PrintWriter(exceptionStackTraceWriter));
String exceptionStackTrace = exceptionStackTraceWriter.toString();

JTextArea exceptionStackTraceTextComponent = new JTextArea();
exceptionStackTraceTextComponent.setText(exceptionStackTrace);

JScrollPane scrollPane = new JScrollPane(exceptionStackTraceTextComponent);
scrollPane.setPreferredSize(new Dimension(800, 600));

JOptionPane.showMessageDialog(null, scrollPane, e1.getLocalizedMessage(), JOptionPane.ERROR_MESSAGE);
}
}

class PopUpListener extends MouseAdapter {
private JPopupMenu menu;

public PopUpListener(JPopupMenu menu) {
this.menu = menu;
}

public void mousePressed(MouseEvent event) {
handlePopupEvent(event);
}

public void mouseReleased(MouseEvent event) {
handlePopupEvent(event);
}

private void handlePopupEvent(MouseEvent event){
if (event.isPopupTrigger()) {
menu.show(event.getComponent(), event.getX(), event.getY());
}
}

}

Update JMenu display names

If I understand what exactly you want (a snapshot could have been useful), then you should use menu.setText("player1")

setName(string) is not for display, see here.

How to create JButtons using JMenuItem and ActionListener

Implement a method to add a JButton in the ProgramDisplay class, e.g.

 void addButton(String name, String employeeID, String rateOfPay, String hoursWorked) {
add(new JButton(name + ":" + employeeID + ", " + rateOfPay + " - " + hoursWorked); }

pass the ProgramDisplay instance as final parameter to the NewListener, e. g.

private class NewListener extends JFrame implements ActionListener {
final ProgramDisplay pd;
NewListener(ProgramDisplay pd) {
this.pd = pd;
}
.....

and call the addButton method from within your ActionPerformed method:

    Apply.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
name = nameField.getText();
employeeID = IDField.getText();
rateOfPay = payRateField.getText();
hoursWorked = hoursField.getText();
setVisible(false);
NewListener.this.pd.addButton(name, employeeID, rateOfPay, hoursWorked);
}
});

How to change a menuItem tool tip from its own action listener?

not sure what happened, there must be another issue in your code, but everything could be .... only speculations, my SSCCE

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

public class ActionExample {

private boolean testCondition = false;
private JMenuItem DeleteTask = new JMenuItem("Delete Task");

public ActionExample() {
Action sample = new SampleAction();
DeleteTask.setMnemonic(KeyEvent.VK_D);
DeleteTask.setToolTipText("Delete a Task");
DeleteTask.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent event) {
if (testCondition) {
testCondition = false;
DeleteTask.setToolTipText("Changed Tool Tip");
} else {
testCondition = true;
DeleteTask.setToolTipText("Delete a Task");
}
}
});
JMenu menu = new JMenu("Menu");
menu.setMnemonic(KeyEvent.VK_M);
menu.add(sample);
menu.add(DeleteTask);
menu.addMenuListener(new SampleMenuListener());
JToolBar tb = new JToolBar();
tb.add(sample);
JTextField field = new JTextField(10);
field.setAction(sample);
JFrame f = new JFrame("ActionExample");
JMenuBar mb = new JMenuBar();
mb.add(menu);
f.setJMenuBar(mb);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(tb, BorderLayout.NORTH);
f.getContentPane().add(field, BorderLayout.SOUTH);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {

@Override
public void run() {
ActionExample actionExample = new ActionExample();
}
});
}
}

class SampleMenuListener implements MenuListener {

@Override
public void menuSelected(MenuEvent e) {
System.out.println("menuSelected");
}

@Override
public void menuDeselected(MenuEvent e) {
System.out.println("menuDeselected");
}

@Override
public void menuCanceled(MenuEvent e) {
System.out.println("menuCanceled");
}
}

class SampleAction extends AbstractAction {

private static final long serialVersionUID = 1L;

public SampleAction() {
super("Sample");
putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke("alt S"));
putValue(MNEMONIC_KEY, new Integer(KeyEvent.VK_S));
putValue(SHORT_DESCRIPTION, "Just a sample action");
}

@Override
public void actionPerformed(ActionEvent evt) {
System.out.println("sample...");
}
}


Related Topics



Leave a reply



Submit