Using ActionListener in separate class - java

I'm trying to make a separate class for an action listener but I'm not sure how to add the action listener to the menu item. I've been trying a few different things but none of them are letting the message dialog appear. I have the action listener in a separate class and the menu item in a separate class and I'm trying to get them to work together.
public class HangmanView {
Listener listener = new Listener();
public JMenuItem getMenuItem() {
JMenuItem menuItem = new JMenuItem("Developer", KeyEvent.VK_T);
menuItem.addActionListener(new Listener());
return menuItem;
}
public JMenuBar menuBar() {
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("File");
menuBar.add(menu);
menu.add(getMenuItem());
return menuBar;
}
Another Class:
public class Listener {
JFrame dialogFrame = new JFrame();
public JFrame menuItemListener() {
HangmanView hangmanView = new HangmanView();
hangmanView.getMenuItem().addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {// right click key
JOptionPane.showMessageDialog(dialogFrame, "Developer: Joe"
, "Developer",
JOptionPane.INFORMATION_MESSAGE);
}// end actionPerformed method
});
return dialogFrame;
}
}

You seem to be suffering from a lot of confusion as to classes, interfaces, etc so it's actually hard to know where to begin!
First up your Listener class needs to implement ActionListener.
Then you need to add it inside your HangmanView class the same way you already are:
public class Listener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {// right click key
JOptionPane.showMessageDialog(dialogFrame, "Developer: Joe"
, "Developer",
JOptionPane.INFORMATION_MESSAGE);
}// end actionPerformed method
});
And that's it, you are done...

Related

Dynamically create Java Swing submenus

I know how to create Java Swing submenus using JMenu. When we hover the mouse over a JMenu object, it displays a JPopupMenu showing the submenu items, like this:
Submenu using JMenu
My problem is that in my application, determining which menu elements will have a submenu is expensive. I don't want to have to determine in advance whether a particular menu element should be a JMenu or just a JMenuItem. I want to make every element a JMenuItem and display a submenu for it only if the user requests it by, e.g., hovering the mouse over a menu item. Like this:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Menu2 extends JFrame
{
public Menu2()
{
super("Menu2");
JMenuBar menuBar = new JMenuBar();
setJMenuBar(menuBar);
JMenu mItems = new JMenu("Items");
menuBar.add(mItems);
mItems.add(new JMI("A"));
mItems.add(new JMI("B"));
mItems.add(new JMI("C"));
JLabel stuff = new JLabel("Other stuff");
stuff.setPreferredSize(new Dimension(200,200));
getContentPane().add(stuff);
pack();
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}
private class JMI extends JMenuItem
implements MouseListener
{
public JPopupMenu childrenPopup = null;
public JMI(String label)
{
super(label);
addMouseListener(this);
}
// MouseListener
public void mouseClicked(MouseEvent ev) {}
public void mouseEntered(MouseEvent ev)
{
// Show a submenu for item "B" only.
// In real life we'd want a Timer to delay showing the submenu
// until we are sure the user is hovering the mouse.
// For simplicity I've omitted it.
if (getText().equals("B")) {
if (childrenPopup == null) {
childrenPopup = new JPopupMenu();
// Expensive processing to determine submenu elements...
childrenPopup.add("D");
childrenPopup.add("E");
}
// Display the submenu
childrenPopup.show(this,getWidth(),0);
}
}
public void mouseExited(MouseEvent ev) {}
public void mousePressed(MouseEvent ev) {}
public void mouseReleased(MouseEvent ev) {}
}
public static void main(String[] args)
throws Exception
{
new Menu2().setVisible(true);
}
}
The only problem is that when my manually created JPopupMenu is displayed, the rest of the menu gets closed. The resulting display does not look like the earlier one, but rather like this:
Submenu displayed manually
Note that I did not click on the "B" menu item, only moved the mouse into it. The menu did not close due to a mouse click.
How can I do what JMenu does -- display a JPopupMenu without closing the rest of the menu?
The approach I've tentatively decided upon is to extend JMenu instead
of JMenuItem and use this type for all of my menu elements. But I
won't populate these elements (the expensive step) until the user
requests it by hovering the mouse.
To avoid cluttering up the menu with the arrow icons that JMenu
normally displays (potentially misleading in this case), I use a technique described by Stackoverflow's MadProgrammer to instantiate an arrowless JMenu in a static factory method. Since I
restore the arrow icon property after creating the arrowless JMenu,
normal JMenu instances created elsewhere will still show the arrow.
Some menu elements will need to execute actions and close the menu,
like a JMenuItem does. A JMenu doesn't normally respond to mouse
clicks, so I execute click actions in my MouseListener.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class Menu3 extends JFrame
{
public Menu3()
{
super("Menu3");
JMenuBar menuBar = new JMenuBar();
setJMenuBar(menuBar);
JMenu mItems = new JMenu("Items");
menuBar.add(mItems);
mItems.add(JM.create("A"));
mItems.add(JM.create("B"));
mItems.add(JM.create("C"));
JLabel stuff = new JLabel("Other stuff");
stuff.setPreferredSize(new Dimension(200,200));
getContentPane().add(stuff);
pack();
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}
private static class JM extends JMenu
implements MouseListener
{
private static final String ARROW_ICON_KEY = "Menu.arrowIcon";
private boolean populated = false; // Submenu already populated?
protected JM(String label)
{
super(label);
addMouseListener(this);
}
// This static factory method returns a JM without an arrow icon.
public static JM create(String label)
{
UIDefaults uiDefaults = UIManager.getLookAndFeelDefaults();
Object savedArrowIcon = uiDefaults.get(ARROW_ICON_KEY);
uiDefaults.put(ARROW_ICON_KEY,null);
JM newJM = new JM(label);
uiDefaults.put(ARROW_ICON_KEY,savedArrowIcon);
return newJM;
}
// MouseListener
public void mouseClicked(MouseEvent ev)
{
// Since some menu elements need to execute actions and a JMenu
// doesn't normally respond to mouse clicks, we execute click
// actions here. In real life we'll probably fire some event
// for which an EventListener can listen. For illustrative
// purposes we'll just write out a trace message.
System.err.println("Executing "+getText());
MenuSelectionManager.defaultManager().clearSelectedPath();
}
public void mouseEntered(MouseEvent ev)
{
// In real life we'd want a Timer to delay showing the submenu
// until we are sure the user is "hovering" the mouse.
// For simplicity I've omitted it.
// Populate this submenu only once
if (!populated) {
// For purposes of example, show a submenu for item "B" only.
if (getText().equals("B")) {
// Expensive processing...
add(create("D"));
add(create("E"));
}
populated = true;
}
}
public void mouseExited(MouseEvent ev) {}
public void mousePressed(MouseEvent ev) {}
public void mouseReleased(MouseEvent ev) {}
}
public static void main(String[] args)
throws Exception
{
new Menu3().setVisible(true);
}
}
The result works the way I want:
Menu3 with open menu

call actionperformed method on clicking jmenu

can i call actionperformed method with jmenu using swing
i am using the following code
JMenu menu1= new JMenu("File");
MenuBar mb= new MenuBar();
mb.add(menu1);
set JmenuBar(mb)
menu1.addActionListener(this);
public void actionPerformed(ActionEvent ae)
{
JOptionPane.showMessaageDialog(null,"menu clicked");
// but its not working
}
thanks in Advance
The action a JMenu is designed to perform is to open a popup with JMenuItems, it doesn't support doing anything else (and even if it did, it would confuse your users). Custom actions are supposed to be handled by JMenuItems in the popup. Install them with something like:
JMenu menu ..
Action myAction = new AbstractAction("Do XY") {
public void actionPerformed(..) {
// implement doing XY
}
};
menu.add(myAction);

JMenuItem Constructor Not Accepting Action

JMenuItem has the following constructor: (Source: GrepCode)
public JMenuItem(Action a) {
this();
setAction(a);
}
However, when my code has
import javax.swing.*;
import java.awt.event.ActionEvent;
public class ActionTest extends JApplet {
private final JFrame frame = new JFrame("Title");
private final JMenuBar menuBar = new JMenuBar();
private final JMenu fileMenu = new JMenu("File");
protected Action someAction;
private JMenuItem someButton = new JMenuItem(someAction);
public ActionTest() {}
#Override
public final void init() {
frame.setJMenuBar(menuBar);
menuBar.add(fileMenu);
fileMenu.add(someButton);
someButton.setText("Button");
someAction = new AbstractAction("Title") {
public void actionPerformed(ActionEvent event) {
//do stuff
}
};
frame.setVisible(true);
}
public static void main(String[] args) {
JApplet applet = new ActionTest();
applet.init();
}
}
and I press the JMenuItem, actionPerformed() is not even called.
Is this a bug, or is my approach completely wrong?
After doing more research, I find that this is the method that it eventually boils down to. It seems to implement a shallow copy, which should simply point to the same memory block that I gave it in the constructor.
The same thing should be occurring when I add the file menu to the menu bar. When the file menu is added, it references the memory block. Whatever is inside that memory block is what is displayed. Then, I add the menu item and it appears in the JMenu.
Somehow it is different when I'm dealing with Actions or constructors. Could somebody explain the difference?
It seems like from what you've posted that you haven't defined your Action when you initialize the JMenuItem. Therefore, because you are passing in null, no action is being triggered
someButton is initialized before someAction, so you are passing null to the JMenuItem. Initialize someButton after you have created someAction and everything will go fine.

Can't Add JMenuItem to JMenu in JPopupMenu

I've got a new UI I'm working on implementing in Java and I'm having trouble implementing a JPopupMenu containing a JMenu (as well as several JMenuItems), which itself contains several JMenuItems. The JPopupMenu appears where I click the RMB, and it looks good, but the "Connect" JMenu doesn't seem to have any children when I mouse-over, despite my best efforts to .add() them.
Having looked at several examples online, I haven't seen any that specifically implement a listener for mouseEntered() to roll out the sub-items. I'm of a mind that I'm messing something up in my menu initialization method.
I've attached the pertinent code for your perusal.
//Elsewhere...
private JPopupMenu _clickMenu;
//End Elsehwere...
private void initializeMenu()
{
_clickMenu = new JPopupMenu();
_clickMenu.setVisible(false);
_clickMenu.add(generateConnectionMenu());
JMenuItem menuItem;
menuItem = new JMenuItem("Configure");
addMenuItemListeners(menuItem);
_clickMenu.add(menuItem);
menuItem = new JMenuItem("Status");
addMenuItemListeners(menuItem);
_clickMenu.add(menuItem);
}
private JMenu generateConnectionMenu()
{
JMenu menu = new JMenu("Connect");
List<Port> portList = _database.getAllPortsInCard(_cardId);
for(int i = 0; i < portList.size(); i++)
{
menu.add(new JMenuItem(portList.get(i).getName()));
}
return menu;
}
The code is certainly not the prettiest, but go easy on me as it's been altered too many times today as time permitted while I tried to figure out why this wasn't working. I'm thinking it may be a question of scope, but I've tried a few different code configurations to no avail. Feel free to ask any followup questions or smack me for an obvious oversight (it's happened before...). Thanks all!
Edit:
Chalk this one up to a lack of experience with Java and Swing... I was manually positioning and making the JPopupMenu visible instead of using the JComponent.setComponentPopupMenu(menu) method. After doing this for the card module in the above image (itself a JButton), the submenu displays correctly. A different, functional version of the initialization code is included below.
private void initializeMenu()
{
_cardMenu = new JPopupMenu();
JMenu menu = new JMenu("Connect");
JMenuItem menuItem;
menuItem = new JMenuItem("1");
menu.add(menuItem);
menuItem = new JMenuItem("2");
menu.add(menuItem);
_cardMenu.add(menu);
_cardMenu.add(new JMenuItem("Configure"));
_cardMenu.add(new JMenuItem("Status"));
_mainButton.setComponentPopupMenu(_cardMenu); //Important, apparently!
}
So, lesson learned. Thanks for the help guys!
This is common Bug or Swing property that in one moment can be visible only one Lightweight popup window, same issue is e.g. with popup from JComboBox added into JPopupMenu,
change Lightweight property to the Heavyweight
better would be
use un_decorated JDialog or JOptionPane with JComponents
EDIT #trashgod
everything works as I excepted, all JMenus, JMenuItems are visible and repeatly fired correct evets
code
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class ContextMenu implements ActionListener, MenuListener, MenuKeyListener {
private JTextArea textArea = new JTextArea();
public ContextMenu() {
final JPopupMenu contextMenu = new JPopupMenu("Edit");
JMenu menu = new JMenu("Sub Menu");
menu.add(makeMenuItem("Sub Menu Save"));
menu.add(makeMenuItem("Sub Menu Save As"));
menu.add(makeMenuItem("Sub Menu Close"));
menu.addMenuListener(this);
JMenu menu1 = new JMenu("Sub Menu");
menu1.add(makeMenuItem("Deepest Sub Menu Save"));
menu1.add(makeMenuItem("Deepest Sub Menu Save As"));
menu1.add(makeMenuItem("Deepest Sub Menu Close"));
menu.add(menu1);
menu1.addMenuListener(this);
contextMenu.add(menu);
contextMenu.add(makeMenuItem("Plain Save"));
contextMenu.add(makeMenuItem("Plain Save As"));
contextMenu.add(makeMenuItem("Plain Close"));
contextMenu.addMenuKeyListener(this);
JFrame frame = new JFrame();
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
frame.add(panel);
panel.setComponentPopupMenu(contextMenu);
textArea.setInheritsPopupMenu(true);
panel.add(BorderLayout.CENTER, textArea);
JTextField textField = new JTextField();
textField.setInheritsPopupMenu(true);
panel.add(BorderLayout.SOUTH, textField);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 200);
frame.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
textArea.append(e.getActionCommand() + "\n");
}
private JMenuItem makeMenuItem(String label) {
JMenuItem item = new JMenuItem(label);
item.addActionListener(this);
return item;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
ContextMenu contextMenu = new ContextMenu();
}
});
}
public void menuSelected(MenuEvent e) {
textArea.append("menuSelected" + "\n");
}
public void menuDeselected(MenuEvent e) {
textArea.append("menuDeselected" + "\n");
}
public void menuCanceled(MenuEvent e) {
textArea.append("menuCanceled" + "\n");
}
public void menuKeyTyped(MenuKeyEvent e) {
textArea.append("menuKeyTyped" + "\n");
}
public void menuKeyPressed(MenuKeyEvent e) {
textArea.append("menuKeyPressed" + "\n");
}
public void menuKeyReleased(MenuKeyEvent e) {
textArea.append("menuKeyReleased" + "\n");
}
}
I don't see an obvious problem in the code shown, although #mKorbel's point may apply. For reference, this ControlPanel adds a subMenu with several items.

Add functionality to a menu button in java

I am new to Java and I was wondering how to add functionality to menu item?
What I would like it to do, is to set two values to 0.
This is the code I have currently:
JMenuItem clear = new JMenuItem("Clear");
Options.add(clear);
This example is from the book "Java
Foundation Classes in a Nutshell".
Written by David Flanagan. Copyright
(c) 1999 by O'Reilly & Associates.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MenuDemo {
public static void main(String[] args) {
// Create a window for this demo
JFrame frame = new JFrame("Menu Demo");
JPanel panel = new JPanel();
frame.getContentPane().add(panel, "Center");
// Create an action listener for the menu items we will create
// The MenuItemActionListener class is defined below
ActionListener listener = new MenuItemActionListener(panel);
// Create some menu panes, and fill them with menu items
// The menuItem() method is important. It is defined below.
JMenu file = new JMenu("File");
file.setMnemonic('F');
file.add(menuItem("New", listener, "new", 'N', KeyEvent.VK_N));
file.add(menuItem("Open...", listener, "open", 'O', KeyEvent.VK_O));
file.add(menuItem("Save", listener, "save", 'S', KeyEvent.VK_S));
file.add(menuItem("Save As...", listener, "saveas", 'A', KeyEvent.VK_A));
JMenu edit = new JMenu("Edit");
edit.setMnemonic('E');
edit.add(menuItem("Cut", listener, "cut", 0, KeyEvent.VK_X));
edit.add(menuItem("Copy", listener, "copy", 'C', KeyEvent.VK_C));
edit.add(menuItem("Paste", listener, "paste", 0, KeyEvent.VK_V));
// Create a menubar and add these panes to it.
JMenuBar menubar = new JMenuBar();
menubar.add(file);
menubar.add(edit);
// Add menubar to the main window. Note special method to add menubars
frame.setJMenuBar(menubar);
// Now create a popup menu and add the some stuff to it
final JPopupMenu popup = new JPopupMenu();
popup.add(menuItem("Open...", listener, "open", 0, 0));
popup.addSeparator(); // Add a separator between items
JMenu colors = new JMenu("Colors"); // Create a submenu
popup.add(colors); // and add it to the popup menu
// Now fill the submenu with mutually-exclusive radio buttons
ButtonGroup colorgroup = new ButtonGroup();
colors.add(radioItem("Red", listener, "color(red)", colorgroup));
colors.add(radioItem("Green", listener, "color(green)", colorgroup));
colors.add(radioItem("Blue", listener, "color(blue)", colorgroup));
// Arrange to display the popup menu when the user clicks in the window
panel.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
// Check whether this is the right type of event to pop up a popup
// menu on this platform. Usually checks for right button down.
if (e.isPopupTrigger())
popup.show((Component)e.getSource(), e.getX(), e.getY());
}
});
// Finally, make our main window appear
frame.setSize(450, 300);
frame.setVisible(true);
}
// A convenience method for creating menu items.
public static JMenuItem menuItem(String label,
ActionListener listener, String command,
int mnemonic, int acceleratorKey) {
JMenuItem item = new JMenuItem(label);
item.addActionListener(listener);
item.setActionCommand(command);
if (mnemonic != 0) item.setMnemonic((char) mnemonic);
if (acceleratorKey != 0)
item.setAccelerator(KeyStroke.getKeyStroke(acceleratorKey,
java.awt.Event.CTRL_MASK));
return item;
}
// A convenience method for creating radio button menu items.
public static JMenuItem radioItem(String label, ActionListener listener,
String command, ButtonGroup mutExGroup) {
JMenuItem item = new JRadioButtonMenuItem(label);
item.addActionListener(listener);
item.setActionCommand(command);
mutExGroup.add(item);
return item;
}
// A event listener class used with the menu items created above.
// For this demo, it just displays a dialog box when an item is selected.
public static class MenuItemActionListener implements ActionListener {
Component parent;
public MenuItemActionListener(Component parent) { this.parent = parent; }
public void actionPerformed(ActionEvent e) {
JMenuItem item = (JMenuItem) e.getSource();
String cmd = item.getActionCommand();
JOptionPane.showMessageDialog(parent, cmd + " was selected.");
}
}
}
Hope it help you get started
You will need to add an ActionListener. This is an interface which must implement a method called actionPerformed.
E.g
clear.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent actionEvent) {
// Clear two values.
}
});`
This will add an anonymous ActionListener that is invoked once the JMenuItem is clicked.
Hope that helps.

Categories