시나리오는 YouTube의 비디오에서 볼 수 있듯이
http://youtu.be/5OwXqnZ64rE
서버 채팅 창이 메시지를 보내고 클라이언트가 메시지를 가져 와서 표시하는 동안 다른 방식으로 작동하지 않습니다.
다음은 세 가지 클래스입니다.
Server:
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 Natalochka
*/
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("This is the server: " + "\n");
Thread t = new Thread(this);
t.start();
}
if(ae.getSource() == servertalkstogui.getButton()){
String linea = servertalkstogui.getTextField().getText();
servertalkstogui.getTextField().setText("");
this.writeLine(linea);
}
}
@Override
public void run() {
try {
ss = new ServerSocket(9999);
s = ss.accept();
oos = new ObjectOutputStream(s.getOutputStream());
ois = new ObjectInputStream(s.getInputStream());
this.readLine();
} 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();
} catch (InterruptedException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void writeLine(String linea){
try {
oos.writeObject(linea);
servertalkstogui.getAreachat().append("\n I say: " + 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("Client says: " + (String)aux + "\n");
}
}
} catch (IOException | ClassNotFoundException e) {
}
}
public void closeServer() throws IOException{
try {
oos.close();
s.close();
ss.close();
} catch (Exception e) {
e.addSuppressed(e);
}
}
}
CLIENT
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 Natalochka
*/
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) {
// to connect to the socket that the Server opened
if(ae.getSource() == clienttalkstogui.getConnect()){
Thread t = new Thread(this);
t.start();
}
// to obtain and send whatever was typed in the text field
if(ae.getSource() == clienttalkstogui.getButton()){
String linea = clienttalkstogui.getTextField().getText();
this.writeLine(linea);
}
}
@Override
public void run() {
try {
s = new Socket("localhost", 9999);
oos = new ObjectOutputStream(s.getOutputStream());
ois = new ObjectInputStream(s.getInputStream());
clienttalkstogui.getAreachat().append("Conected to port" + "\n");
this.readLine();
} catch (IOException | InterruptedException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void writeLine(String linea){
try {
// to send it to the server
oos.writeObject(linea);
// to have it displayed on the client window too
clienttalkstogui.getAreachat().append(linea);
} catch (IOException e) {
//this.closeClient();
e.getLocalizedMessage();
}
}
public void readLine() throws InterruptedException{
try {
while(true){
Object aux = ois.readObject();
if(aux != null && aux instanceof String){
clienttalkstogui.getAreachat().append("Server says: " + (String)aux + "\n");
}
}
} catch (IOException | ClassNotFoundException e) {
}
}
/*
public void closeClient()
{
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 Natalochka
*/
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) throws InterruptedException {
Gui objeto = new Gui();
}
}
다음은 오류 로그입니다.
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at backend.Server.writeLine(Server.java:80)
at backend.Server.actionPerformed(Server.java:48)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2346)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
at java.awt.Component.processMouseEvent(Component.java:6525)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
at java.awt.Component.processEvent(Component.java:6290)
at java.awt.Container.processEvent(Container.java:2234)
at java.awt.Component.dispatchEventImpl(Component.java:4881)
at java.awt.Container.dispatchEventImpl(Container.java:2292)
at java.awt.Component.dispatchEvent(Component.java:4703)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4898)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4533)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4462)
at java.awt.Container.dispatchEventImpl(Container.java:2278)
at java.awt.Window.dispatchEventImpl(Window.java:2739)
at java.awt.Component.dispatchEvent(Component.java:4703)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:746)
at java.awt.EventQueue.access$400(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:697)
at java.awt.EventQueue$3.run(EventQueue.java:691)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:86)
at java.awt.EventQueue$4.run(EventQueue.java:719)
at java.awt.EventQueue$4.run(EventQueue.java:717)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:716)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
BUILD STOPPED (total time: 58 seconds)
내 전체 답변을 다시 작성합니다.
코드에는 읽기, 디버그 및 오류 생성을 어렵게 만드는 몇 가지 구현 결함이 있습니다.
NullPointerException
두 설정되어 있기 때문에 당신이 얻을이다 ActionListener
온 send
버튼 (대한 리스너 Client
와 리스너에 대한 Server
) :
botonchat.addActionListener(cliente);
botonchat.addActionListener(servidor);
따라서 Server
또는 Client
에 대한 변수 만 설정하더라도 둘 다 호출되고 하나는 일부 null
변수->가 NullPointerException
있습니다.
빠른 (그리고 더티) 수정은 변수 oos
를 사용하기 전에 변수 가 설정 되어 있는지 확인 JTextField
하고 데이터를 읽었을 때만 지우는 것입니다 .
//Server
public void writeLine(String linea)
{
try
{
if (this.oos != null)
{
oos.writeObject(linea);
servertalkstogui.getTextField().setText("");//clearing JTextField
servertalkstogui.getAreachat().append("\n I say: " + linea);
}
}
catch (IOException e)
{
e.getLocalizedMessage();
}
}
//Client
public void writeLine(String linea)
{
try
{
if (this.oos != null)
{
// to send it to the server
oos.writeObject(linea);
clienttalkstogui.getTextField().setText("");//clear the text when it have been read
// to have it displayed on the client window too
clienttalkstogui.getAreachat().append(linea);
}
}
catch (IOException e)
{
// this.closeClient();
e.getLocalizedMessage();
}
}
의 청산 제거 JTextField
의를 actionPerformed
:
//Server
@Override
public void actionPerformed(ActionEvent ae)
{
if (ae.getSource() == servertalkstogui.getCreate()/* .getButton() */)
{
servertalkstogui.getAreachat().append("This is the server: " + "\n");
Thread t = new Thread(this);
t.start();
}
if (ae.getSource() == servertalkstogui.getButton())
{
String linea = servertalkstogui.getTextField().getText();
//servertalkstogui.getTextField().setText("");// do not clear the text here ! You don't know if it will be read yet.
this.writeLine(linea);
}
}
이 작업은 Exception
.
Client
및 의 코드를 분리하는 것이 좋습니다 . Server
둘 다 인스턴스화 할 이유가 없습니다 Gui
.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다