好吧,我创建了一个使用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通知其所有侦听器其状态已更改。

10-06 09:35