使用SwingUtilities.invokeLater()更新文本字段

时间:2012-10-19 13:21:32

标签: java multithreading event-dispatch-thread swingutilities

我的程序包含一个简单的gui和一个扩展线程的类!

我正在尝试学习如何使用SwingUtilities.invokeLater()来使用它来更新我的GUI中的文本字段,但是如何在不使静态的情况下到达我的gui中的文本字段?我是在正确的轨道上还是我到目前为止做错了什么:)?

代码

这是从名为Client的类中获取的,它扩展了线程,这是我想要使用SwingUtilities.invokeLater(Runnable)更新我的GUI

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(这是我目前为止的代码)获取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

    }
}
我的GUI中

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

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

4 个答案:

答案 0 :(得分:2)

您可以通过在包含对invokeLater()的调用的方法中包含最终的局部变量来实现。您可以从runnable对象中访问该变量。

例如:

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

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

答案 1 :(得分:1)

文本字段必须在Client类中声明为实例变量,或者如果它们在另一个类中声明,则必须可以从Client类访问它们。

您使用SwingUtilities.invokeLater()走在正确的轨道上,只需更新run()Runnable的{​​{1}}方法内的文字字段。

答案 2 :(得分:1)

关于你的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
  }
}

这意味着mg必须为null,原因是您没有为此变量提供对GUI的有效引用。要解决此问题,您需要通过方法或构造函数参数传递对显示的GUI的引用。例如,如果通过构造函数,您可以执行:

public class MySocketConnector implements Runnable {
  private MainGui mg;

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

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

  //...
}

编辑1
关于你的评论:

  

我如何将mg改为现在的gui?我目前通过以下代码使用它:private MainGui mg;

这只是声明变量,但它没有初始化它。

答案 3 :(得分:0)

您可以做的一件事是在您的班级中有一个String字段,该字段可以扩展Thread类。 在run()方法中,将该字段设置为您在文本字段中所需的任何值。 然后编写一个方法,返回您在run()中设置的字符串,并调用该方法来设置文本字段。