2

I've looked at other JLabel threads and though similar, a few just don't seem to apply to what I'm experiencing. First, I want to say I am a novice when it comes to Java. Next, I am trying to follow tutorials and demos at the docs.oracle.com site. Now, I can update the label when I type something into a JTextField and there is an ActionListener on that...

But I also have a Menu, and when I select a Menu Item, that Action does not want to update the label.

Questions -

  1. How do I have action listeners on both JTextFields and JMenuItems? Are there two ActionEvent methods or do I use one method and somehow identify each type of action?
  2. If I use the same basic code in the JTextField ActionEvent and JMenuItem ActionEvent, the JLabel updates correctly with the JTextField event but not JMenuItem event. They both use the messageField.setText property. Could the JMenuItem action be doing something to block the setText?

I can easily copy code in here, but it's pretty spaghetti-like at the moment, so if you want to see anything, let me know specifically and I'll post it.

I would appreciate any assistance that anyone would be able to provide.

---edit--- Wow!! Thanks for all of the comments and suggestions.

1 - I know it has to be my code. As I mentioned, I am really just cobbling stuff together from demos and tutorials, and trying to learn Java along the way. I've just never gotten the hang of object oriented.... 2 - I do know the individual Listeners are working. I'm using System.out.println to validate, as well as inspecting those labels in debug mode to see they have indeed changed.
3 - I will look at the various links and code posted here and see if I can figure out what's wrong with my code.

Really, thanks again!

---edit---

Here is what I originally had in my createAndShowGUI method....

private static void createAndShowGUI()   
{  
    JFrame frame = new JFrame("Create XML for Photo Gallery");  
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  

    CreateGalleryXML window = new CreateGalleryXML();  
    frame.setJMenuBar(window.createMenuBar());  
    frame.add(new CreateGalleryXML());  

    frame.pack();  
    frame.setVisible(true);  
}  
Osh
  • 119
  • 1
  • 1
  • 8

3 Answers3

6

Seems like you yourself are doing something wrong, in your code. Without a proper SSCCE it's hard to say what thing you doing wrong, since it works perfectly, using same ActionListener for both JMenuItem and JTextField.

Here is a sample program to match with yours :

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

public class UpdateLabel
{
    private JLabel label;
    private String labelText;

    private ActionListener action = new ActionListener()
    {
        public void actionPerformed(ActionEvent ae)
        {
            setLabelText((String) ae.getActionCommand());
            label.setText(getLabelText());
        }
    };

    private void setLabelText(String text)
    {
        labelText = text;
    }

    private String getLabelText()
    {
        return labelText;
    }

    private void createAndDisplayGUI()
    {
        final JFrame frame = new JFrame("Update Label");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.setLocationByPlatform(true);

        JMenuBar menuBar = new JMenuBar();
        JMenu programMenu = new JMenu("Program");
        JMenuItem exitMenuItem = new JMenuItem("Exit");
        exitMenuItem.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                frame.dispose();
            }
        });
        JMenu labelMenu = new JMenu("Label");
        JMenuItem updateMenuItem = new JMenuItem("Update Label");
        updateMenuItem.setActionCommand("Updated by JMenuItem");
        updateMenuItem.addActionListener(action);

        programMenu.add(exitMenuItem);
        labelMenu.add(updateMenuItem);
        menuBar.add(programMenu);
        menuBar.add(labelMenu);

        frame.setJMenuBar(menuBar);

        JPanel contentPane = new JPanel();

        label = new JLabel("I am the LABEL which will be updated!!");
        contentPane.add(label);

        JTextField tfield = new JTextField(10);
        tfield.setActionCommand("Updated by JTextField");
        tfield.addActionListener(action);

        frame.add(contentPane, BorderLayout.CENTER);
        frame.add(tfield, BorderLayout.PAGE_END);

        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String... args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new UpdateLabel().createAndDisplayGUI();
            }
        });
    }
}

And here is the output in both the cases :

Updated with JMenuItem and Updated with JTextField

Do check out the main method, might be you had failed to put your code inside EDT - Event Dispatcher Thread, that can lead to such issues too. All updates on the Swing GUI, must be done on the Event Dispatcher Thread.

LATEST EDIT

It seems to me that CreateGalleryXML extends JPanel by the look of it. See at Line 3 of this below code taken from your update, here you are initializing a new Object of CreateGalleryXML inside, when you already had one Object window created at Line 1:

CreateGalleryXML window = new CreateGalleryXML();  
frame.setJMenuBar(window.createMenuBar());  
frame.add(new CreateGalleryXML());

So try to change the above thingy to this

CreateGalleryXML window = new CreateGalleryXML();  
frame.setJMenuBar(window.createMenuBar());  
frame.add(window);

and see what happens and Please do revert back again :-)

nIcE cOw
  • 24,468
  • 7
  • 50
  • 143
  • Wow... This did it for me. I pretty much scrapped everything, started with your code, then started building back up from there. I'm still a good bit confused, but I've now gotten far enough along that things are looking like they're going in the right direction. There's enough of the core back in that I can see my message label being updated when necessary. Going back and looking at my previous code, I think it had to do with my createAndShowGUI method was inadvertently creating multiple frames? Maybe? – Osh Apr 04 '12 at 03:49
  • I posted my original createAndShowGUI since I think that was the root of all of my problems. That's as an edit to my original post, if you are interested. Thanks again for all of your assistance!!!! I truly appreciate it! – Osh Apr 04 '12 at 04:03
  • @Osh : I had edited my post a bit further, seems like you creating a new Object as mentioned above is the real cause of all problems. Try to rectify that as mentioned above, and Please do revert back :-) – nIcE cOw Apr 04 '12 at 06:15
  • Yup. that was my problem. So in a nutshell, was I creating a second object, and that's what was being updated when I should have just added the previously created object to the frame instead? I know, basic OO programming, but like I mentioned, I'm not good at it, but only trying to learn.... Thanks again, this is just further proof that I need to spend more time with lessons and understanding instead of just jumping in with both feet and trying to hack my way through it. – Osh Apr 05 '12 at 00:28
  • Exactly, the `JMenuBar` belonged to the object window, but whatever you added later on to the `JFrame`, that is an anonymous object, to which you have no reference to point to. No worries, sometimes you get to know things with experience, as you encounter them. Glad it helped you somewhere, just remember, KEEP SMILING :-) hehe – nIcE cOw Apr 05 '12 at 04:41
  • :-) of course! It's all a learning process. Now I'm just trying to track down another issue that's confounding me. On the plus side, stepping back, commenting out everything and just starting from scratch using your code as a starting point, I was able to clean up everything a good bit! – Osh Apr 05 '12 at 23:08
  • Hope you found success in your endeavour, as you move along :-) . Do try what @trashgod, has to say too, that advice is really wonderful regarding [Action](http://docs.oracle.com/javase/tutorial/uiswing/misc/action.html). Even I didn't knew about that, till I read that Java Doc, regarding it's benefits :-) – nIcE cOw Apr 06 '12 at 06:20
6

Use Action to encapsulate common functionality that must be shared by menus and related components. See this example that extends AbstractAction.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • +1, I guess when you can use `AbstractAction`, one must use it instead of `ActionLIstener` :-) I forgot the word , to represent this situation :-) – nIcE cOw Apr 02 '12 at 09:17
  • 1
    @GagandeepBali: It's a good defense against duplicate code evolving separately. – trashgod Apr 02 '12 at 09:21
4

Pretty much everything you could need to know is in the Java tutorials. Down the bottom they have demo's on how to do both menu's and text fields. They include source code to look at as well.

There's not much more I can say that they don't say better, but in answer to your questions:

  1. Both, you can have separate listener's on each component, or one that figures out what component is responsible for causing the action event. I would suggest you use separate ones for each thing.

  2. Can't really say with out seeing the code, are you sure that the action on the JMenu is even firing? Does it print something to the console etc if you use System.out.println somewhere?

dann.dev
  • 2,406
  • 3
  • 20
  • 32
  • +1, for pointing out to try `System.out.println(...)`, atleast that will print no matter what wrong you're doing in your Swing code. – nIcE cOw Apr 02 '12 at 06:25