我的程序包含一个简单的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);
}
});
}
答案 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()
中设置的字符串,并调用该方法来设置文本字段。