Search code examples
javaswingnullpointerexceptionrandomaccessfile

NullPointerException When Writing to a RandomAccessFile


I can write to the random access file directly after I create it but as soon as I try to write from my function then it breaks.

private void openFile()
{
    JFileChooser fileChooser = new JFileChooser();

    fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY );
    int result = fileChooser.showSaveDialog( this );

    // user clicked Cancel button on dialog
    if ( result == JFileChooser.CANCEL_OPTION )
    {
        return;
    }

    File fileName = fileChooser.getSelectedFile();

    if ( fileName == null || fileName.getName().equals( "" ) )
    {
    JOptionPane.showMessageDialog( this,
        "Invalid File Name",
        "Invalid File Name",
        JOptionPane.ERROR_MESSAGE );
    }
    else 
    {
     // Open the file
        try 
        {
            RandomAccessFile output = new RandomAccessFile( fileName, "rw" );
            createRecord();
        }
        catch ( IOException e ) 
        {
            JOptionPane.showMessageDialog( this,
            "File does not exist",
            "Invalid File Name",
            JOptionPane.ERROR_MESSAGE );
        }      
    }
}

private void createRecord()
{
    String firstName = tfdFirst.getText();
    String lastName = tfdLast.getText();
    String emailAddress = tfdEmail.getText();
    String homeAddress = tfdAddress.getText();
    Long phoneNumber = new Long(tfdPhone.getText());
    char gender = tfdGender.getText().charAt(0);

    System.out.println(firstName + lastName + emailAddress + homeAddress + phoneNumber + gender);

    try
    {
        output.seek(0);
        output.writeChar(gender);
        writeString( output, lastName);
        writeString( output, firstName);
        writeString( output, emailAddress);
        writeString( output, homeAddress);
        output.writeLong(phoneNumber);
    }
    catch(IOException ex)
    {
        ex.printStackTrace();
    }
}

Sorry for the wall of code, but those are the two offending functions. The first tries to open a RandomAccessFile called output, before calling createRecord() which tries to write user input from a JFrame to the file. If I put a simple writeInt() function in the place of createRecord() then it works okay but once createRecord() is called it's as if output never existed.

I've been working at this for hours to no avail, so if someone could help find a solution I would be very grateful.

Edit: Stack Trace as requested. (Warning, very long...)

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at good_gals_customer_app.NewCustomerUI.createRecord(NewCustomerUI.java:298)
at good_gals_customer_app.NewCustomerUI.openFile(NewCustomerUI.java:273)
at good_gals_customer_app.NewCustomerUI.butCreateRecordActionPerformed(NewCustomerUI.java:186)
at good_gals_customer_app.NewCustomerUI.access$100(NewCustomerUI.java:21)
at good_gals_customer_app.NewCustomerUI$2.actionPerformed(NewCustomerUI.java:87)
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:6527)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
at java.awt.Component.processEvent(Component.java:6292)
at java.awt.Container.processEvent(Container.java:2234)
at java.awt.Component.dispatchEventImpl(Component.java:4883)
at java.awt.Container.dispatchEventImpl(Container.java:2292)
at java.awt.Component.dispatchEvent(Component.java:4705)
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:4705)
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)

Solution

  • You have, what appears to be, a shadowing problem...

    You've created a local variable output in openFile...

    RandomAccessFile output = new RandomAccessFile( fileName, "rw" );
    

    But are access, what appears to be an instance variable in createRecord...

    output.seek(0);
    

    In all likelihood, the instance variable is null...

    Normally, I would suggest removing the redeclaration and using the instance field, but in the this, I think you should get rid of the instance field and pass a reference of the RandomAccessFile to the createRecord method

    You're also not managing your resources, remember if you open, you must close it...

    try (RandomAccessFile output = new RandomAccessFile( fileName, "rw" ))
    {
        createRecord(output);
    }
    catch ( IOException e ) 
    {
        JOptionPane.showMessageDialog( this,
        "File does not exist",
        "Invalid File Name",
        JOptionPane.ERROR_MESSAGE );
    }      
    

    Take a look at The try-with-resources Statement for more details