繁体   English   中英

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

[英]Updating a textfield using SwingUtilities.invokeLater()

我的程序由一个简单的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(到目前为止,这是我的代码)执行空指针执行

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); 
    }
}); 
}

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

例如:

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);
      }
    }
  );
}

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

您在使用SwingUtilities.invokeLater()上走了正确的路,只需在invokeLater内更新Runnablerun()方法内的文本字段即可。

关于您的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必须为空,其原因是您没有为该变量提供对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;

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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