tags:

views:

94

answers:

3

Hello, I'm working my way through an exercise to understand Java, and basically I need to merge the functionality of two classes into one app.

I'm stuck on one area though - the referencing of objects across classes.

What I have done is set up a gui in one class (test1), and this has a textfield in ie.

chatLine = new JTextField();

in another class(test2), I was planning on leaving all the functionality in there and referencing the various gui elements set up in test1 - like this test1.chatLine

I understand this level of referencing, I tested this by setting up a test method in the test2 class

public static void testpass() {

        test1.testfield.setText("hello");
    }

I'm trying to understand how to implement the more complex functionality in test2 class though, specifically this existing code;

test1.chatLine.addActionListener(new ActionAdapter() {
            public void actionPerformed(ActionEvent e) {
               String s = Game.chatLine.getText();
               if (!s.equals("")) {
                  appendToChatBox("OUTGOING: " + s + "\n");
                  Game.chatLine.selectAll();

                  // Send the string
                  sendString(s);
               }
            }
         });

This is the bit I'm stuck on, if I should be able to do this - as it's failing on the compile, can I add the actionadapter stuff to the gui element thats sat in test1, but do this from test2 - I'm wondering if I'm trying to do something that's not possible.

Hope this makes sense, I'm pretty confused over this - I'm trying to understand how the scope and referencing works.

Ideally what i'm trying to achieve is one class that has all the main stuff in, the gui etc, then all the related functionality in the other class, and target the first class's gui elements with the results etc.

Any thoughts greatly appreciated.

+1  A: 

I'm not clear on whether chatLine is a local variable, an instance variable, or a static variable. Any of these things could be the source of your compile error, which you didn't specify -- what's the error?

If it's an instance or static variable, it can be made visible from anywhere by making it public. This doesn't mean that's a good idea.

At least, it should be private and exposed via a getChatLine() method.

Even then, there's some question about whether this design is the right one, but at least you'd be doing it right at a compiler level and basic data encapsulation level.

Sean Owen
Hi, Apologies - I realise it's a little vague, the chatline var is public static JTextField chatLine; in the test1 class. I ammended my test method in the test2 class to this public static void testpass() { Game.chatLine.setText("hello"); } and it works, but its all the test1.chatLine.addActionListener(new ActionAdapter() that I'm trying to undertsand - of its possible to add the listener to the chatline textfield from the test2 class, while it's sat in the test1 class
ivor
It is possible to call chatLine.addActionListener from anywhere where you can access chatLine; you probably have an error somewhere else. It might help if you provided the compiler's error message.
Arkku
It seems to be this error I get that points at the test1.chatLine.addActionListener(new ActionAdapter();Exception in thread "main" java.lang.NullPointerException
ivor
@ivor: That means something is uninitialised at the time of the call (or `getText()` returns `null`). It would be a compile time error if it had something to do with visibility.
Arkku
+2  A: 

If you can access chatLine in the first place, you can call its (public) methods, including addActionListener. To access chatLine directly, you need to make it public, and if you want to make it specific to the class (as opposed to a different chatLine for each instance of the class), it needs to be static.

Note, however, that it's often desirable to not make variables public. An important reason for having classes and objects in the first place is encapsulation. You might consider hiding the implementation inside the classes by making it private and only providing higher level public methods to access what is needed, e.g. do not expose the "raw" JTextField but rather expose the functionality you use it to provide.

Arkku
+1  A: 

Generally speaking everything in Java is referenced but primitive types.

The so called visibility of objects is another matter:

  • public scoped members are visible to all
  • 'Package Friendly' members (those that have no scope explicitly mentioned) are visible to all abjects belonging to the same package
  • protected scoped members are both 'Package Friendly' and visible to all inheriting class objects
  • Finally, private scoped members are visible only to the object itself [Objects from the same class can view each other's private members (as far as I can recall)]

Now,

  • an inner static class can access its enclosing class's static members.
  • A 'normal' inner class (without the static modifier) can access its enclosing class's static members and enclosing object's instance members - that goes as well to anonymous inner class.

Finally any chain of method/field calls as below is valid (but ugly) as long as no part of the chain 'references' a null:

myObj.getThatObject().somePublicField.doSomthing().activate().someOtherPublicField

One recommendation though is not to declare members as public...

Yaneeve
Though this does not answer the question specifically, I hope you get the point about referencing...
Yaneeve
Cheers, that's helpful
ivor