我正在用Java构建一个小型的聊天室应用程序。
我在这里试图通过静态ClientGUI引用成员发送当前类ClientGUI实例(this)。 ServerApplication类应该通过常规静态getter(在ServerApplication.main中完成)接收当前的clientGUI参考。

经过一些烦人的调试之后,我仍然无法弄清在收到ClientGUI引用后,服务器端引用为何仍为空(getCurrentClientGuiReference()失败)。

(当然-发送的ref在传输到服务器端之前已初始化)。

是否无法通过本地静态ref成员传输当前ref?
也许我错过了什么?

波纹管是相关的代码。

提前致谢。

客户端:

package chatApplication;

import java.net.*;
import java.awt.*;
import java.awt.event.*;
import java.io.BufferedReader;
import java.io.InputStreamReader;

import javax.swing.*;

public class ClientGUI implements StringConsumer, StringProducer
{

//Graphic components
private JFrame frame;
private JButton btConnect,btSend;

private JTextField tfText, tfServerName, tfPort, tfNickName;
private JPanel north,south,center;
ActionListener listener;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

JLabel mainLable = new JLabel();

//Utilities and connection components
private ConnectionProxy consumer = null;
private ConnectionProxy producer = null;
private ClientDescriptor clientDescriptor = null;

//Connection creation switch
private boolean isConnection = false;

//Client details meant for ClientDescriptor
static private String nickname = "Noname";
static private String serverAddress = "127.0.0.1";
static private String port = "1300";
static private ClientGUI currentClientGuiReference = null;

public ClientGUI()
{
    frame = new JFrame("Chit & Chat");
    listener = new ActionListener()
    {
        public void actionPerformed(ActionEvent event)
        {
            if (event.getSource() == btConnect)
            {

                if (isConnection == false)
                {
                    ClientGUI.nickname = tfNickName.getText();
                    ClientGUI.serverAddress = tfServerName.getText();
                    ClientGUI.port = tfPort.getText();
                    ClientGUI.currentClientGuiReference = ClientGUI.this;

                    clientDescriptor = new ClientDescriptor(nickname, serverAddress, port, currentClientGuiReference); // Identical though NOT related to serverapplication's clientdescriptor
                    consumer = new ConnectionProxy(clientDescriptor, ClientGUI.this);

                    //Connecting client consumer as a producer
                    ClientGUI.this.addConsumer(consumer);

                    //Temporary text
                    mainLable.setText("Client consumer/producer thread is connected and running!");
                }

            }

            if (event.getSource() == btSend)
            {
                String outGoingMessageToChat = tfText.getText();
                producer.consume(outGoingMessageToChat); //sending outgoing msg to prducer.consume -->  writeutf
            }

        }
    };

    btConnect = new JButton ("Connect to chat");
    btSend = new JButton ("Send Message");
    btConnect.addActionListener(listener);
    btSend.addActionListener(listener);

    tfText = new JTextField(50);
    tfPort = new JTextField(10);
    tfServerName = new JTextField(20);
    tfNickName = new JTextField(10);
    tfServerName.setText("127.0.0.1");
    tfPort.setText("1300");
    tfNickName.setText("Nickname");

    north = new JPanel();
    south = new JPanel();
    center = new JPanel();
    north.setBackground(Color.blue);
    south.setBackground(Color.gray);
    center.setBackground(Color.white);

    south.add(tfText);
    south.add(btSend);
    north.add(tfNickName,BorderLayout.WEST);
    north.add(tfServerName);
    north.add(tfPort);
    north.add(btConnect,BorderLayout.WEST);


    frame.addWindowListener(new WindowAdapter()
    {
        public void windowClosing (WindowEvent event)
        {
            ClientGUI.this.removeConsumer(clientDescriptor);
            frame.setVisible(false);
            frame.dispose();
            System.exit(0);
        }
    }
    );

    frame.add(north,BorderLayout.NORTH);
    frame.add(center,BorderLayout.CENTER);
    frame.add(south,BorderLayout.SOUTH);
}

public void go()
{
    ClientGUI.currentClientGuiReference = ClientGUI.this;
    frame.setSize(700,700);
    frame.setVisible(true);
    mainLable.setText("Hey! " +
            "Please enter a nickname, Server Address and a port in the text fields above" +
            " and press 'Connect to chat'");
    center.add(mainLable);
    frame.add(center, BorderLayout.WEST);
    if (isConnection == true)
    {
        mainLable.setText("Your details were sent.");
    }
}

@Override
public void addConsumer(StringConsumer consumer)
{
    this.producer = (ConnectionProxy)consumer;

    //All actions completed - client thread producer/consumer is running.
    isConnection = true;
}

@Override
public void removeConsumer(StringConsumer sc)
{
    consumer.removeConsumer(clientDescriptor);
}

@Override
public void consume(String inComingMessageFromChat)
{
    //Temporary code
    mainLable.setText(inComingMessageFromChat);
}


public ConnectionProxy getConsumer()
{
    return consumer;
}

public void setConsumer(ConnectionProxy consumer)
{
    this.consumer = consumer;
}

/**
 * @param args
 */
public static void main(String[] args)
{
    ClientGUI clientGUI = new ClientGUI();
    clientGUI.go();
}

public static String getNickname() {return nickname;}

public static String getServerAddress() {return serverAddress;}

public static String getPort() {return port;}

public static ClientGUI getCurrentClientGuiReference() {return currentClientGuiReference;}


}

服务器端:

package chatApplication;

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

public class ServerApplication {

public static int port = 1300;
public static int backlog = 5;

/**
 * @param args
 */
public static void main(String[] args)
{


    //Server side network variables
    ServerSocket serverSocket = null;

    //MessageBoard object
    MessageBoard messageBoard = new MessageBoard();

    //Client side network variables
    Socket clientSocket = null;
    ClientDescriptor clientDescriptor = null;
    ConnectionProxy clientConnectionProxy = null;

    //Client details meant for ClientDescriptor
    String clientNickname = "Noname";
    String clientServerAddress = "127.0.0.1";
    String clientPort = "1300";
    ClientGUI clientCurrentGuiReference = null;


    try //Creating Server
    {
        serverSocket = new ServerSocket(port,backlog); //ServerSocket(int port, int backlog)
    }
    catch(IOException e)
    {
        e.printStackTrace();
    }

    while (true)
    {
        try
        {
            System.out.println("Server is waiting for Client requests...");
            clientSocket = serverSocket.accept(); // A new thread is created for the new client
            System.out.println("Client connection request accepted, creating client connection proxy...");

            clientConnectionProxy = new ConnectionProxy(clientSocket); //connecting client socket to server
            clientConnectionProxy.addConsumer(messageBoard); //Applying specific server system network utilities and connecting proxy to the messageboard

            System.out.println("Requesting Client details from Client side...");

            clientNickname = ClientGUI.getNickname();
            clientServerAddress = ClientGUI.getServerAddress();
            clientPort = ClientGUI.getPort();
            clientCurrentGuiReference = ClientGUI.getCurrentClientGuiReference();

            System.out.println("Creating Client Descriptor...");
            clientDescriptor = new ClientDescriptor(clientNickname, clientServerAddress, clientPort, clientCurrentGuiReference);

            clientDescriptor.addConsumer(messageBoard);

            messageBoard.addConsumer(clientDescriptor);

            clientConnectionProxy.start();//Start client connection's thread running
            System.out.println("Client thread started...");
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
}
}

最佳答案

我认为static doesn't do what you think it does。如果Client和Server分别运行(例如在两个不同的进程和两个不同的JVM中),那么为任何对象分配任何变量的数量将使Client和Server都可以看到相同的值/对象。您必须使用某种方式在流程之间进行通信。

一旦设法将ClientGUI传递到服务器,我怀疑您将能够以所需的方式使用它。 ClientGUI也是一个对象,无法在客户端和服务器之间进行通信。您也必须自己进行管理。

08-05 11:02