好吧,我创建了一个使用IRC客户端的套接字程序。 jButton2应该提交消息。 jButton1将连接到IRC服务器。 http://i.stack.imgur.com/SiUO7.png
我有什么办法可以将变量公开?每当我尝试将其公开或私有,最终或静态或移动它时,总会出现一些非常奇怪的问题。
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
try {
String server = jTextField2.getText();
String nick = jTextField4.getText();
String login = jTextField5.getText();
String pass = jTextField6.getText();
String channel = jTextField3.getText();
Socket socket = new Socket(server, 6667);
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream()));
BufferedReader reader = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
writer.write("NICK " + nick + "\r\n");
writer.write("USER " + login + " 0 * Programming Bot" + "\r\n");
if (pass.equals("")) {
} else {
writer.write("nickserv IDENTIFY " + pass + "\r\n");
writer.write("ns set autoop on" + "\r\n");
}
writer.flush();
String line;
while ((line = reader.readLine()) != null) {
jTextArea1.append(line + "\r\n");
// 004 indicates we are logged in
if (line.indexOf("004") >= 0) {
// We are now logged in so we can leave the loop
break;
} else if (line.indexOf("433") >= 0) {
jTextArea1.append("Nickname is already in use.\r\n");
return;
}
}
// Join the channel.
writer.write("JOIN " + channel + "\r\n");
writer.flush();
Thread bl = new Thread(new BotListenerThread(reader, writer, channel));
bl.start();
writer.write("PRIVMSG dema Hello\u00A0There." + "\r\n");
} catch (IOException ex) {
Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex);
}
}
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
// Cannot access reader here
//writer.write("PRIVMSG dema "+jTextField1.getText()+"\r\n");
//writer.flush();
}
然后,BotListenerThread将接收并发送回ping / pong,并将输出文本放入我的textArea中,但是由于它位于不同的文件中,因此我似乎无法找到一种方法来修改jTextArea。提示??
package ambassadorirc;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
public class BotListenerThread implements Runnable // threads implement the runnable interface
{
BufferedReader reader;
BufferedWriter writer;
String channel;
// our constructor requires the reader, writer and channel from the main program
public BotListenerThread(BufferedReader reader, BufferedWriter writer, String channel) {
this.reader = reader;
this.writer = writer;
this.channel = channel;
}
public void run() {
System.out.println("Listener ready...");
String line = "";
// Keep reading lines from the server.
try {
// again we use the infinite loop
while ((line = reader.readLine()) != null)
{
if (line.toLowerCase().startsWith("ping ")) {
// We must respond to PINGs to avoid being disconnected.
writer.write("PONG " + line.substring(5, line.length()) + "\r\n");
// every time you issue a command you MUST flush to send it
writer.flush();
}
// the next lines are a VERY unsafe implementation of an auto-op script ;)
else if (line.contains("myNich") && line.contains("JOIN :"+channel))
{
System.out.println("Opping myNick");
writer.write("MODE "+channel+" +o myNick\r\n");
writer.flush();
}
else {
// print the line received from the server
System.out.println(line);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
最佳答案
您不能公开局部变量,也不应公开您的类字段,但是您可以通过构造函数参数或setter方法将任何对象传递给另一个对象。您需要做的是将您的GUI对象传递到BotListenerThread类中,然后从BotListenerThread内的GUI上调用公共方法,注意遵守Swing的线程化规则,这是我担心的代码问题。
即,更改此:
Thread bl = new Thread(new BotListenerThread(reader, writer, channel));
对此:
// note the difference from the line above
Thread bl = new Thread(new BotListenerThread(reader, writer, channel, this));
并更改BotListenerThread构造函数以接受GUI对象并使用它来设置字段。
public class BotListenerThread implements Runnable {
private BufferedReader reader;
private BufferedWriter writer;
private String channel;
private MyGuiClass gui;
public BotListenerThread(BufferedReader reader, BufferedWriter writer,
String channel, MyGuiClass gui) {
this.reader = reader;
this.writer = writer;
this.channel = channel;
this.gui = gui;
}
// now the gui variable is usable
但是,更好的总体解决方案是使用MVC,并且不要让BotListenerThread与View类(GUI)直接交互,而是让BotListenerThread作为“控件”的一部分来更改Model类的状态-该类保留了程序逻辑,然后让Model通知其所有侦听器其状态已更改。