-2

Unfortunately I did not learn Java, I know other programming languages with the exception of Java.

I know how to create a Menu and add items to the menu. I figured that out from my simple basic java books. However I have access to a piece of open source software and need to make some tweaks to it, to make it work for me and I am stuck. So I will provide code of what is going on and provide code of what I have and then hopefully someone can fill in the missing pieces and explain as well as to how it worked they way it worked.

The code below is part of the file that calls TranslatorAction.java It calls it on the line when creating a new menu item. I completely understand this part. I only posted this code so you can see that the import statement is not being imported for JMenuItem and that the menu item is being added indirectly from the menu.add call. The adminMenu.add is creating the menu item by creating a object / class?? with the paremeters new TranslatorAction

javax.swing.JMenu;
import javax.swing.JMenuBar;
import com.bo.actions.TranslatorAction;
    private void createAdminMenu(JMenuBar menuBar) {
    JMenu adminMenu = new JMenu(com.POSConstants.ADMIN);
    adminMenu.add(new TranslatorAction());
    menuBar.add(adminMenu);
    }

When new TranslatorAction() is called from the above for creating the new menu item. I am having an issue with accessing the setting the text for the new JMenuItem. I know from playing with the code that the line super("test"); is setting the new JMenuItem text. I want to be able to have this set to a variable, so that way it can be changed on the fly. Below is the whole file that gets called from above with adminMenu.add(New TranslatorAction());

TranslatorAction java file code

package com.bo.actions;
  import java.awt.event.ActionEvent;
  import javax.swing.AbstractAction;
  import javax.swing.Icon;
  import javax.swing.JTabbedPane;
  import com.POSConstants;
  import com.bo.ui.BackOfficeWindow;


  public class TranslatorAction extends AbstractAction {

  public TranslatorAction(){
  //I know this sets the JMenuItem to Test.  Again no importing of     
  //JMenuItem at all what so ever.  But I need to set the JmenuItem
  //to something on the fly instead of hard coding it.  Can anyone
  //show and explain how to dynamically create / change super("test"),
  // so that way it is not hard coded? 

  super("Test"); 
  }

  public TranslatorAction(String name) {
    super(name);
  }

  public TranslatorAction(String name, Icon icon) {
        super(name, icon);
  }

  public void actionPerformed(ActionEvent e) {
  }
  }

Thanks for every ones' time for helping me. Shawn

  • 2
    Please edit your question to give a complete example. In particular, all methods should be inside a class. You should also fix the indentation. – Code-Apprentice Feb 15 '17 at 00:18
  • Also, I do not understand what you are asking exactly. You should show in your example where you need to add code that you do not know what to put. – Code-Apprentice Feb 15 '17 at 00:20
  • I did comment the code with what I understand and what I need to change. the line super("test"); is what I need to change. This line I know changes the text on the file menu. So if I change it to super("java"); the file menu will have java on it. I need to be able to change this dynamically. So I guess what I need to know is not the code to change it dynamically but what do I need to do to access setText for the JMenuItem that is created from the call from the other class adminMenu.add(new translatorAction()); – Shawn Mulligan Feb 15 '17 at 00:35
  • I should think that you can make `JMenu adminMenu;` Class global - either public, static, or both. – DevilsHnd - 退職した Feb 15 '17 at 02:10
  • 1
    I think you might want to investigate the concept of MVC - in particular the responsibility of the model and the utilisation of the observer pattern to generate notifications when the model state changes – MadProgrammer Feb 15 '17 at 02:52
  • If an answer helps you solve your problem, don't forget to tick the checkmark at the top to let future users know the answer worked. – MasterBlaster Feb 17 '17 at 01:05
  • Possible duplicate of [Change the title text of JMenuItem upon click?](https://stackoverflow.com/q/20234460/5267751) ----- *(at least it looks like that from the title. Admittedly, the title of this question is better than the other one, but the question&answer of the other one is much more simpler)* – user202729 Jul 16 '18 at 08:06

1 Answers1

0

You can dynamically set a JMenuItems text with the JMenuItem#setText(String) method.

A simpler solution without using separate classes would be to create your own JMenuItem, set its action using anonymous classes, and add it to the JMenu.

final JMenu menu = new JMenu("Test JMenu");
final JMenuItem menuItem = new JMenuItem("Initial Text");
menuItem.setAction(new AbstractAction() {

    @Override
    public void actionPerformed(ActionEvent e) {
        menu.setText("Different Text");
    }

});
menu.add(menuItem);

Note that if you are planning on implementing the MVC pattern (Which @MadProgrammer and I highly recommend), your method call to the controller would be in the actionPerformed(...) method. More information on the MVC pattern can be found in this answer.


If you are really set on adding an AbstractAction to your JMenu, you're going to need to add a way to give your action access to an instance of the JMenuItem it's going to be added to.

You can get this JMenuItem by using myJMenu.getItem(menu.getItemCount() - 1). This gets the last JMenuItem in the JMenu. JMenuItems that are added with the JMenu#add(Action a) are added to the end of the JMenu, as stated in the documentation.

Since there is no way to get the JMenuItem created until after the call to add(Action a), to give your custom AbstractAction the JMenuItem instance you can add a setter method (setJMenuItem(JMenuItem item)) to your custom action.

My reworked AbstractAction implementation looks like this:

public class CustomAction extends AbstractAction {

    private JMenuItem item;

    public CustomAction() {
        super("Initial Text");
    }

    public void setJMenuItem(JMenuItem item) {
        this.item = item;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        item.setText("Different Text");
    }

}

Make sure to set the JMenuItem after you add the action because in this case if the actionPerformed(...) method is called and item is null a NullPointerException will be thrown.

final JMenu menu = new JMenu("Test JMenu");
final CustomAction action = new CustomAction();
menu.add(action);
action.setJMenuItem(menu.getItem(menu.getItemCount() - 1));
Community
  • 1
  • 1
MasterBlaster
  • 948
  • 2
  • 12
  • 26
  • Thank you so much. I will be giving this a try. The only reason for having separate classes and using AbstractAction is to stay in the style of the original code. However, all of the original code sets the text of the JMenuItem by calling the menu.add(new class()) and then in the new class it created the displayed JMenuItem with SUPER("Display Name Of Menu Item"). And I did do a lot of reading through different books that I have on java and they all go into basic details about JMenuItem and the JMenu classes, but not enough for me to piece it together. – Shawn Mulligan Feb 16 '17 at 17:21
  • 2 Books I am learning from are Deitel and Deitel Java How To Program Covers Swing and Ivor Horton's Beginning Java 2. However none of these go into depth with some of the things that I need to know or trying to figure out like this for example. I know how to do this without using separate classes, but with keeping the style of the original author is what I want to maintain. If there are any other good Java resource books or ones better than I am using please let me know as well. – Shawn Mulligan Feb 16 '17 at 19:58
  • Not just for me but others reading as well. Being my initial separate class file does not import the JMenuItem, I am assuming that I have to import that for this to work? When I compile I get an error CAN NOT FIND SYMBOL JMenuItem. – Shawn Mulligan Feb 16 '17 at 23:43
  • Okay so this works beautifully for me. The problem is when the menu loads it Displays Initial Text, and it only changes to Different Text after you click on Initial text. So I thought that I could just add the following: item.setText("My Text"); in the setJMenuItem. When I did this I get what you referred to earlier which is the NullPointerException. What I need to be able to do is set it on initial loading of the menu, not after it displays and is clicked on. Thanks for all the help. – Shawn Mulligan Feb 17 '17 at 00:33
  • Okay problem solved. I had to change item.setText("My Text"); to this.item.setText("My New Text"); and it now works. Now from there I should be able to finish what I need to accomplish. Again info on any good Java resources or books would be great. Thank You everyone. – Shawn Mulligan Feb 17 '17 at 00:59
  • Is there anyway to do this without needing to use JMenuItem? When you do MyMenu.add(blah) it automatically creates the JMenuItem, so is there anyway to intercept the created JMenuItem without having to explicitly create it? – Shawn Mulligan Feb 17 '17 at 19:45
  • You can use `new JMenuItem(Action a)` to create a `JMenuItem` with an `Action` without adding it to or using a `JMenu`. – MasterBlaster Feb 19 '17 at 21:10