我创建了一个简短的java聊天应用。 3个类:GUI,服务器和客户端。
gui有自己的吸气剂,以便与其他类别的物体交谈。
当我尝试创建套接字时,它首先向我弹出防火墙,说它已阻止某个应用尝试在我的计算机上打开一个端口,好吧,我点击了“允许应用”,我甚至还明确地说它在防火墙允许的应用程序列表中。现在的问题是,当我点击菜单创建套接字时,它会完全冻结应用程序,除了中止它之外你什么也做不了。
当然,应用程序基于Threads,每次我想创建套接字时,例如当我点击菜单项时
if(ae.getSource() == servertalkstogui.getCreate()){
然后它启动一个在Run方法下运行的Thread。但在那时它冻结了。我不知道我是在无限循环还是什么。此外,我不喜欢在循环中使用“睡眠”,但到目前为止我不知道任何其他替代方案,但最重要的是检测冻结应用程序的错误
package backend;
import frontend.Gui;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author Alvarito
*/
public class Server implements ActionListener, Runnable {
private ServerSocket ss;
private Socket s;
private ObjectOutputStream oos;
private ObjectInputStream ois;
private Gui servertalkstogui;
public Server(Gui in) {
servertalkstogui = in;
}
@Override
public void actionPerformed(ActionEvent ae) {
if (ae.getSource() == servertalkstogui.getCreate()) {
servertalkstogui.getAreachat().append("hola");
System.out.println("creado");
Thread t = new Thread(this);
t.run();
}
if (ae.getSource() == servertalkstogui.getButton()) {
String linea = servertalkstogui.getTextField().getText();
writeLine(linea);
}
}
@Override
public void run() {
try {
ss = new ServerSocket(9999);
s = ss.accept();
oos = new ObjectOutputStream(s.getOutputStream());
ois = new ObjectInputStream(s.getInputStream());
}
catch (IOException e) {
try {
this.closeServer();
}
catch (IOException ex) {
System.out.println("se jodio");
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
e.getLocalizedMessage();
}
}
public void writeLine(String linea) {
try {
oos.writeObject(linea);
servertalkstogui.getAreachat().append(linea);
}
catch (IOException e) {
e.getLocalizedMessage();
}
}
public void readLine() throws InterruptedException {
try {
while (true) {
Object aux = ois.readObject();
if (aux != null && aux instanceof String) {
servertalkstogui.getAreachat().append((String) aux);
}
}
}
catch (IOException | ClassNotFoundException e) {
}
}
public void closeServer() throws IOException {
try {
oos.close();
s.close();
ss.close();
}
catch (Exception e) {
e.addSuppressed(e);
}
}
}
现在是客户端类
package backend;
import frontend.Gui;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author Alvarito
*/
public class Client implements ActionListener, Runnable {
private Socket s;
private ObjectOutputStream oos;
private ObjectInputStream ois;
private Gui clienttalkstogui;
public Client(Gui in) {
clienttalkstogui = in;
}
@Override
public void actionPerformed(ActionEvent ae) {
if (ae.getSource() == clienttalkstogui.getConnect()) {
Thread t = new Thread(this);
t.run();
clienttalkstogui.getAreachat().append("me he conectado");
System.out.println("hola");
}
}
public void writeLine(String linea) {
try {
oos.writeObject(linea);
clienttalkstogui.getAreachat().append(linea);
}
catch (IOException e) {
e.getLocalizedMessage();
}
}
public void readLine() throws InterruptedException {
try {
while (true) {
Object aux = ois.readObject();
if (aux != null && aux instanceof String) {
clienttalkstogui.getAreachat().append((String) aux);
}
}
}
catch (IOException | ClassNotFoundException e) {
}
}
public void run() {
try {
s = new Socket("localhost", 9999);
oos = new ObjectOutputStream(s.getOutputStream());
ois = new ObjectInputStream(s.getInputStream());
}
catch (IOException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void close() {
try {
ois.close();
oos.close();
s.close();
}
catch (Exception e) {
e.getLocalizedMessage();
}
}
}
现在Gui班:
package frontend;
import backend.Client;
import backend.Server;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
/**
*
* @author Alvarito
*/
public class Gui extends JFrame {
private JMenuBar bar;
private JMenu menu;
private JMenuItem connect, create, exit;
private JTextArea areachat;
private JTextField campochat;
private JButton botonchat;
private JScrollPane scroll;
/* WE CREATE INSTANTIATED OBJECTS OF CLASSES INTERACTING WITH THE GUI */
Server servidor = new Server(this);
Client cliente = new Client(this);
/* CREATING THE CONSTRUCTOR */
public Gui() {
super("CHAT WINDOW");
this.setSize(400, 500);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
/* INSTANTIATE THE OBJECTS */
bar = new JMenuBar();
menu = new JMenu("Menu");
connect = new JMenuItem("Conectar");
create = new JMenuItem("Crear");
exit = new JMenuItem("Salir");
areachat = new JTextArea();
campochat = new JTextField(20);
botonchat = new JButton("Send");
scroll = new JScrollPane(areachat);
/* THE BAR IS PLACED IN THE JFRAME WINDOW */
this.setJMenuBar(bar);
/* THE MENU IS ADDED TO THE BAR */
bar.add(menu);
/* THE ITEMS ARE ADDED TO THE MENU */
menu.add(connect);
menu.add(create);
menu.add(exit);
/* MAKE ITEMS LISTEN TO THE EVENT FROM THE CODE CLASSES */
create.addActionListener(servidor);
connect.addActionListener(cliente);
exit.addActionListener(servidor);
exit.addActionListener(cliente);
botonchat.addActionListener(cliente);
botonchat.addActionListener(servidor);
/* CREATING THE LAYOUTS */
/* AREACHAT */
this.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 2;
gbc.gridheight = 1;
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1;
gbc.weighty = 1;
this.add(scroll, gbc);
/* TEXTFIELD */
gbc.gridx = 0;
gbc.gridy = 1;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1;
gbc.weighty = 0;
this.add(campochat, gbc);
/* BOTON */
gbc.gridx = 1;
gbc.gridy = 1;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.weightx = 0;
gbc.weighty = 0;
this.add(botonchat, gbc);
this.setVisible(true);
}
/* CREATING THE GETTERS AND SETTERS */
/* GETTERS */
public JTextArea getAreachat() {
return areachat;
}
public JMenuItem getCreate() {
return create;
}
public JMenuItem getConnect() {
return connect;
}
public JTextField getTextField() {
return campochat;
}
public JButton getButton() {
return botonchat;
}
/* SETTERS */
public static void main(String [] args) {
Gui objeto = new Gui();
}
}
答案 0 :(得分:0)
您应该使用start()而不是run()来启动线程。
调用run()只需调用run方法,而无需启动线程。然后你在ui线程中阻止