gpt4 book ai didi

java - 在 Swing 事件中启动线程

转载 作者:太空宇宙 更新时间:2023-11-04 08:14:56 25 4
gpt4 key购买 nike

我正在开发客户端/服务器聊天的客户端应用程序,这是为了学习经验。我的问题是我似乎无法让 socket 和 Swing 同时运行。

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

应该发生的是, Action 监听器应该创建处理通信的新 SocketManager 对象。事件虽然说已连接,但并未运行。当我创建新的 SocketManager 对象并在新线程上运行它时,它会连接并恢复来自服务器的消息,但随后 Swing 会卡住,我必须结束该进程才能将其关闭。

我应该在新的工作线程或其他线程上启动它吗?也许只是因为我累了,但我没有想法。

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

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

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

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

}

最佳答案

好的@Zexanima,您已经为套接字管理器创建了一个 Socket 类。像这样的事情:

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

我希望能提供服务。 :)

关于java - 在 Swing 事件中启动线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10594772/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com