Java 在Swing事件中启动线程

Java 在Swing事件中启动线程,java,multithreading,swing,sockets,client-server,Java,Multithreading,Swing,Sockets,Client Server,我正在开发客户机/服务器聊天的客户端应用程序,以获得学习经验。我的问题是,我似乎无法让插座和秋千同时运行 我想说的是,当用户打开JOpionsPane并输入主机名和端口号时,单击OK,然后它们就连接好了。当套接字信息被硬编码时,它工作得很好,但现在我正在尝试获取用户对它的输入 我们要做的是,action listener应该创建处理通信的新SocketManager对象。事件虽然它说它已连接,但它不会运行。当我创建新的SocketManager对象并在新线程上运行它时,它会连接并恢复来自服务器的

我正在开发客户机/服务器聊天的客户端应用程序,以获得学习经验。我的问题是,我似乎无法让插座和秋千同时运行

我想说的是,当用户打开JOpionsPane并输入主机名和端口号时,单击OK,然后它们就连接好了。当套接字信息被硬编码时,它工作得很好,但现在我正在尝试获取用户对它的输入

我们要做的是,action listener应该创建处理通信的新SocketManager对象。事件虽然它说它已连接,但它不会运行。当我创建新的SocketManager对象并在新线程上运行它时,它会连接并恢复来自服务器的消息,但随后摆动会冻结,我必须结束进程以关闭它

我应该在一个新的工作线程上启动它吗?也许只是因为我累了,但我没有主意了

编辑 我更新了ActLis.class和SocketManager.class,建议为SocketManager对象“network”添加一个新线程。当我尝试使用“network”时,尽管出于某种原因它返回null

ActLis.clss

Main.class

SocketManager.class

窗口类

package com.client.core;
导入java.awt.*;
导入javax.swing.*;
公共类窗口扩展了JFrame{
私有int屏幕宽度=800;
专用int屏幕高度=600;
专用SocketManager网络;
private JPanel window=new JPanel(new BorderLayout()),
中心=新的JPanel(新的BorderLayout()),
右=新建JPanel(新建BorderLayout()),
display=new JPanel(new BorderLayout()),
chat=new JPanel(),
users=newjpanel(newborderlayout());
私人JTextArea聊天室=新的JTextArea(“欢迎来到聊天室!”,7,50),
ListoUsers=新的JTextArea(“无在线”);
私有JTextField chatWrite=新JTextField(),
userSearch=newjtextfield(10),
用户名=新的JTextField();
私有JScrollPane用户列表=新JScrollPane(ListoUsers),
currentChat=新的JScrollPane(聊天盒);
私有JMenuBar菜单=新建JMenuBar();
私有JMenu文件=新JMenu(“文件”);
private JMenuItem exit=新JMenuItem(“exit”),
ipconnect=new JMenuItem(“连接到IP”);
私有JComponent[]登录=新JComponent[]{newjlabel(“用户名:”),Username};
公共窗口(){
//初始设置
超级(“NAMEHERE-聊天客户端Alpha v0.0.1”);
可设置大小(真);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
设置大小(屏幕宽度、屏幕高度);
//面板
listOfUsers.setLineWrap(true);
ListoUsers.setEditable(false);
显示.背景(颜色.黑色);
setLayout(新的BoxLayout(chat,BoxLayout.Y_轴));
聊天。挫折背景(颜色。蓝色);
用户.背景(颜色.绿色);
//文本字段
addChatArea();
//菜单栏
addMenuBar();
//添加主面板。
添加面板();
//听众
addListeners();
对于(int x=0;x<1;x++){
登录();
}
}
私有void登录(){
showMessageDialog(空,登录,“登录”,JOptionPane.PLAIN_消息);
}
私有void addChatArea(){
chatBox.setEditable(false);
setVerticalScrollBarPolicy(JScrollPane.VERTICAL\u SCROLLBAR\u ALWAYS);
currentChat.setVerticalScrollBarPolicy(JScrollPane.VERTICAL\u SCROLLBAR\u ALWAYS);
添加(userList);
添加(userSearch,BorderLayout.NORTH);
添加(currentChat);
chat.add(chatwite);
setboorder(BorderFactory.createEmptyBorder(1,1,1,1));
}
私有void addMenuBar(){
文件.add(ipconnect);
文件。添加(退出);
菜单.添加(文件);
}
私有的void addPanels(){
对。添加(用户);
添加(显示、边框布局、中心);
添加(聊天室,边界布局,南部);
添加(中心,边框布局,中心);
添加(右侧,BorderLayout.EAST);
窗口。添加(菜单,边框布局。北);
添加(窗口);
}
私有void addListeners(){
addActionListener(新的ActLis(用户名,this));
addActionListener(新的ActLis(chatWrite,this));
username.setActionCommand(“setUsername”);
setActionCommand(“chatWriter”);
ipconnect.addActionListener(新ActLis());
exit.addActionListener(new ActLis());
}
公共网络(SocketManager n){
网络=n;
}
公共void updateChat(字符串s){
chatBox.setText(chatBox.getText()+“\n”+s);
}
}

Ok@Zexanima您已经为套接字管理器创建了一个套接字类。大概是这样的:

public class YouSocketClass {
   static public Socket socket = null;
   static public InputStream in = null;
   static public OutputStream out = null;

   public YouSocketClass() {
     super();
   }
   public static final Socket getConnection(final String ip, final int port, final int timeout) {
    try {
        socket = new Socket(ip, port);
        try {
            socket.setSoTimeout(timeout);
        } catch(SocketException se) {
            log("Server Timeout");
        }
        in = socket.getInputStream();
        out = socket.getOutputStream();
    } catch(ConnectException e) {
        log("Server name or server ip is failed. " + e.getMessage());
        e.printStackTrace();
    } catch(Exception e) {
        log("ERROR Socket: " + e.getMessage() + " " + e.getCause());
        e.printStackTrace();
    }
    return socket;
}

public static void closeConnection() {
    try {
        if(socket != null) {
            if(in != null) {
                if(out != null) {
                    socket.close();
                    in.close();
                    out.close();
                }
            }
        }
    } catch(Exception e2) {
        e2.printStackTrace();
    }
}

private static Object log(Object sms) {
    System.out.println("Test Socket1.0: " + sms);
    return sms;
}
}

我希望这能为你服务。:)

Ok@Zexanima您已经为套接字管理器创建了一个套接字类。大概是这样的:

public class YouSocketClass {
   static public Socket socket = null;
   static public InputStream in = null;
   static public OutputStream out = null;

   public YouSocketClass() {
     super();
   }
   public static final Socket getConnection(final String ip, final int port, final int timeout) {
    try {
        socket = new Socket(ip, port);
        try {
            socket.setSoTimeout(timeout);
        } catch(SocketException se) {
            log("Server Timeout");
        }
        in = socket.getInputStream();
        out = socket.getOutputStream();
    } catch(ConnectException e) {
        log("Server name or server ip is failed. " + e.getMessage());
        e.printStackTrace();
    } catch(Exception e) {
        log("ERROR Socket: " + e.getMessage() + " " + e.getCause());
        e.printStackTrace();
    }
    return socket;
}

public static void closeConnection() {
    try {
        if(socket != null) {
            if(in != null) {
                if(out != null) {
                    socket.close();
                    in.close();
                    out.close();
                }
            }
        }
    } catch(Exception e2) {
        e2.printStackTrace();
    }
}

private static Object log(Object sms) {
    System.out.println("Test Socket1.0: " + sms);
    return sms;
}
}

我希望这能为你服务。:)

我们应该如何帮助这些代码?我唯一能识别的代码是Swing组件的一些更新和显示一些消息对话框。所有其他代码都是我们不知道的自定义代码。也可以查看SwingWorker类。请记住,如果您使用showInputDialog()单击JOptionPane上的“取消”按钮,或者您将从红色的X按钮关闭它,两种方式都会得到一个空值。@Zexanima请记住,SwingComponents只能在EventDispatchThread中访问。SwingWorker使这更容易。在doInBackground()中执行I/O工作,其余的在EDT中执行。但是你也可以用普通的线程和大量的SwingUtilities.invokeLater()来实现这一点,那么我们应该如何帮助编写这段代码呢?我唯一能识别的代码是Swing组件的一些更新和显示一些消息对话框。所有其他代码都是我们不知道的自定义代码。也可以查看一下SwingWorker类。不过,请记住,如果您使用showInputDialog()单击JOptionPane上的“取消”按钮,或者从红色的X按钮关闭它,两种方式都会得到一个空值。@Zexanima还记得SwingComponent吗
package com.client.core;

import java.io.*;
import java.net.*;

public class SocketManager implements Runnable {

private Socket sock;
private PrintWriter output;
private BufferedReader input;
private String hostname;
private int portnumber;
private String message;
private Window gui;

public SocketManager(String ip, int port){
    try{
        hostname = ip;
        portnumber = port;
    }catch(Exception e){
        System.out.println("Client: Socket failed to connect.");
    }
}



public synchronized void send(String data){
    try{
        //System.out.println("Attempting to send: " + data);
        output.println(data);
        output.flush();
        //System.out.println("Message sent.");
    }catch(Exception e){
        System.out.println("Message could not send.");
    }
}

public synchronized void setGUI(Window w){
    gui = w;
}

public synchronized void connect(){
    try{
        sock = new Socket(hostname,portnumber);
    }catch(Exception e){

    }
}

public synchronized Socket getSocket(){
    return sock;
}

public synchronized void setSocket(SocketManager s){
    sock = s.getSocket();
}

public synchronized void close(){
    try{
        sock.close();
    }catch(Exception e){
        System.out.println("Could not close connection.");
    }
    output = null;
    input = null;
    System.gc();
}

public synchronized boolean isConnected(){
    return (sock == null) ? false : (sock.isConnected() && !sock.isClosed());
}

public synchronized void listenStream(){
    try {
        while((message = input.readLine()) != null){        
            System.out.println("Server: " + message);
            gui.updateChat(message);
        }
    } catch (Exception e) {

    }
}

@Override
public void run() {
    try {
        sock = new Socket(hostname,portnumber);
        output = new PrintWriter(sock.getOutputStream(),true);
        input = new BufferedReader(
                new InputStreamReader(sock.getInputStream()));
        while(true){
            listenStream();
        }
    } catch (Exception e) {
        System.out.println("Run method fail. -> SocketManager.run()");
    }finally{
        try {
            sock.close();
        } catch (Exception e) {

        }
    }

}

}
package com.client.core;

import java.awt.*;
import javax.swing.*;


public class Window extends JFrame{

private int screenWidth = 800;
private int screenHeight = 600;

private SocketManager network;

private JPanel window = new JPanel(new BorderLayout()),
        center = new JPanel(new BorderLayout()),
        right = new JPanel(new BorderLayout()),
        display = new JPanel( new BorderLayout()),
        chat = new JPanel(),
        users = new JPanel(new BorderLayout());

private JTextArea chatBox = new JTextArea("Welcome to the chat!", 7,50),
        listOfUsers = new JTextArea("None Online");

private JTextField chatWrite = new JTextField(),
        userSearch = new JTextField(10),
        username = new JTextField();

private JScrollPane userList = new JScrollPane(listOfUsers),
        currentChat = new JScrollPane(chatBox);

private JMenuBar menu = new JMenuBar();

private JMenu file = new JMenu("File");

private JMenuItem exit = new JMenuItem("Exit"),
        ipconnect = new JMenuItem("Connect to IP");
private JComponent[] login = new JComponent[]{new JLabel("Username:"), username};

public Window(){

    //Initial Setup
    super("NAMEHERE - Chat Client Alpha v0.0.1");
    setResizable(true);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setSize(screenWidth,screenHeight);


    //Panels
    listOfUsers.setLineWrap(true);
    listOfUsers.setEditable(false);
    display.setBackground(Color.black);
    chat.setLayout(new BoxLayout(chat, BoxLayout.Y_AXIS));
    chat.setBackground(Color.blue);
    users.setBackground(Color.green);       

    //TextFields
    addChatArea();

    //Menu bar
    addMenuBar();   

    //Adding the main panels. 
    addPanels();

    //Listeners
    addListeners();

    for(int x = 0; x < 1; x++){
        login();
    }
}

private void login(){
    JOptionPane.showMessageDialog(null, login, "Log in", JOptionPane.PLAIN_MESSAGE);
}

private void addChatArea(){
    chatBox.setEditable(false);     
    userList.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
    currentChat.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
    users.add(userList);
    users.add(userSearch, BorderLayout.NORTH);
    chat.add(currentChat);
    chat.add(chatWrite);
    chat.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
}

private void addMenuBar(){
    file.add(ipconnect);
    file.add(exit);
    menu.add(file); 
}

private void addPanels(){
    right.add(users);
    center.add(display, BorderLayout.CENTER);
    center.add(chat, BorderLayout.SOUTH);
    window.add(center, BorderLayout.CENTER);
    window.add(right, BorderLayout.EAST);
    window.add(menu, BorderLayout.NORTH);
    add(window);
}

private void addListeners(){
    username.addActionListener(new ActLis(username, this));
    chatWrite.addActionListener(new ActLis(chatWrite, this));
    username.setActionCommand("setUsername");
    chatWrite.setActionCommand("chatWriter");
    ipconnect.addActionListener(new ActLis());
    exit.addActionListener(new ActLis());
}

public void setNetwork(SocketManager n){
    network = n;
}

public void updateChat(String s){
    chatBox.setText(chatBox.getText() + "\n" + s);
}

}
public class YouSocketClass {
   static public Socket socket = null;
   static public InputStream in = null;
   static public OutputStream out = null;

   public YouSocketClass() {
     super();
   }
   public static final Socket getConnection(final String ip, final int port, final int timeout) {
    try {
        socket = new Socket(ip, port);
        try {
            socket.setSoTimeout(timeout);
        } catch(SocketException se) {
            log("Server Timeout");
        }
        in = socket.getInputStream();
        out = socket.getOutputStream();
    } catch(ConnectException e) {
        log("Server name or server ip is failed. " + e.getMessage());
        e.printStackTrace();
    } catch(Exception e) {
        log("ERROR Socket: " + e.getMessage() + " " + e.getCause());
        e.printStackTrace();
    }
    return socket;
}

public static void closeConnection() {
    try {
        if(socket != null) {
            if(in != null) {
                if(out != null) {
                    socket.close();
                    in.close();
                    out.close();
                }
            }
        }
    } catch(Exception e2) {
        e2.printStackTrace();
    }
}

private static Object log(Object sms) {
    System.out.println("Test Socket1.0: " + sms);
    return sms;
}
}