Updating a textfield using SwingUtilities.invokeLater()

2.5k Views Asked by At

My program consists of a simple gui and a class that extends thread!

i am trying to learn how to use SwingUtilities.invokeLater() in order to use it to update a textfield in my GUI but how do i reach the textfield in my gui without making static? and am i on the right track or have i done something wrong so far:)?

Code

This has been taken from the Class called Client that extends thread this is where i want to update my GUI from using SwingUtilities.invokeLater(Runnable)

public void run(){
    while (socket.isConnected()) {

    if (input.hasNext()) {

        updateTextField();
    }

}
}

private void updateTextField() {
    SwingUtilities.invokeLater(new Runnable() {

        @Override
        public void run() {
  // here i want to update my textfield using txt.setText(input.nextLine());

        }
    });

}

UPDATE (This is my code so far) getting a nullpointer execption

public void run(){
    while (socket.isConnected()) {
            String x = input.next();
            System.out.println(x);
    mg.updateChat(x); // this is the line that gives me the nullexeption

    }
}

in my GUI

public void updateChat(final String input){
SwingUtilities.invokeLater(new Runnable() {

    @Override
    public void run() {
        // TODO Auto-generated method stub
    txtChat.setText(input); 
    }
}); 
}
4

There are 4 best solutions below

3
On BEST ANSWER

You can do it by having a final local variable in the method that contains the call to invokeLater(). You can access that variable from within the runnable object.

For example:

public void run(){
  while (socket.isConnected()) {
    if (input.hasNext()) {
      String nextInput = input.next();
      myGui.updateTextField(nextInput);
    }
  }
}

in your GUI class:

public void updateTextField(final String nextInput) {
  SwingUtilities.invokeLater(
    new Runnable(){
      @Override
      public void run() {
        // assuming a private JTextField variable, myTextField
        myTextField.setText(nextInput);
      }
    }
  );
}
3
On

The textfields must either be declared as instance variables in the Client class or if they are declared in another class, they must be accessible from the Client class.

You are on the right track on using SwingUtilities.invokeLater(), just update the textfields inside the run() method of the Runnable inside the invokeLater.

2
On

One thing you can do is have a String field in your class that extends Thread class. And inside run() method set that field to whatever value you want in your textfield. And then write a method that returns the string that you set inside run() and call that method to set your textfield.

4
On

Regarding your NPE:

public void run() {
  while (socket.isConnected()) {
    String x = input.next();
    System.out.println(x);
    mg.updateChat(x); // this is the line that gives me the nullexeption
  }
}

This means that mg must be null, and the reason for this is that you haven't given this variable a valid reference to the GUI. To solve this, you need to pass in a reference to the displayed GUI via either a method or constructor parameter. For instance, if via a constructor, you could do:

public class MySocketConnector implements Runnable {
  private MainGui mg;

  public MySocketConnector(MainGui mg) {
    this.mg = mg;
  }

  @Override
  public void run() {
    while (socket.isConnected() {
      // ... etc...
    }
  }

  //...
}

Edit 1
Regarding your comment:

How would i change mg to be my current gui? i currently intilize it by the following code: private MainGui mg;

This just declares the variable but it doesn't initialize it.