Java 静态ObjectOutputStream引用在客户端代码中不起作用

Java 静态ObjectOutputStream引用在客户端代码中不起作用,java,javafx,objectoutputstream,Java,Javafx,Objectoutputstream,制作一个聊天应用程序,我最近将它从Swing移植到JavaFX。我遇到了使用ObjectOutputStream引用的问题 在Client.java文件中,底部的toServer引用返回null。我认为将toServer设置为静态将允许我访问代码中任何位置的指针。只是不知道我做错了什么 我收到java.lang.NullPointerException 位于Client.sendMessageToServer(Client.java:130) 如果您有任何意见,我将不胜感激,谢谢

制作一个聊天应用程序,我最近将它从Swing移植到JavaFX。我遇到了使用ObjectOutputStream引用的问题

在Client.java文件中,底部的toServer引用返回null。我认为将toServer设置为静态将允许我访问代码中任何位置的指针。只是不知道我做错了什么

我收到java.lang.NullPointerException 位于Client.sendMessageToServer(Client.java:130) 如果您有任何意见,我将不胜感激,谢谢

        Main.java
            import javafx.application.Application;
            import javafx.fxml.FXMLLoader;
            import javafx.scene.Scene;
            import javafx.scene.layout.AnchorPane;
            import javafx.scene.layout.BorderPane;
            import javafx.stage.Stage;

            import java.io.IOException;

            /**
             * @author Sergey
             *         Date: 11/22/13 Time: 9:10 PM
             */
            public class Main extends Application
            {
                private Stage      primaryStage;
                private BorderPane rootLayout;


                /**
                 * this code creates a borderpane with a menubar at the top, the purpose is of
                 * this is to nest the chat client into the borderpane's centre location
                 */
                @Override
                public void start( Stage primaryStage )
                {
                    this.primaryStage = primaryStage;
                    this.primaryStage.setTitle( "chatninjas client" );

                    try
                    {
                        // load the menubar layout from the fxml file
                        FXMLLoader loader = new FXMLLoader( Client.class.getResource( "ninjamenu.fxml" ) );
                        rootLayout = ( BorderPane ) loader.load();
                        Scene scene = new Scene( rootLayout );
                        primaryStage.setScene( scene );
                        primaryStage.show();
                    }
                    catch( Exception ex )
                    {
                        // Exception gets thrown if the fxml file could not be loaded
                        ex.printStackTrace();
                    }

                    showChatRoom();
                }


                /**
                 * Shows the chat room area that will be nested into the centre of the borderpane above
                 */
                public void showChatRoom()
                {
                    try
                    {
                        // Load the fxml file and set into the center of the main layout
                        FXMLLoader loader = new FXMLLoader( Client.class.getResource( "ninja.fxml" ) );
                        AnchorPane overviewPage = ( AnchorPane ) loader.load();
                        rootLayout.setCenter( overviewPage );
                    }
                    catch( IOException e )
                    {
                        // Exception gets thrown if the fxml file could not be loaded
                        e.printStackTrace();
                    }
                }

                /**
                 * Returns the main stage.
                 *
                 * @return
                 */
                public Stage getPrimaryStage()
                {
                    return primaryStage;
                }

                public static void main( String[] args )
                {
                    launch( args );
                }
            }


        NinjaController.java
            import javafx.event.ActionEvent;
            import javafx.event.EventHandler;
            import javafx.fxml.FXML;
            import javafx.fxml.Initializable;
            import javafx.scene.control.Button;
            import javafx.scene.control.TextArea;
            import javafx.scene.control.TextField;

            import java.net.URL;
            import java.util.ResourceBundle;

            public class NinjaController implements Initializable
            {
                @FXML //  fx:id="userOutput"
                static protected TextArea  userOutput = null;

                @FXML //  fx:id="userInput"
                static protected TextField userInput  = null;

                @FXML //  fx:id="sendButton"
                static protected Button    sendButton = null;

                @FXML
                ResourceBundle resources = null;

                @FXML
                URL location = null;

                @Override
                public void initialize( URL fxmlFileLocation, ResourceBundle resources )
                {
                    this.resources = resources;
                    this.location  = fxmlFileLocation;

                    System.out.println( "about to show the resources var: "        + resources );
                    System.out.println( "about to show the fxmlFileLocation var: " + fxmlFileLocation );

                    userInput.setOnAction( new EventHandler<ActionEvent>()
                    {
                        @Override
                        public void handle( javafx.event.ActionEvent actionEvent )
                        {
                            Client.sendMessageToServer( constructMessageFromFXMLuserInput() );
                            userInput.setText( "" );

                            System.out.println( "send via enter key" );

                        }
                    });

                    sendButton.setOnAction( new EventHandler<javafx.event.ActionEvent>()
                    {
                        @Override
                        public void handle( javafx.event.ActionEvent actionEvent )
                        {
                            Client.sendMessageToServer( constructMessageFromFXMLuserInput() );
                            userInput.setText( "" );

                            System.out.println( "sent via send button" );
                        }
                    } );
                }

                /* dont think i need this anymore
                public void onEnter()
                {
                    System.out.println( "user hit enter while mouse was focused in the textfield with this message: " + userInput.getText() );
                }
                */

                // returns a String trimmed of spaces
                public static String retrieveTextFromFXMLuserInput()
                {
                    return userInput.getText().trim();
                }

                // appends the incoming text area (userOut) with an inbound message
                public static void sendMessageToFXMLuserOutput( Message incomingMessage )
                {
                    userOutput.appendText( incomingMessage.getMsgBody() + "\n" );
                }

                public static Message constructMessageFromFXMLuserInput()
                {
                    // if the userInput field is empty, don't even bother sending the message
                    if( retrieveTextFromFXMLuserInput().equals( "" ))
                    {
                        System.out.println( "message is empty, didnt send anything" );
                        return null;
                    }

                    return new Message( retrieveTextFromFXMLuserInput(),
                                        null,    // font entry
                                        null,    // font entry
                                        "bob" /*getUserName()*/ );
                }
            }

        Client.java:

            import java.io.IOException;
            import java.io.ObjectInputStream;
            import java.io.ObjectOutputStream;
            import java.net.Socket;
            import java.util.Date;

            import static java.text.DateFormat.MEDIUM;
            import static java.text.DateFormat.getTimeInstance;

            public class Client
            {
                /*
                    These are the user set preferences, the userName will be set by the user
                    when the Client loads.
                */
                private static String userName;  // this field will be changed when user is prompted for a name
                private static int fontSize = 12;


                // Object IO streams
                private static ObjectOutputStream toServer;
                private ObjectInputStream  fromServer;

                /*
                Plan to update the port selection to use a showInputDialog that will request a user
                specified port and url of the server to connect to.
                Like the other showInputDialogs, this will have a server address and port preset.
                 */
                private static final int port = 4000;

                String  date;
                boolean connected;

                // static Font myFont = new Font( fontType, Font.BOLD, fontSize ); // testing the font functionality // works!

                Message wantToSend;

                public Client() throws IOException
                {
                    String hostname = "localhost";

                    Socket socket = new Socket( hostname, port );

                    // prompt the user for an alias using JOptionPane.showInputDialog
                    userName = "bob"; //getName(); // getName needs to be rewritten, it used the old JFrames approach, needs to use the new css approach

                    toServer   = new ObjectOutputStream( socket.getOutputStream() );
                    fromServer = new ObjectInputStream(  socket.getInputStream() );

                    // send the username to the server for "online list"
                    // ** feature is beta right now **
                    wantToSend = new Message( userName );
                    toServer.writeObject( wantToSend );

                    Message receiveMessage;

                    connected = true;

                    while( connected )
                    {
                        try
                        {
                            // make the date look pretty: 8:54:17 PM
                            date = getTimeInstance( MEDIUM ).format( new Date() );

                            receiveMessage = ( Message ) fromServer.readObject();

                            if( receiveMessage != null )
                            {
                                sendMessageToController( receiveMessage );
                            }
                            else
                            {
                                sendMessageToController( new Message( 1, ">>>  Message from server == null <<< BUGCODE1001" ) );
                            }
                        }
                        catch( ClassNotFoundException e1 )
                        {
                            e1.printStackTrace();
                        }
                    }
                }

                /*                   _     _                                                   _     _
                                    | |   | |                           ___                   | |   | |
                       __ _    ___  | |_  | |_    ___   _ __   ___     ( _ )      ___    ___  | |_  | |_    ___   _ __   ___
                      / _` |  / _ \ | __| | __|  / _ \ | '__| / __|    / _ \/\   / __|  / _ \ | __| | __|  / _ \ | '__| / __|
                     | (_| | |  __/ | |_  | |_  |  __/ | |    \__ \   | (_>  <   \__ \ |  __/ | |_  | |_  |  __/ | |    \__ \
                      \__, |  \___|  \__|  \__|  \___| |_|    |___/    \___/\/   |___/  \___|  \__|  \__|  \___| |_|    |___/
                       __/ |
                      |___/
                */

                /**
                 * Prompt for and return the desired screen name.
                 */


                // need to update this code with nicole's login screen functionality
                /*
                public String getName()
                {
                    // the random generator is for testing purposes, i didn't want to keep having
                    // to type in usernames to test features
                    return ( String ) JOptionPane.showInputDialog(
                            null,
                            "Choose a name:",
                            "Screen name selection",
                            JOptionPane.PLAIN_MESSAGE,
                            null,
                            null,
                            "moose" + ( int ) ( Math.random() * ( 9999 - 1111 ) ) );
                }
                */

                public void sendMessageToController( Message sendThisToController )
                {
                    System.out.println("--sending message to controller");
                    NinjaController.sendMessageToFXMLuserOutput( sendThisToController );
                    System.out.println("--message sent to controller");
                }

                static void sendMessageToServer( Message messageToSend )
                {
                    try
                    {
                        if( ! ( messageToSend.getMsgBody().isEmpty() ) )
                        {
                            // sends wantToSend object to the  server via ObjectOutputStream->OutputStream->Socket
                            toServer.writeObject( messageToSend ); // exception:  java.lang.NullPointerException
//at Client.sendMessageToServer(Client.java:130)
                            print( "message sent to server" );
                            toServer.flush();
                        }
                        else if( messageToSend == null ) // this shouldn't ever happen  BUGCODE1000
                        {
                            print( " >>> wantToSend is null .. this message is a bug  BUGCODE1000 <<< " );
                        }
                        else;
                    }
                    catch( IOException ex )
                    {
                        System.err.println( ex );
                    }

                }

                // basic stdout print because System.out.println( "" )
                public static void print( String printThisMessageToSystemOutPrintln )
                {
                    System.out.println( printThisMessageToSystemOutPrintln );
                }
            }
Main.java
导入javafx.application.application;
导入javafx.fxml.fxmloader;
导入javafx.scene.scene;
导入javafx.scene.layout.ancorpane;
导入javafx.scene.layout.BorderPane;
导入javafx.stage.stage;
导入java.io.IOException;
/**
*@作者谢尔盖
*日期:2013年11月22日时间:晚上9:10
*/
公共类主扩展应用程序
{
私人阶段初级阶段;
私有边界布局;
/**
*这段代码创建了一个顶部带有菜单栏的边框窗格,目的是
*这是为了将聊天客户端嵌套到borderpane的中心位置
*/
@凌驾
公共无效开始(阶段primaryStage)
{
this.primaryStage=primaryStage;
this.primaryStage.setTitle(“聊天忍者客户端”);
尝试
{
//从fxml文件加载菜单栏布局
FXMLLoader=newFXMLLoader(Client.class.getResource(“ninjamenu.fxml”);
rootLayout=(BorderPane)loader.load();
场景=新场景(根布局);
初级阶段。场景(场景);
primaryStage.show();
}
捕获(例外情况除外)
{
//如果无法加载fxml文件,将引发异常
例如printStackTrace();
}
展示室();
}
/**
*显示将嵌套在上方边框窗格中心的聊天室区域
*/
公共聊天室()
{
尝试
{
//加载fxml文件并设置到主布局的中心
FXMLLoader=newFXMLLoader(Client.class.getResource(“ninja.fxml”);
AnchorPane概览页面=(AnchorPane)loader.load();
rootLayout.setCenter(概览页面);
}
捕获(IOE异常)
{
//如果无法加载fxml文件,将引发异常
e、 printStackTrace();
}
}
/**
*返回主阶段。
*
*@返回
*/
公共阶段getPrimaryStage()
{
返回初级阶段;
}
公共静态void main(字符串[]args)
{
发射(args);
}
}
NinjaController.java
导入javafx.event.ActionEvent;
导入javafx.event.EventHandler;
导入javafx.fxml.fxml;
导入javafx.fxml.Initializable;
导入javafx.scene.control.Button;
导入javafx.scene.control.TextArea;
导入javafx.scene.control.TextField;
导入java.net.URL;
导入java.util.ResourceBundle;
公共类NinjaController实现可初始化
{
@FXML//fx:id=“userOutput”
静态受保护的TextArea userOutput=null;
@FXML//fx:id=“userInput”
静态保护的TextField userInput=null;
@FXML//fx:id=“sendButton”
静态保护按钮sendButton=null;
@FXML
ResourceBundle resources=null;
@FXML
URL位置=空;
@凌驾
公共void初始化(URL fxmlFileLocation,ResourceBundle资源)
{
这就是资源=资源;
this.location=fxmlFileLocation;
System.out.println(“即将显示资源变量:“+resources”);
System.out.println(“即将显示fxmlFileLocation变量:”+fxmlFileLocation);
setOnAction(新的EventHandler()
{
@凌驾
公共无效句柄(javafx.event.ActionEvent)
{
sendMessageToServer(constructMessageFromFXMLuserInput());
userInput.setText(“”);
System.out.println(“通过回车键发送”);
}
});
setOnAction(新的EventHandler()
{
@凌驾
公共无效句柄(javafx.event.ActionEvent)
{
sendMessageToServer(constructMessageFromFXMLuserInput());
userInput.setText(“”);
System.out.println(“通过发送按钮发送”);