Как jButton1ActionPerformed и jButton2ActionPerformed могут совместно использовать BufferedReader/BufferedWriter?
Ну, я создал программу с использованием сокетов с намерением для IRC-клиента. jButton2 должен отправлять сообщения. JButton1 должен подключиться к IRC-серверу. ли я сделать переменную общедоступной? Каждый раз, когда я пытаюсь сделать его общедоступным, приватным, финальным, статичным или перемещать его, всегда возникают некоторые очень странные проблемы.
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 должен получить и отправить обратно пинг / понг, а также поместить выходной текст в мою 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();
}
}
1 ответ
Вы не можете сделать локальную переменную общедоступной, и вы не должны делать свои поля класса общедоступными, но вы можете передать любой объект другому либо с помощью параметра конструктора, либо с помощью метода установки. Что вам нужно сделать, это передать ваш объект GUI в класс BotListenerThread, а затем вызвать публичные методы GUI изнутри BotListenerThread, заботясь о соблюдении правил многопоточности 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, как часть "Control", изменяет состояние класса Model - класса которая содержит логику вашей программы, и затем Model уведомит всех своих слушателей, что ее состояние было изменено.