3

I'm new to Java and I've hit a brick wall. I want to access GUI components (that have been created in one class) from another class. I am creating a new GUI class from one class, like so;

GUI gui = new GUI();

and I can access the components in that class, but when I go to a different class I cant. I really just need to access the JTextAreas to update their content. Could someone point me in the right direction please, any help is greatly appreciated.

GUI Class:

public class GUI {

    JFrame frame = new JFrame("Server");        
    ...
    JTextArea textAreaClients = new JTextArea(20, 1);  
    JTextArea textAreaEvents = new JTextArea(8, 1);

    public GUI()
    {
        frame.setLayout(new FlowLayout(FlowLayout.LEADING, 5, 3));     
        ...
        frame.setVisible(true);
    }
}
Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
horHAY
  • 788
  • 2
  • 10
  • 23
  • How about passing the required objects (maybe in a list or something) to the class that needs to access them (through that class' constructor)? – Stefan Apr 03 '14 at 09:36

5 Answers5

7

First respect encapsulation rules. Make your fields private. Next you want to have getters for the fields you need to access.

public class GUI {
    private JTextField field = new JTextField();

    public GUI() {
        // pass this instance of GUI to other class
        SomeListener listener = new SomeListener(GUI.this);
    }

    public JTextField getTextField() {
        return field;
    }
}

Then you'll want to pass your GUI to whatever class needs to access the text field. Say an ActionListener class. Use constructor injection (or "pass reference") for the passing of the GUI class. When you do this, the GUI being referenced in the SomeListener is the same one, and you don't ever create a new one (which will not reference the same instance you need).

public class SomeListener implements ActionListener {
    private GUI gui;
    private JTextField field;

    public SomeListener(GUI gui) {
        this.gui = gui;
        this.field = gui.getTextField();
    }
}

Though the above may work, it may be unnecesary. First think about what exactly it is you want to do with the text field. If some some action that can be performed in the GUI class, but you just need to access something in the class to perform it, you could just implement an interface with a method that needs to perform something. Something like this

public interface Performable {
    public void someMethod();
}

public class GUI implements Performable {
    private JTextField field = ..

    public GUI() {
        SomeListener listener = new SomeListener(GUI.this);
    }

    @Override
    public void someMethod() {
         field.setText("Hello");
    }
}

public class SomeListener implements ActionListener {
    private Performable perf;

    public SomeListener(Performable perf) {
        this.perf = perf;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        perf.someMethod();
    }
}
Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
  • you've successfully confused me! I want to access the textarea to append the text inside, thats its. – horHAY Apr 03 '14 at 09:49
  • Well you haven't exactly pointed out where you want to access it _from_. So I made a case up. What's happening is that you pass the current instance of `GUI` (`GUI.this`) to whatever the _other_ class is. In my case, it's `SomeListener`. And you can access the text field by using the getter method I supplied. You can see the constructor of `SomeListener`, it takes in an instance of `GUI`, it is not creating a new one, but just _referencing_ the same GUI – Paul Samsotha Apr 03 '14 at 09:51
  • The second case is just another option. If you don't really need to access the method, but can just call a method to manipulate the text field. I tried to make the code as easy as possible to understand. – Paul Samsotha Apr 03 '14 at 09:54
  • I am creating the GUI in a class named Server-Start and I also want to access it from a class called Server. – horHAY Apr 03 '14 at 09:54
  • And where is `Server` created? Inside `Server-Start`? – Paul Samsotha Apr 03 '14 at 09:55
  • Yes inside Server-Start – horHAY Apr 03 '14 at 09:55
  • Great. So alter the constructor of `Server` to look like my `SomeListener` constructor, that takes in a `GUI` parameter. When you instantiate `Server`, pass the instance of `GUI` to it. `GUI gui = new GUI(); Server server = new Server(gui);`. Get it – Paul Samsotha Apr 03 '14 at 09:57
  • @horHAY So if your `Server` class looks somewhat similar to my `SomeListener` class, you should have no problem referencing the text field from the GUI class, inside the `Server` class. – Paul Samsotha Apr 03 '14 at 10:00
  • @peeskillet Thank you very much, works fine. Thank you also tony_craft, trashgod & stefan for helping. – horHAY Apr 03 '14 at 10:03
3

The best option to access that text areas is creating a get method for them. Something like this:

public JTextArea getTextAreaClients(){
    return this.textAreaClients;
}

And the same for the other one.So to access it from another class:

GUI gui = new GUI();
gui.getTextAreaClients();

Anyway you will need a reference for the gui object at any class in which you want to use it, or a reference of an object from the class in which you create it.

EDIT ---------------------------------------

To get the text area from GUI to Server you could do something like this inside of Create-Server.

GUI gui = new GUI();
Server server = new Server();

server.setTextAreaClients(gui.getTextAreaClients());

For this you should include a JTextArea field inside of Server and the setTextAreaClients method that will look like this:

JTextArea clients;

public void setTextAreaClients(JTextArea clients){
    this.clients = clients;
}

So in this way you will have a reference to the JTextArea from gui.

Tony_craft
  • 213
  • 1
  • 10
  • That creates a new instance of `GUI`, so you would be accessing the wrong instance. The solution is viable if you were to pass the current instance of `GUI` to the class that needs to access components of `GUI`. – Stefan Apr 03 '14 at 09:37
  • @Tony_craft How would I go about referencing? I'm still getting errors when I try to access the gui using "gui. " – horHAY Apr 03 '14 at 09:43
  • Could you post the class from which you are trying to access to "gui" or at least the part in which you are doing it. Also include a post of the error you are getting – Tony_craft Apr 03 '14 at 09:45
3

Several approaches are possible:

  • The identifier gui is a reference to your GUI instance. You can pass gui to whatever class needs it, as long as you respect the event dispatch thread. Add public accessor methods to GUI as required.

  • Declarations such as JTextArea textAreaClients have package-private accessibility. They can be referenced form other classes in the same package.

  • Arrange for your text areas to receive events from another class using a PropertyChangeListener, as shown here.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
1

here i add a simple solution hope it works good,

Form A

controls

Textfield : txtusername

    FormB fb = new FormB();
    fb.loginreset(txtusername); //only textfield name no other attributes

Form B
to access FormA's control

 public void ResetTextbox(JTextField jf)
 {
     jf.setText(null); // or you can set or get any text
 }
0

There is actually no need to use a class that implements ActionListener.

It works without, what might be easier to implement:

public class SomeActionListener {

private Gui gui;
private JButton button1;

    public SomeActionListener(Gui gui){

        this.gui  = gui;
        this.button1 = gui.getButton();
        this.button1.addActionListener(l -> System.out.println("one"));
    }

}

and then, like others have elaborated before me in this topic:

public class GUI {
    private JButton button = new JButton();

    public GUI() {
        // pass this instance of GUI to other class
        SomeActionListener listener = new SomeActionListener(GUI.this);
    }

    public JButton getButton() {
        return button;
    }
}
rainer
  • 3,295
  • 5
  • 34
  • 50