how to add a action listner to jmenuitem - java

My menuitem are being added thorugh database .
i have to perform action such as opening the new jframe , if a user select a particular menuitem.
Here the menu dimension is add to the Menubar , and under which various menuitem are being added such as Period , Entity, which are being fetch from database.
Now i want to open a new jframe on the click of Period menuitem .
public void MenuExp(){
JMenu DimensionMenu = new JMenu("Dimension");
JMenu editMenu = new JMenu("Help");
jMenuBar1.add(DimensionMenu);
jMenuBar1.add(editMenu);
//JMenuItem newAction = new JMenuItem("Account");
//fileMenu.add(newAction);
//JMenuItem newPeriod = new JMenuItem("Period");
//fileMenu.add(newPeriod);
try{
Class.forName("oracle.jdbc.OracleDriver");
Connection comm = (Connection)DriverManager.getConnection("jdbc:oracle:thin:#192.168.100.25:1521:orcl","SYSTEM","Admin123");
Statement st = comm.createStatement();
String Query = "select OBJECT_NAME from RAHUL_APP1.HSP_OBJECT where OBJECT_TYPE = 2 AND OBJECT_ID <> 30" ;
//and User_Name ='" + jTextField1.getText()+"'";
ResultSet rs = st.executeQuery(Query);
while(rs.next()){
JMenuItem newAction = new JMenuItem(rs.getString(1));
DimensionMenu.add(newAction);
rs.close();
st.close();
comm.close();
newAction.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0){
System.out.println("You have clicked on the Account");
}
});
}
} catch(Exception e){
JOptionPane.showMessageDialog(this,e);
}
}

You need to do some parametrization of the frame or have for example frame class stored also in DB and initialize it using reflexion...
Update:
Implementation can be like this:
package betlista.so.swing.menuitemdialogsfromdb;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
public class MainFrame extends JFrame {
public MainFrame() {
super("Frame");
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
add(createMenu());
pack();
}
private JMenuBar createMenu() {
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("Open");
menu.add(new DialogCreatingMenuItem("Dialog 1", "betlista.so.swing.menuitemdialogsfromdb.MainFrame$MyDialog1"));
menu.add(new DialogCreatingMenuItem("Dialog 2", "betlista.so.swing.menuitemdialogsfromdb.MainFrame$MyDialog2"));
menuBar.add(menu);
return menuBar;
}
class DialogCreatingMenuItem extends JMenuItem implements ActionListener {
String className;
public DialogCreatingMenuItem(String text, String className) throws HeadlessException {
super(text);
this.className = className;
addActionListener(this);
}
#Override
public void actionPerformed(ActionEvent ae) {
try {
Class<JDialog> clazz = (Class<JDialog>)Class.forName(this.className);
JDialog dialog = clazz.newInstance();
dialog.setVisible(true);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
public static class MyDialog1 extends JDialog {
public MyDialog1() {
setTitle("Dialog 1");
add(new JLabel("Dialog 1"));
pack();
}
}
public static class MyDialog2 extends JDialog {
public MyDialog2() {
setTitle("Dialog 2");
add(new JLabel("Dialog 2"));
pack();
}
}
public static void main(String[] args) {
new MainFrame().setVisible(true);
}
}
where Strings in
menu.add(new DialogCreatingMenuItem("Dialog 1", "betlista.so.swing.menuitemdialogsfromdb.MainFrame$MyDialog1"));
menu.add(new DialogCreatingMenuItem("Dialog 2", "betlista.so.swing.menuitemdialogsfromdb.MainFrame$MyDialog2"));
are retrieved from database...

Here is a sample code:
menuItem1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
...
}
});
Remember the steps to creating a menu:
1. Create a MenuBar and add to the panel
2. Create a Menu and add to MenuBar
3. Create a MenuItem and add to Menu
Then add the listener to the MenuItem
Edit: if you use it outside the try statement it should work

Now i want to open a new jframe on the click of Period menuitem
Of course you have to add an ActionListener to your menu to do that, but the real question is How do you determine the right listener to each menu item? Since you fetch your menu items from database then it's not that easy as it looks like.
Note: see The Use of Multiple JFrames, Good/Bad Practice?
Option 1 (kind of dirty)
As I've said, you could store an action command and set it back to the menu item just like you set the menu's name:
while(rs.next()) {
String menuName = rs.getString("menuname");
String actionCommand = rs.getString("actioncommand");
JMenuItem newAction = new JMenuItem(menuName);
newAction.setActionCommand(actionCommand);
DimensionMenu.add(newAction);
...
}
Then you can have a listener that make use of ActionEvent#getActionCommand() to decide the right action to perform and attach this listener to all your menu items:
class MenuActionListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent evt) {
String actionCommand = evt.getActionCommand();
switch (actionCommand) {
case "OpenNewDialog": openNewDialog(); break;
...
}
}
private void openNewDialog() {
// implementation here
}
}
Then:
ActionListener listener = new MenuActionListener();
while(rs.next()) {
String menuName = rs.getString("menuname");
String actionCommand = rs.getString("actioncommand");
JMenuItem newAction = new JMenuItem(menuName);
newAction.setActionCommand(actionCommand);
newAction.addActionListener(listener);
DimensionMenu.add(newAction);
...
}
Option 2
Implement Factory method pattern to create a specific ActionListener or Action based on menu's action command:
class ActionListenerFactory {
public static Action createAction(final String actionCommand) {
switch (actionCommand) {
case "OpenNewDialog": return openNewDialogAction(); break;
...
}
}
private Action openNewDialogAction() {
Action action = new AbstractAction() {
#Override
public void actionPerformed(ActionEvent evt) {
// open new dialog here
}
};
return action;
}
}
Then:
while(rs.next()) {
String menuName = rs.getString("menuname");
String actionCommand = rs.getString("actioncommand");
JMenuItem newAction = new JMenuItem(menuName);
newAction.setActionCommand(actionCommand);
newAction.addActionListener(ActionListenerFactory.createAction(actionCommand));
DimensionMenu.add(newAction);
...
}
See also:
How to Use Actions tutorial.
Concurrency in Swing lesson.
Worker threads and SwingWorker to do database calls in a background thread and create/update Swing component in the Event Dispatch Thread

Related

How to use a boolean outside the scope of a key listener

I created a shop cart login JFrame and I added a "shopkeeperToggle" so that when it's pressed the user logs in to the shopkeeper's JFrame and otherwise to a shopper's jframe. the problem is I don't know how to implement it, I tried to set a boolean "pressed" to false whenever the key is released in the "shopkeeperToggle" key listener, and apparently I'm unable to use the value of pressed inside the sign-in button.
Here's the code for the toggle:
shopkeeperToggle = new JToggleButton("Shopkeeper");
shopkeeperToggle.addKeyListener(new KeyAdapter() {
#Override
public void keyReleased(KeyEvent e) {
pressed = false;
}
});
and this is what I'm trying to do in the sign in button:
signinButton = new JButton("Sign in ");
signinButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3308/shoppingCart","root","");
// select the users that have the inputted credentials from the database
String sql = "SELECT * FROM users WHERE userUsername = ? AND userEmail =?AND userPassword = ? ";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1,usernamelogin.getText());
ps.setString(2, emaillogin.getText());
ps.setString(3,passwordlogin.getText());
ResultSet rs = ps.executeQuery();
// if query executed and
if (rs.next()) {
// if login succ show window log succ, and go to home shopping page
JOptionPane.showMessageDialog(null,"Login successful! :)");
/////////////////this is where I fail////////////////////
if (pressed) {
OwnerHomePage ownerhome = new OwnerHomePage();
ownerhome.setVisible(true);
setVisible(false);
} else {
UserHomePage home = new UserHomePage();
home.setVisible(true);
setVisible(false);
}
} else {
JOptionPane.showMessageDialog(null,"Wrong Username or Email or Password :(");
}
} catch (Exception e1) {
JOptionPane.showMessageDialog(null,e1);
}
}
}
This may offer some help in fixing your issue. It is a fully compilable demo. The following changes were made.
Used Actions in lieu of KeyListener. A little more involved to setup but they can be configured to monitor only certain keys.
Used a JButton in lieu of a JToggleButton. No specific reason and can be changed.
Created separate inner classes for the listeners. Tends to reduce clutter and is usually more readable.
Changed the name of the button depending on the mode.
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.AbstractAction;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
public class ActionMapAndButtons {
JFrame frame = new JFrame("Demo");
public static void main(String[] args) {
SwingUtilities
.invokeLater(() -> new ActionMapAndButtons().start());
}
public void start() {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
MyClass cls = new MyClass();
frame.add(cls);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
class MyClass extends JPanel {
JButton button = new JButton("Shopper Sign in");
boolean pause = false;
public MyClass() {
setPreferredSize(new Dimension(300, 300));
button.addActionListener(new ButtonListener());
add(button);
InputMap map = getInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
for (int i = 0; i < 256; i++) {
map.put(KeyStroke.getKeyStroke((char)i), "anyKey");
}
getActionMap().put("anyKey", new MyAction());
setFocusable(true);
}
private class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent ae) {
Object obj = ae.getSource();
if (obj instanceof JButton) {
JButton b = (JButton) obj;
pause = !pause;
if (pause) {
b.setText("Shopkeeper Sign in");
} else {
b.setText("Shopper Sign in");
}
}
}
}
private class MyAction extends AbstractAction {
public void actionPerformed(ActionEvent ae) {
String cmd = ae.getActionCommand();
if (pause) {
System.out.println("Shopkeeper - " + cmd);
} else {
System.out.println("Shopper - " + cmd);
}
}
}
}
Inner (or nested) classes and action maps are covered in The Java Tutorials
You can define pressed as a static value;
class c {
static boolean pressed = true;
...
}
and you can access anywhere;
c.pressed; //will return true if you don't change

Update JMenu in Swing via revalidate() and repaint() not working

In the process of logging in, if the administrator is being logged in I want to enable JMenuItem called Admin. When program starts, its visibility is set to false. So when a user clicks Log In I run JMenu again and trying to recreate it just with Admin now set on true. Here's the code of my initialize method that's being run if it detects the user is an admin. The method is inside the JMenuBar class that the application uses.
public void initialize() {
file = new JMenu("File");
file.setName("File Menu");
file.addMouseListener(this);
help = new JMenu("Help");
help.setName("Help Menu");
help.addMouseListener(this);
login = new JMenu("Login");
login.setName("Login Menu");
login.addMouseListener(this);
language = new JMenu("Language");
language.setName("Language Menu");
language.addMouseListener(this);
admin = new JMenu("Admin");
admin.setName("Admin Menu");
if(LoginDialog.AdminLoggedIn) {
admin.setEnabled(true);
} else
admin.setEnabled(false);
admin.addMouseListener(this);
add(file);
add(login);
add(help);
add(language);
add(admin);
this.revalidate();
this.repaint();
}
Thanks.
I would suggest not re-creating your JMenu but rather modifying it, depending on the Administrator state of your program. You could give the program a Privileges enum, one with REGULAR and ADMINISTRATOR (and possibly other) fields, something like:
public enum Privileges {
REGULAR("Regular"), ADMINISTRATOR("Administrator");
private String text;
private Privileges(String text) {
this.text = text;
}
#Override
public String toString() {
return text;
}
}
And then change the state of your JMenu depending on the program's Privileges state. Also side note: don't use a MouseListener on your menus since these do not respect the enabled/disabled state of your menus / menuitems / buttons. For example, here is my small MVCE example, one that uses a Model-View-Controller structure (of sorts):
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.*;
import javax.swing.event.SwingPropertyChangeSupport;
#SuppressWarnings("serial")
public class MenuChanger extends JPanel {
private CreateMenu createMenu = new CreateMenu();
private MenuChngModel model = new MenuChngModel();
private ButtonGroup buttonGroup = new ButtonGroup();
public MenuChanger() {
setPreferredSize(new Dimension(400, 300));
model.addPropertyChangeListener(MenuChngModel.PRIVILEGES, new ModelListener());
JPanel privilegesPanel = new JPanel();
privilegesPanel.setLayout(new GridLayout(0, 1, 5, 5));
privilegesPanel.setBorder(BorderFactory.createTitledBorder("Privileges"));
for (final Privileges privileges : Privileges.values()) {
JRadioButton rBtn = new JRadioButton(privileges.toString());
if (privileges == Privileges.REGULAR) {
rBtn.setSelected(true);
}
rBtn.addActionListener(e -> {
createMenu.setPrivileges(privileges);
});
buttonGroup.add(rBtn);
privilegesPanel.add(rBtn);
}
add(privilegesPanel);
}
public CreateMenu getCreateMenu() {
return createMenu;
}
private class ModelListener implements PropertyChangeListener {
#Override
public void propertyChange(PropertyChangeEvent evt) {
Privileges privileges = (Privileges) evt.getNewValue();
createMenu.setPrivileges(privileges);
}
}
private static void createAndShowGui() {
MenuChanger mainPanel = new MenuChanger();
JFrame frame = new JFrame("MenuChanger");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.setJMenuBar(mainPanel.getCreateMenu().getMenubar());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
class MenuChngModel {
public static final String PRIVILEGES = "privileges";
private SwingPropertyChangeSupport pcSupport = new SwingPropertyChangeSupport(this);
private Privileges privileges = Privileges.REGULAR;
public Privileges getPrivileges() {
return privileges;
}
public void setPrivileges(Privileges privileges) {
Privileges oldValue = this.privileges;
Privileges newValue = privileges;
this.privileges = privileges;
pcSupport.firePropertyChange(PRIVILEGES, oldValue, newValue);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
pcSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
pcSupport.removePropertyChangeListener(listener);
}
public void addPropertyChangeListener(String name, PropertyChangeListener listener) {
pcSupport.addPropertyChangeListener(name, listener);
}
public void removePropertyChangeListener(String name, PropertyChangeListener listener) {
pcSupport.removePropertyChangeListener(name, listener);
}
}
enum Privileges {
REGULAR("Regular"), ADMINISTRATOR("Administrator");
private String text;
private Privileges(String text) {
this.text = text;
}
#Override
public String toString() {
return text;
}
}
class CreateMenu {
private JMenuBar menubar = new JMenuBar();
private JMenu fileMenu = new JMenu("File");
private JMenu adminMenu = new JMenu("Administrator");
private JMenuItem fileMenuItem = new JMenuItem("File Menu Item");
private JMenuItem adminFileMenuItem = new JMenuItem("Admin File Menu Item");
public CreateMenu() {
fileMenu.setMnemonic(KeyEvent.VK_F);
adminMenu.setMnemonic(KeyEvent.VK_A);
fileMenu.add(fileMenuItem);
fileMenu.add(adminFileMenuItem);
adminMenu.add(new JMenuItem("Foo 1"));
adminMenu.add(new JMenuItem("Foo 2"));
adminFileMenuItem.setEnabled(false);
adminMenu.setEnabled(false);
menubar.add(fileMenu);
menubar.add(adminMenu);
}
public void setPrivileges(Privileges privileges) {
switch (privileges) {
case REGULAR:
adminMenu.setEnabled(false);
adminFileMenuItem.setEnabled(false);
break;
case ADMINISTRATOR:
adminMenu.setEnabled(true);
adminFileMenuItem.setEnabled(true);
break;
default:
break;
}
}
public JMenuBar getMenubar() {
return menubar;
}
}

JScrollPane not working as intended, why?

Edit the action listener by adding 6 more branches to the else-if logic. Each
branch will compare the actionCommand to the 6 submenu items: Metal, Motif,
Window, Never, Always, and As Needed.
a. Each Look and Feel submenu item will use a try-catch statement to set
the look and feel to the appropriate one, displaying an error message if this
was not accomplished.
b. Each Scroll Bars submenu item will set the horizontal and vertical scroll
bar policy to the appropriate values.
c. Any components that have already been created need to be updated. This
can be accomplished by calling the SwingUtilities.updateComponentTreeUI method, passing a reference to the component that you want to update as an argument. Specifically you will need to add the line
SwingUtilities.updateComponentTreeUIgetContentPane());
to each branch that you just added to the logic structure.
My code is this..and it is crashing and I am completely stuck on why. Any help is appreciated.
package src.javaapplication5;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class NoteTaker extends JFrame {
//constants for set up of note taking area
public static final int WIDTH = 600;
public static final int HEIGHT = 300;
public static final int LINES = 13;
public static final int CHAR_PER_LINE = 45;
//objects in GUI
private JTextArea theText; //area to take notes
private JMenuBar mBar; //horizontal menu bar
private JPanel textPanel; //panel to hold scrolling text area
private JMenu notesMenu; //vertical menu with choices for notes
//****THESE ITEMS ARE NOT YET USED. YOU WILL BE CREATING THEM IN THIS LAB
private JMenu viewMenu; //vertical menu with choices for views
private JMenu lafMenu; //vertical menu with look and feel
private JMenu sbMenu; //vertical menu with scroll bar option
private JScrollPane scrolledText; //scroll bars
//default notes
private String note1 = "No Note 1.";
private String note2 = "No Note 2.";
/**
* constructor
*/
public NoteTaker() {
//create a closeable JFrame with a specific size
super("Note Taker");
setSize(WIDTH, HEIGHT);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//get contentPane and set layout of the window
Container contentPane = getContentPane();
contentPane.setLayout(new BorderLayout());
//creates the vertical menus
createNotes();
createViews();
//creates horizontal menu bar and
//adds vertical menus to it
mBar = new JMenuBar();
mBar.add(notesMenu);
mBar.add(viewMenu);
//****ADD THE viewMenu TO THE MENU BAR HERE
setJMenuBar(mBar);
//creates a panel to take notes on
textPanel = new JPanel();
textPanel.setBackground(Color.blue);
JTextArea theText = new JTextArea(LINES, CHAR_PER_LINE);
theText.setBackground(Color.white);
JScrollPane scrolledText = new JScrollPane(theText);
//****CREATE A JScrollPane OBJECT HERE CALLED scrolledText
//****AND PASS IN theText, THEN
//****CHANGE THE LINE BELOW BY PASSING IN scrolledText
textPanel.add(scrolledText);
contentPane.add(textPanel, BorderLayout.CENTER);
}
/**
* creates vertical menu associated with Notes menu item on menu bar
*/
public void createNotes() {
notesMenu = new JMenu("Notes");
JMenuItem item;
item = new JMenuItem("Save Note 1");
item.addActionListener(new MenuListener());
notesMenu.add(item);
item = new JMenuItem("Save Note 2");
item.addActionListener(new MenuListener());
notesMenu.add(item);
item = new JMenuItem("Open Note 1");
item.addActionListener(new MenuListener());
notesMenu.add(item);
item = new JMenuItem("Open Note 2");
item.addActionListener(new MenuListener());
notesMenu.add(item);
item = new JMenuItem("Clear");
item.addActionListener(new MenuListener());
notesMenu.add(item);
item = new JMenuItem("Exit");
item.addActionListener(new MenuListener());
notesMenu.add(item);
}
/**
* creates vertical menu associated with Views menu item on the menu bar
*/
public void createViews() {
viewMenu = new JMenu("Views");
viewMenu.setMnemonic(KeyEvent.VK_V);
createLookAndFeel();
createScrollBars();
lafMenu.addActionListener(new MenuListener());
sbMenu.addActionListener(new MenuListener());
viewMenu.add(lafMenu);
viewMenu.add(sbMenu);
}
/**
* creates the look and feel submenu
*/
public void createLookAndFeel() {
lafMenu = new JMenu("Look and Feel");
lafMenu.setMnemonic(KeyEvent.VK_L);
JMenuItem metalItem;
JMenuItem motifItem;
JMenuItem windowsItem;
metalItem = new JMenuItem("Metal");
metalItem.addActionListener(new MenuListener());
motifItem = new JMenuItem("Motif");
motifItem.addActionListener(new MenuListener());
windowsItem = new JMenuItem("Windows");
windowsItem.addActionListener(new MenuListener());
lafMenu.add(metalItem);
lafMenu.add(motifItem);
lafMenu.add(windowsItem);
}
/**
* creates the scroll bars submenu
*/
public void createScrollBars() {
sbMenu = new JMenu("Scroll Bars");
sbMenu.setMnemonic(KeyEvent.VK_S);
JMenuItem neverItem;
JMenuItem alwaysItem;
JMenuItem asneededItem;
neverItem = new JMenuItem("Never");
neverItem.addActionListener(new MenuListener());
alwaysItem = new JMenuItem("Always");
alwaysItem.addActionListener(new MenuListener());
asneededItem = new JMenuItem("As Needed");
asneededItem.addActionListener(new MenuListener());
sbMenu.add(neverItem);
sbMenu.add(alwaysItem);
sbMenu.add(asneededItem);
}
private class MenuListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
String actionCommand = e.getActionCommand();
if (actionCommand.equals("Save Note 1")) {
note1 = theText.getText();
} else if (actionCommand.equals("Save Note 2")) {
note2 = theText.getText();
} else if (actionCommand.equals("Clear")) {
theText.setText("");
} else if (actionCommand.equals("Open Note 1")) {
theText.setText(note1);
} else if (actionCommand.equals("Open Note 2")) {
theText.setText(note2);
} else if (actionCommand.equals("Exit")) {
System.exit(0);
} else if (actionCommand.equals("Metal")) {
try {
UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
SwingUtilities.updateComponentTreeUI(getContentPane());
} catch (Exception ex) {
JOptionPane.showMessageDialog(null, "Error setting "
+ "the look and feel");
System.exit(0);
}
} else if (actionCommand.equals("Motif")) {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel");
SwingUtilities.updateComponentTreeUI(getContentPane());
} catch (Exception ex) {
JOptionPane.showMessageDialog(null, "Error setting "
+ "the look and feel");
System.exit(0);
}
} else if (actionCommand.equals("Windows")) {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
SwingUtilities.updateComponentTreeUI(getContentPane());
} catch (Exception ex) {
JOptionPane.showMessageDialog(null, "Error setting "
+ "the look and feel");
System.exit(0);
}
} else if (actionCommand.equals("Never")) {
scrolledText.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
SwingUtilities.updateComponentTreeUI(getContentPane());
scrolledText.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
SwingUtilities.updateComponentTreeUI(getContentPane());
} else if (actionCommand.equals("Always")) {
scrolledText.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
SwingUtilities.updateComponentTreeUI(getContentPane());
scrolledText.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
SwingUtilities.updateComponentTreeUI(getContentPane());
} else if (actionCommand.equals("As Needed")) {
scrolledText.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
SwingUtilities.updateComponentTreeUI(getContentPane());
scrolledText.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
SwingUtilities.updateComponentTreeUI(getContentPane());
} //****ADD 6 BRANCHES TO THE ELSE-IF STRUCTURE
//****TO ALLOW ACTION TO BE PERFORMED FOR EACH
//****MENU ITEM YOU HAVE CREATED
else {
theText.setText("Error in memo interface");
}
}
}
public static void main(String[] args) {
NoteTaker gui = new NoteTaker();
gui.setVisible(true);
}
}
lots of issues, please to compare your code with
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.border.EmptyBorder;
public class NoteTaker {
//constants for set up of note taking area
public static final int WIDTH = 600;
public static final int HEIGHT = 300;
public static final int LINES = 13;
public static final int CHAR_PER_LINE = 45;
//
private JFrame frame = new JFrame("Note Taker");
//objects in GUI
private JTextArea theText; //area to take notes
private JMenuBar mBar; //horizontal menu bar
private JPanel textPanel; //panel to hold scrolling text area
private JMenu notesMenu; //vertical menu with choices for notes
//****THESE ITEMS ARE NOT YET USED. YOU WILL BE CREATING THEM IN THIS LAB
private JMenu viewMenu; //vertical menu with choices for views
private JMenu lafMenu; //vertical menu with look and feel
private JMenu sbMenu; //vertical menu with scroll bar option
private JScrollPane scrolledText; //scroll bars
//default notes
private String note1 = "No Note 1.";
private String note2 = "No Note 2.";
/**
* constructor
*/
public NoteTaker() {
//create a closeable JFrame with a specific size
//setSize(WIDTH, HEIGHT);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//get contentPane and set layout of the window
//Container contentPane = frame;
//contentPane.setLayout(new BorderLayout());
//creates the vertical menus
createNotes();
createViews();
//creates horizontal menu bar and
//adds vertical menus to it
mBar = new JMenuBar();
mBar.add(notesMenu);
mBar.add(viewMenu);
//****ADD THE viewMenu TO THE MENU BAR HERE
frame.setJMenuBar(mBar);
//creates a panel to take notes on
textPanel = new JPanel(new BorderLayout());
textPanel.setBackground(Color.blue);
textPanel.setBorder(new EmptyBorder(5,5,5,5));
/*JTextArea*/ theText = new JTextArea(LINES, CHAR_PER_LINE);
theText.setBackground(Color.white);
/*JScrollPane*/ scrolledText = new JScrollPane(theText);
//****CREATE A JScrollPane OBJECT HERE CALLED scrolledText
//****AND PASS IN theText, THEN
//****CHANGE THE LINE BELOW BY PASSING IN scrolledText
textPanel.add(scrolledText);
frame.add(textPanel/*, BorderLayout.CENTER*/);
frame.pack();
frame.setVisible(true);
}
/**
* creates vertical menu associated with Notes menu item on menu bar
*/
public void createNotes() {
notesMenu = new JMenu("Notes");
JMenuItem item;
item = new JMenuItem("Save Note 1");
item.addActionListener(new MenuListener());
notesMenu.add(item);
item = new JMenuItem("Save Note 2");
item.addActionListener(new MenuListener());
notesMenu.add(item);
item = new JMenuItem("Open Note 1");
item.addActionListener(new MenuListener());
notesMenu.add(item);
item = new JMenuItem("Open Note 2");
item.addActionListener(new MenuListener());
notesMenu.add(item);
item = new JMenuItem("Clear");
item.addActionListener(new MenuListener());
notesMenu.add(item);
item = new JMenuItem("Exit");
item.addActionListener(new MenuListener());
notesMenu.add(item);
}
/**
* creates vertical menu associated with Views menu item on the menu bar
*/
public void createViews() {
viewMenu = new JMenu("Views");
viewMenu.setMnemonic(KeyEvent.VK_V);
createLookAndFeel();
createScrollBars();
lafMenu.addActionListener(new MenuListener());
sbMenu.addActionListener(new MenuListener());
viewMenu.add(lafMenu);
viewMenu.add(sbMenu);
}
/**
* creates the look and feel submenu
*/
public void createLookAndFeel() {
lafMenu = new JMenu("Look and Feel");
lafMenu.setMnemonic(KeyEvent.VK_L);
JMenuItem metalItem;
JMenuItem motifItem;
JMenuItem windowsItem;
metalItem = new JMenuItem("Metal");
metalItem.addActionListener(new MenuListener());
motifItem = new JMenuItem("Motif");
motifItem.addActionListener(new MenuListener());
windowsItem = new JMenuItem("Windows");
windowsItem.addActionListener(new MenuListener());
lafMenu.add(metalItem);
lafMenu.add(motifItem);
lafMenu.add(windowsItem);
}
/**
* creates the scroll bars submenu
*/
public void createScrollBars() {
sbMenu = new JMenu("Scroll Bars");
sbMenu.setMnemonic(KeyEvent.VK_S);
JMenuItem neverItem;
JMenuItem alwaysItem;
JMenuItem asneededItem;
neverItem = new JMenuItem("Never");
neverItem.addActionListener(new MenuListener());
alwaysItem = new JMenuItem("Always");
alwaysItem.addActionListener(new MenuListener());
asneededItem = new JMenuItem("As Needed");
asneededItem.addActionListener(new MenuListener());
sbMenu.add(neverItem);
sbMenu.add(alwaysItem);
sbMenu.add(asneededItem);
}
private class MenuListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
String actionCommand = e.getActionCommand();
if (actionCommand.equals("Save Note 1")) {
note1 = theText.getText();
} else if (actionCommand.equals("Save Note 2")) {
note2 = theText.getText();
} else if (actionCommand.equals("Clear")) {
theText.setText("");
} else if (actionCommand.equals("Open Note 1")) {
theText.setText(note1);
} else if (actionCommand.equals("Open Note 2")) {
theText.setText(note2);
} else if (actionCommand.equals("Exit")) {
System.exit(0);
} else if (actionCommand.equals("Metal")) {
try {
UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
SwingUtilities.updateComponentTreeUI(frame);
} catch (Exception ex) {
JOptionPane.showMessageDialog(null, "Error setting "
+ "the look and feel");
System.exit(0);
}
} else if (actionCommand.equals("Motif")) {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel");
SwingUtilities.updateComponentTreeUI(frame);
} catch (Exception ex) {
JOptionPane.showMessageDialog(null, "Error setting "
+ "the look and feel");
System.exit(0);
}
} else if (actionCommand.equals("Windows")) {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
SwingUtilities.updateComponentTreeUI(frame);
} catch (Exception ex) {
JOptionPane.showMessageDialog(null, "Error setting "
+ "the look and feel");
System.exit(0);
}
} else if (actionCommand.equals("Never")) {
//SwingUtilities.updateComponentTreeUI(frame);
scrolledText.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scrolledText.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
//SwingUtilities.updateComponentTreeUI(frame);
} else if (actionCommand.equals("Always")) {
//SwingUtilities.updateComponentTreeUI(frame);
scrolledText.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
scrolledText.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
//SwingUtilities.updateComponentTreeUI(frame);
} else if (actionCommand.equals("As Needed")) {
//SwingUtilities.updateComponentTreeUI(frame);
scrolledText.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrolledText.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
//SwingUtilities.updateComponentTreeUI(frame);
} //****ADD 6 BRANCHES TO THE ELSE-IF STRUCTURE
//****TO ALLOW ACTION TO BE PERFORMED FOR EACH
//****MENU ITEM YOU HAVE CREATED
else {
theText.setText("Error in memo interface");
}
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
NoteTaker gui = new NoteTaker();
}
});
}
}
You are getting an exception because scrollText is null.
When creating scrollText, it is created as a local variable in the constructor.
JScrollPane scrolledText = new JScrollPane(theText);
It is also declared as a field, but since it is also declared as a local variable in the constructor, the field is never initialized.
Instead, just do:
scrolledText = new JScrollPane(theText);
Your code:
else if (actionCommand.equals("Never")) {
scrolledText.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
SwingUtilities.updateComponentTreeUI(getContentPane());
scrolledText.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
SwingUtilities.updateComponentTreeUI(getContentPane());
} else if (actionCommand.equals("Always")) {
scrolledText.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
SwingUtilities.updateComponentTreeUI(getContentPane());
scrolledText.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
SwingUtilities.updateComponentTreeUI(getContentPane());
} else if (actionCommand.equals("As Needed")) {
scrolledText.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
SwingUtilities.updateComponentTreeUI(getContentPane());
scrolledText.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
SwingUtilities.updateComponentTreeUI(getContentPane());
}
My code :
else if (actionCommand.equals("Never")) {
scrolledText.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
SwingUtilities.updateComponentTreeUI(getContentPane());
scrolledText.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
SwingUtilities.updateComponentTreeUI(getContentPane());
}
else if (actionCommand.equals("Always")) {
scrolledText.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
SwingUtilities.updateComponentTreeUI(getContentPane());
scrolledText.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
SwingUtilities.updateComponentTreeUI(getContentPane());
}
else if (actionCommand.equals("As Needed")) {
scrolledText.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
SwingUtilities.updateComponentTreeUI(getContentPane());
scrolledText.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
SwingUtilities.updateComponentTreeUI(getContentPane());
}

JFrame Action Listener that listens to all menu items?

So I have a JFrame set up with a menu with the current structure that looks something along the lines of this:
File
Exit
Pages
Reviews
A
B
C
Help
About
I want to create a Action Listener that only listens to menu items under Reviews. Is this a possibility (and if so, how) or do I have to create a generic listener and check if it's one of those items?
Yes, it is possible:
Store your menu items as fields
Add the same ActionListener to each menu item.
In the listener check for the source to know which item was clicked.
Should look like:
public class YourFrame extends JFrame implements ActionListener {
private final JMenuItem menuA, menuB;
public YourFrame(){
super("Your app");
JMenuBar menuBar = new JMenuBar();
JMenu menuReviews = new JMenu("Reviews");
menuA = new JMenuItem("A");
menuB = new JMenuItem("B");
...
menuReviews.add(menuA);
menuReviews.add(menuB);
menuBar.add(menuReviews);
setJMenuBar(menuBar);
...
menuA.addActionListener(this);
menuB.addActionListener(this);
...
}
public void actionPerformed(ActionEvent event){
if(event.getSource()==menuA){
System.out.println("Menu A clicked");
...
}else if(event.getSource()==menuB){
System.out.println("Menu B clicked");
...
}
}
}
Note that here I let the JFrame implement ActionListener, but this is just for convenience. You could use a dedicated class, or an anonymous class created in the constructor:
ActionListener reviewsListener = new ActionListener(){
public void actionPerformed(ActionEvent event){
if(event.getSource()==menuA){
System.out.println("Menu A clicked");
...
}else if(event.getSource()==menuB){
System.out.println("Menu B clicked");
...
}
}
};
menuA.addActionListener(reviewsListener);
menuB.addActionListener(reviewsListener);
If you want to integrate this process a little more, I could also suggest to extend JMenu, so that you can pass it your action listener and add it systematically to new menu items.
public class YourJMenu extends JMenu {
private ActionListener listener;
public YourJMenu(String name, ActionListener listener){
super(name);
this.listener = listener;
}
#Override
public JMenuItem add(JMenuItem item){
item.addActionListener(listener);
return super.add(item);
}
}
With this, you just need to write:
JMenu menuReviews = new YourJMenu("Reviews", this);
and drop the:
menuA.addActionListener(this);
menuB.addActionListener(this);
Using a common method we can add the action listener to all the menu items under a menu. Below is a example code.
public class MenuItemEvent {
JFrame objFrm = new JFrame("Menu event demo");
JMenuBar mBar;
JMenu mnu;
JMenuItem mnuItem1, mnuItem2, mnuItem3;
public void show() {
objFrm.setSize(300, 300);
mBar = new JMenuBar();
mnu = new JMenu("Reviews");
mBar.add(mnu);
mnuItem1 = new JMenuItem("A");
mnu.add(mnuItem1);
mnuItem2 = new JMenuItem("B");
mnu.add(mnuItem2);
mnuItem3 = new JMenuItem("C");
mnu.add(mnuItem3);
//method call
fnAddActionListener(mnu);
objFrm.setJMenuBar(mBar);
objFrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
objFrm.setVisible(true);
}
//method to add action listener to all menu items under a menu
public void fnAddActionListener(JMenu mnu) {
if (mnu.getItemCount() != 0) {
for (int iCount = 0; iCount < mnu.getItemCount(); iCount++) {
(mnu.getItem(iCount)).addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
fnMenuItemAction(e);
}
});
}
}
}
//menu item action event
public void fnMenuItemAction(ActionEvent e) {
if (e.getSource().equals(mnuItem1)) {
System.out.println("Menu Item 1");
} else if (e.getSource().equals(mnuItem2)) {
System.out.println("Menu Item 2");
} else if (e.getSource().equals(mnuItem3)) {
System.out.println("Menu Item 3");
}
}
public static void main(String[] args) {
new MenuItemEvent().show();
}
}
or with the below function
//fnMenuItemAdd(mnu,mnuItem1)
//etc.
public void fnMenuItemAdd(JMenu mnu, JMenuItem mni) {
mnu.add(mni);
mni.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
fnMenuItemAction(e);
}
});
}

An efficient way of adding JMenuItems

OK so before my INV program was to REMOVE menu items but then I was all like.. that's too much. So what if I were to ADD menu items for specific Right-clicked items INSTEAD of removing every time?
So, if you right-clicked on Item 1, you'd get "Use" and "Drop" added to the menu. Then ONCE you choose your option, the JMenu would delete everything so it would be right where we started. Then if you right-clicked on ITem 2, it would add "Use" and "Cancel". See where I'm going?
I tried doing it myself, but I just can't figure out how to do it -- for example, to add a new JMenuItem, you need to do this:
popup.add(item = new JMenuItem("Cancel"));
item.addActionListener(menuListener);
and, as you can see, add an actionlistener. I can't do that under if (actItemx == "Item 1") { so... what do I do?
Anyways, here's what I have so far:
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseAdapter;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
public class inv extends JApplet implements MouseListener
{
public JList listbox;
public JPopupMenu popup;
public JMenuItem item;
public void init()
{
ActionListener menuListener = new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
String invAction = event.getActionCommand();
int itemSelect = listbox.getSelectedIndex();
Object actItem = listbox.getModel().getElementAt(itemSelect);
System.out.println("Popup menu item [" + invAction + "] [ " + actItem + " ] was pressed.");
}
};
popup = new JPopupMenu();
popup.add(item = new JMenuItem("Use"));
item.addActionListener(menuListener);
popup.add(item = new JMenuItem("Drop"));
item.addActionListener(menuListener);
popup.add(item = new JMenuItem("Cancel"));
item.addActionListener(menuListener);
String listData[] =
{
"Item 1","Item 2","Item 3","Item 4"
};
listbox = new JList( listData );
listbox.addMouseListener( new MouseAdapter()
{
public void mousePressed(MouseEvent e)
{
if ( SwingUtilities.isRightMouseButton(e) )
{
System.out.println("Row: " + getRow(e.getPoint()));
listbox.setSelectedIndex(getRow(e.getPoint()));
}
}
}
);
listbox.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
add(listbox);
listbox.setVisible(true);
listbox.setFocusable(false);
listbox.addMouseListener(new MousePopupListener());
}
class MousePopupListener extends MouseAdapter
{
public void mousePressed(MouseEvent e)
{
checkPopup(e);
}
public void mouseClicked(MouseEvent e)
{
checkPopup(e);
}
public void mouseReleased(MouseEvent e)
{
checkPopup(e);
}
private void checkPopup(MouseEvent e)
{
if (e.isPopupTrigger())
{
int itemSelectx = listbox.getSelectedIndex();
Object actItemx = listbox.getModel().getElementAt(itemSelectx);
System.out.println("You pressed on " + actItemx);
if (actItemx == "Item 1") {
System.out.println("Removed cancel for " + actItemx);
popup.remove(itemSelectx); // So upon right-click on Item 1, you won't see "Cancel" menu.
}
popup.show(inv.this, e.getX(), e.getY());
popup.revalidate();
}
}
}
private int getRow(Point point)
{
return listbox.locationToIndex(point);
}
public void mouseEntered(MouseEvent e)
{
}
public void mouseReleased(MouseEvent e)
{
}
public void mousePressed(MouseEvent e)
{
}
public void mouseClicked(MouseEvent e)
{
}
public void mouseExited(MouseEvent e)
{
}
}
What about setting up different JPopup menu's for each type of item. What I mean by that is you have something that looks like this:
public JPopupMenu useDropPopup;
public JPopupMenu useCancelPopup;
public void init() {
ActionListener menuListener = new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
String invAction = event.getActionCommand();
int itemSelect = listbox.getSelectedIndex();
Object actItem = listbox.getModel().getElementAt(itemSelect);
System.out.println("Popup menu item [" + invAction + "] [ " + actItem + " ] was pressed.");
}
};
useDropPopup = new JPopupMenu();
useCancelPopup = new JPopupMenu();
JMenuItem useMenuItem = new JMenuItem("Use");
useMenuItem.addActionListener(menuListener);
JMenuItem dropMenuItem = new JMenuItem("Drop");
dropMenuItem.addActionListener(menuListener);
JMenuItem cancelMenuItem = new JMenuItem("Cancel");
cancelMenuItem.addActionListener(menuListener);
useDropPopup.add(useMenuItem);
useDropPopup.add(dropMenuItem);
useCancelPopup.add(useMenuItem);
useCancelPopup.add(cancelMenuItem);
// ... etc bring up the appropriate popup depending on the item.
}
Also, you should not assign a JMenuItem to item inside of a method call. That's bad practice. Also consider using different actionlisteners for each menu item so you can separate the functional code of each menu item, ex:
useMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
useMenuAction(event);
}
};
// ... after the init method
public void useMenuAction(ActionEvent evt) {
// Add specific use menu code here.
}
This is mostly an addition to the answer from jluzwick:
Instead of creating a JMenuItem and adding an ActionListener to it, you can use a Action - this is basically a combination of a ActionListener with a name, optionally Icon and some other properties. (Most simply extend from AbstractAction, overriding the actionPerformed-Method.)
Then add the Action to your JMenu, and it will construct the JMenuItem itself. (You can also use the same Action object on other places, like Buttons, the "normal" menu bar, etc.)

Categories