Java ActionListener调用while循环方法
我添加了一个ActionListener,它创建了一个新的聊天框架,可以从服务器发送和接收消息。这是ActionPerformed()方法中的代码 所以它创建了一个新的聊天框,如果我没有调用chat.chatting()方法,我可以正常地将消息发送到服务器,但无法从服务器接收消息。所以我必须调用这个方法,因为如果服务器确实发送消息,我需要一直监听来自服务器的消息 这是聊天的代码() 这是while循环。 如果我创建聊天框并在主方法中调用此方法,它可以工作,但如果我在ActionListener中创建聊天框,它将被卡住。ActionListener似乎不能有一个完全不结束的while循环 我不知道如何解决这个问题,有没有更好的方法从登录界面创建一个新的聊天界面?正如前面所建议的,在后台线程中运行聊天代码可能是一个好主意-例如使用Java ActionListener调用while循环方法,java,swing,jbutton,chat,actionlistener,Java,Swing,Jbutton,Chat,Actionlistener,我添加了一个ActionListener,它创建了一个新的聊天框架,可以从服务器发送和接收消息。这是ActionPerformed()方法中的代码 所以它创建了一个新的聊天框,如果我没有调用chat.chatting()方法,我可以正常地将消息发送到服务器,但无法从服务器接收消息。所以我必须调用这个方法,因为如果服务器确实发送消息,我需要一直监听来自服务器的消息 这是聊天的代码() 这是while循环。 如果我创建聊天框并在主方法中调用此方法,它可以工作,但如果我在ActionListener中
SwingWorker
(这是专为Swing GUI使用而设计的)。通过对BananaChat
类的一些猜测工作,一个非常简单(单向)的聊天程序可以如下所示:
主要类别:
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
public class Chat {
private int nextPort = 80;
public static void main(final String[] args) {
new Chat().launchGui();
}
private void launchGui() {
final JFrame frame = new JFrame("Stack Overflow: chat with multiple servers");
frame.setBounds(100, 100, 800, 600);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
final JPanel panel = new JPanel();
final JButton startChatButton = new JButton("Start a new chat");
startChatButton.addActionListener(actionEvent -> {
final BananaChat bananaChat = new BananaChat("user name", "password",
"192.0.0.1", String.valueOf(nextPort), "???");
nextPort++;
bananaChat.startChatting();
});
panel.add(startChatButton);
frame.getContentPane().add(panel);
frame.setVisible(true);
}
}
ABananaChat
class:
import java.util.List;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingWorker;
public class BananaChat extends JFrame {
private final String userName;
private final String password;
private final String IP;
private final String port;
private final String status;
private final Random dummyServerMessages;
private final JTextArea messagesTextArea;
public BananaChat(final String userName, final String password, final String IP,
final String port, final String status) {
super("Chat with " + IP + ":" + port);
this.userName = userName;
this.password = password;
this.IP = IP;
this.port = port;
this.status = status;
dummyServerMessages = new Random(123456);
messagesTextArea = new JTextArea();
add(new JScrollPane(messagesTextArea));
setBounds(1000, 100, 400, 200);
setVisible(true);
}
public void startChatting() {
final SwingWorker chatWorker = new SwingWorker<Void, String>() {
@Override
protected Void doInBackground() {
while (!isCancelled()) {
final String message = getMessageFromServer();
publish(message + "\n");
pause(1000);
}
return null;
}
@Override
protected void process(final List<String> messages) {
messages.forEach(messagesTextArea::append);
}
};
chatWorker.execute();
}
// Generate silly random messages. Can be replaced by a call to in.readLine().
private String getMessageFromServer() {
final String message;
if (dummyServerMessages.nextInt(6) < 2)
message = "Hello";
else
message = "Silence";
return message + " from " + userName + "@" + IP + ":" + port;
}
private void pause(final int milliseconds) {
try {
Thread.sleep(milliseconds);
} catch (final InterruptedException e) {
e.printStackTrace();
}
}
public String getPassword() {
return password;
}
public String getStatus() {
return status;
}
}
import java.util.List;
导入java.util.Random;
导入javax.swing.JFrame;
导入javax.swing.JScrollPane;
导入javax.swing.JTextArea;
导入javax.swing.SwingWorker;
公共类BananaChat扩展了JFrame{
私有最终字符串用户名;
私有最终字符串密码;
私有最终字符串IP;
专用最终字符串端口;
私有最终字符串状态;
私有最终随机消息;
私有最终JTextArea消息stextarea;
公共BananaChat(最终字符串用户名、最终字符串密码、最终字符串IP、,
最终字符串端口,最终字符串状态){
超级(“与“+IP+”聊天:“+port”);
this.userName=用户名;
this.password=密码;
this.IP=IP;
this.port=端口;
这个状态=状态;
dummyServerMessages=新随机(123456);
messagesTextArea=newjtextarea();
添加(新的JScrollPane(messagesTextArea));
挫折(1000、100、400、200);
setVisible(真);
}
公共无效起始图案(){
最终SwingWorker chatWorker=新SwingWorker(){
@凌驾
受保护的Void doInBackground(){
while(!iscanceled()){
final String message=getMessageFromServer();
发布(消息+“\n”);
暂停(1000);
}
返回null;
}
@凌驾
受保护的无效进程(最终列表消息){
messages.forEach(messagesTextArea::append);
}
};
chatWorker.execute();
}
//生成愚蠢的随机消息。可由调用in.readLine()替换。
私有字符串getMessageFromServer(){
最终字符串消息;
if(dummyServerMessages.nextInt(6)<2)
message=“你好”;
其他的
message=“沉默”;
从“+用户名+”@“+IP+”:“+端口返回消息+”;
}
专用无效暂停(最终整数毫秒){
试一试{
睡眠(毫秒);
}捕获(最终中断异常e){
e、 printStackTrace();
}
}
公共字符串getPassword(){
返回密码;
}
公共字符串getStatus(){
返回状态;
}
}
1)有关更好的帮助,请尽快发布(最小完整可验证示例)或(短、自包含、正确的示例)。不要在事件分派线程中运行阻塞代码。你需要在后台线程中运行这样的代码——通常这是使用a最方便的。你能为问题添加更多的代码吗,比如BananaChat
类?这将使提出更具体的建议成为可能。
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
public class Chat {
private int nextPort = 80;
public static void main(final String[] args) {
new Chat().launchGui();
}
private void launchGui() {
final JFrame frame = new JFrame("Stack Overflow: chat with multiple servers");
frame.setBounds(100, 100, 800, 600);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
final JPanel panel = new JPanel();
final JButton startChatButton = new JButton("Start a new chat");
startChatButton.addActionListener(actionEvent -> {
final BananaChat bananaChat = new BananaChat("user name", "password",
"192.0.0.1", String.valueOf(nextPort), "???");
nextPort++;
bananaChat.startChatting();
});
panel.add(startChatButton);
frame.getContentPane().add(panel);
frame.setVisible(true);
}
}
import java.util.List;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingWorker;
public class BananaChat extends JFrame {
private final String userName;
private final String password;
private final String IP;
private final String port;
private final String status;
private final Random dummyServerMessages;
private final JTextArea messagesTextArea;
public BananaChat(final String userName, final String password, final String IP,
final String port, final String status) {
super("Chat with " + IP + ":" + port);
this.userName = userName;
this.password = password;
this.IP = IP;
this.port = port;
this.status = status;
dummyServerMessages = new Random(123456);
messagesTextArea = new JTextArea();
add(new JScrollPane(messagesTextArea));
setBounds(1000, 100, 400, 200);
setVisible(true);
}
public void startChatting() {
final SwingWorker chatWorker = new SwingWorker<Void, String>() {
@Override
protected Void doInBackground() {
while (!isCancelled()) {
final String message = getMessageFromServer();
publish(message + "\n");
pause(1000);
}
return null;
}
@Override
protected void process(final List<String> messages) {
messages.forEach(messagesTextArea::append);
}
};
chatWorker.execute();
}
// Generate silly random messages. Can be replaced by a call to in.readLine().
private String getMessageFromServer() {
final String message;
if (dummyServerMessages.nextInt(6) < 2)
message = "Hello";
else
message = "Silence";
return message + " from " + userName + "@" + IP + ":" + port;
}
private void pause(final int milliseconds) {
try {
Thread.sleep(milliseconds);
} catch (final InterruptedException e) {
e.printStackTrace();
}
}
public String getPassword() {
return password;
}
public String getStatus() {
return status;
}
}