简体   繁体   中英

How do I access an object outside of “private void initialize”?

I'm new to Java and I'm working on my first GUI using the WindowBuilder plugin for Eclipse Mars.

In "private void initialize" it creates my objects: a TextArea and a JButton.

I want to be able to manipulate my TextArea in a method, but I can't simply type something like: txtOutput.setText("test");

(I want my JButton to call a method and let the method do all the work because I also have a menu item that's going to do the same thing, so it makes sense to put my code into a method and have the menu item and the button call the method. My actionPerformed event handlers are working and they call the method, but the method can't "see" the txtOutput.) I'm guessing some keyword needs to be in front of txtOutput .

What do I need to put in front of txtOutput?

Sorry for being such a newb. I hope I've explained this well. Thank you for any help you can offer.

Here is a copy of my code:

package Junkpad;

import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.JFrame;
import java.awt.TextArea;
import java.awt.Toolkit;

import javax.swing.JButton;
import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class GUITest {

    private JFrame frame;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
            try {
                GUITest window = new GUITest();
                window.frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
            }
        });
    }

    public GUITest() {
        initialize();
    }

    private void initialize() {
        frame = new JFrame();
        frame.setResizable(false);
        frame.setBounds(100, 100, 450, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(null);
        frame.setTitle("My First GUI");

        TextArea txtOutput = new TextArea();
        txtOutput.setBounds(0, 20, 442, 197);
        frame.getContentPane().add(txtOutput);

        JButton btnChangeText = new JButton("Change Text");
        btnChangeText.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent actEvent) {
                Object srcSource = actEvent.getSource();
            if (srcSource == btnChangeText) {
                ChangeText();
            }
            }
        });
        btnChangeText.setBounds(247, 223, 180, 29);
        frame.getContentPane().add(btnChangeText);

        JMenuBar menuBar = new JMenuBar();
        menuBar.setBounds(0, 0, 442, 27);
        frame.getContentPane().add(menuBar);

        JMenu mnFile = new JMenu("File");
        menuBar.add(mnFile);

        JMenuItem mntmChangeText = new JMenuItem("Change Text");
        mntmChangeText.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent actEvent) {
                Object srcSource = actEvent.getSource();
            if (srcSource == mntmChangeText) {
                ChangeText();
            }
            }
        });
        mnFile.add(mntmChangeText);

        // center frame on screen
        Dimension dimDimension = Toolkit.getDefaultToolkit().getScreenSize();
        frame.setLocation((dimDimension.width-frame.getSize().width)/2, (dimDimension.height-frame.getSize().height)/2);
    }

    private static void ChangeText(){
        // here is where I want to change the text of txtOutput
        // none of these attempts work:
            //txtOutput.setText("testing");
            //GUITest.txtOutput.setText("testing");
            //initialize.txtOutput.setText("testing");
            //this.txtOutput.setText("testing");

        // the calls from the actionPerformed event handlers are working
        // because this code runs when I click the button or the menu item 
        System.out.println("ChangeText was called");
    }
}

You must be aware of two things: scope of visibility and lifetime.

In a method, the scope is the block and the lifetime is the duration of its execution.

void init(){
    int i = 42;
    JTextArea myText = ...;

}

Both are visible till the end of the block ( } ) and i is gone when init returns and the object referenced via myText will be gone, too, unless you copy the reference to some other place, perhaps the enclosing panel.

class Foo {
    int j;
    JTextArea ourText;

    void m1(){ }
    void m2(){ }
}

Both j and ourText are visible in all methods of the class. And both live inside the object of class Foo whenever one is created. So, there may be many j's and many ourTexts, but you identify them clearly when you call aFoo.m1() or bFoo.m1() so there is no way they can be confused.

Much more could be said... But this should help you solve your problem.

Edit Now that I see the code I can say that the declaration of

JTextArea txtArea;

must be written as a field of the class; method initialize may only assign the new JTextArea() to it. If it is a variable in method initialize its visibility is restricted to the block of that method. Its "life" is saved by passing it into the content pane of the frame - which is a field of class GUITest.

Now, if you correct that and uncomment txtOutput.setText("testing") in method changeText you'll see another error cropping up:

GUITest.java:85: error: non-static variable txtOutput cannot be referenced from a static context
        txtOutput.setText("testing");
        ^

This is yet another chapter of the Scope & Lifetime Story. A static method or field ("class field") is visible to all methods in a class but it isn't permitted to make an unqualified access to "instance fields", because it would be impossible to tell the instance to which it belongs. Static fields, however, are unique, belong to the class as a unit and have maximum lifetime, ie, as long as the class is in the program. Thus the reverse - referencing a static variable from a non-static method - is permitted. (But the possibly many objects of that class must take care that their common usage of that static variable doesn't result in a pell-mell.)

You remove the "static" from method changeText - and it works!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM