简体   繁体   English

在Swing事件中启动线程

[英]Starting a thread in a Swing event

I'm working on the client side application of the client/server chat I'm doing for learning experience. 我正在为学习经验而进行的客户端/服务器聊天的客户端应用程序上工作。 My problem is I can't seem to get the socket and swing,both to run at the same time. 我的问题是我似乎无法同时运行套接字和摆动。

What I want to is, when the user opens a JOpionsPane and enters the hostname and port number, clicks okay, then they are connected. 我想要的是,当用户打开一个JOpionsPane并输入主机名和端口号时,单击“确定”,然后将它们连接起来。 When the socket information was hardcoded it worked fine, but now I'm trying to get the users input for it. 当套接字信息被硬编码时,它可以正常工作,但是现在我正试图让用户输入它。

What's meant to happen is, action listener is supposed to create the new SocketManager object that handles communication. 这意味着要发生的是,动作侦听器应该创建新的处理通讯的SocketManager对象。 Event though it says it's connected, it doesn't run. 事件,尽管它说已连接,但未运行。 When I create the new SocketManager object and run it on a new thread it connects and revives messages form the server, but then the swings freezes and I have to end the process to shut it down. 当我创建新的SocketManager对象并在新线程上运行它时,它将连接并恢复服务器中的消息,但是随后的动作停止了,我必须结束将其关闭的过程。

Should I start it on a new worker thread or something? 我应该在新的工作程序线程上启动它还是其他东西? Maybe it's just because I'm tired, but I'm out of ideas. 也许只是因为我累了,但我没有主意。

EDIT I updated my ActLis.class and SocketManager.class with the suggestion of adding a new thread for my SocketManager object 'network'. 编辑我更新了ActLis.class和SocketManager.class,并建议为SocketManager对象“网络”添加新线程。 When I try and use 'network' though it returns null for some reason. 当我尝试使用“网络”时,尽管出于某种原因它返回null。

ActLis.clss ActLis.clss

package com.client.core;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;

public class ActLis implements ActionListener {

private Main main = new Main();;
private JTextField ipadress = new JTextField(),
        portnumber = new JTextField(),
        actionField;

private String username;

final JComponent[] ipinp = new JComponent[]{new JLabel("Enter Hostname (IP Adress): "),
        ipadress,
        new JLabel("Enter Port number: "), portnumber};
private SocketManager network;
private Window win;

public ActLis(){

}

public ActLis(JTextField t, Window w){
    actionField = t;
    win = w;

}

@Override
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();


if(cmd == "Exit"){
    System.exit(0);
} else if(cmd == "Connect to IP"){
    try{
        JOptionPane.showMessageDialog(null, ipinp, "Connect to IP", JOptionPane.PLAIN_MESSAGE);
        if(network != null){
            network.close();
        }
        network = new SocketManager(ipadress.getText(),Integer.parseInt(portnumber.getText()));
        network.setGUI(win);
        Thread t = new Thread(network);
        t.start();
        JOptionPane.showMessageDialog(null, "Connected to chat host successfully!","Connected", JOptionPane.INFORMATION_MESSAGE);
    }catch(Exception ee){
        JOptionPane.showMessageDialog(null, "Could not connect. Check IP adress or internet connection","Error - Could not connect", JOptionPane.ERROR_MESSAGE);
        ee.printStackTrace();
    }

} else if (cmd == "chatWriter"){

    if( actionField.getText() != ""){   
        try{
            network.send(actionField.getText());
            win.updateChat(actionField.getText());
            actionField.setText("");
            actionField.requestFocus();
        }catch(Exception ex){
            JOptionPane.showMessageDialog(null, "You are not connected to a host. (File -> Connect to IP)","Error - Not Connected", JOptionPane.ERROR_MESSAGE);
            ex.printStackTrace();
        }

    }

} else if (cmd == "setUsername"){
    username = actionField.getText();
    network.send("USERNAME:" + username);


}


}
}

Main.class 主类

package com.client.core;

import javax.swing.JFrame;

public class Main extends JFrame{

private SocketManager network;

public static void main(String[] args){     
    Main main = new Main();
    main.run();

}

private void run(){
    Window win = new Window();
    win.setVisible(true);
}
}

SocketManager.class SocketManager.class

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) {

        }
    }

}

}

Window.class Window.class

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);
}

}

Ok @Zexanima you have create a Socket class for socket manager. OK @Zexanima,您已经为套接字管理器创建了一个Socket类。 Something like this: 像这样:

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;
}
}

I hope that serve. 希望能为您服务。 :) :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM