1

So my problem is that for some reason my AttributeSet is null and I'm not sure how to fix this.

public class MyDocumentFilter extends DocumentFilter {

//TODO FIX THIS, as IS NULL FOR SOME REASON

@Override
public void replace(FilterBypass fb, int i, int o, String s, AttributeSet set) throws BadLocationException{
    for(int n = s.length(); n > 0; n--){
        char c = s.charAt(n - 1);
        System.out.println(set);
        if(Character.isAlphabetic(c) || c == ' '){
            super.replace(fb, i, o, String.valueOf(c), set);
        }else{
            JOptionPane.showMessageDialog(null, "Error: Type field must not contain numbers and should be longer than 1 character");
        }
    }
}

@Override
public void remove(FilterBypass fb, int i, int o) throws  BadLocationException{
    super.remove(fb, i, o);
}

public void insertString(FilterBypass fb, int i, String s, AttributeSet set) throws BadLocationException{
    super.insertString(fb, i, s, set);
}

this is my code, which I had based off of another answer on stackoverflow.(jTextField accept only alphabet and white space)

I could have sworn this worked properly the other day, and when I gave my program test data today it started giving me NullPointerExceptions. I'm completely lost as to why my AttributeSet is null, can someone help?

Edit1: Okay now I'm not completely sure that it's my AttributeSet that's null. I'm also not sure if it's the .replace() method that's the source of the NPE. There is another class where I initialize all my swing components and if I delete out typeField.setText(null) (typeField is the name of the jTextArea), the program doesn't throw NPE anymore. Now I'm even more baffled.

3 Answers3

0

You are not printing the char it should be System.out.println(c); not System.out.println(set);

Edit: if you call a method of a null object it will throw a NullPointerException. Check if it is null before calling a method.

Edit 1: This test case doesn't throw a NullPointerException. Something else could be causing the problem.

import javax.swing.*;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;
import java.awt.event.ActionEvent;

class Test {
public static String input = null;

private Test() {
    initComponents();
}

public static void main(String[] args) {
    SwingUtilities.invokeLater(Test::new);
}

private void initComponents() {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JTextField jtf = new JTextField();
    ((AbstractDocument) jtf.getDocument()).setDocumentFilter(new MyDocumentFilter());

    frame.add(jtf);

    jtf.addActionListener(new AbstractAction() {
        @Override
        public void actionPerformed(ActionEvent e) {
            input = jtf.getText();
            System.out.println(input);
            }
        });

        frame.pack();
        frame.setVisible(true);
    }
}

class MyDocumentFilter extends DocumentFilter {
    @Override
    public void replace(FilterBypass fb, int i, int o, String s, AttributeSet set) throws BadLocationException{
        for (int n = s.length(); n > 0; n--) {
            char c = s.charAt(n - 1);
            if (Character.isAlphabetic(c) || c == ' ') {
                super.replace(fb, i, o, String.valueOf(c), set);
            } else {
                JOptionPane.showMessageDialog(null, "Error: Type field must not contain numbers and should be longer than 1 character");
            }
        }
    }

@Override
public void remove(FilterBypass fb, int i, int o) throws  BadLocationException {
    super.remove(fb, i, o);
}

public void insertString(FilterBypass fb, int i, String s, AttributeSet set) throws BadLocationException {
    super.insertString(fb, i, s, set);
}
}

Edit 2: Hacky solution to clear the text field

jtf.addActionListener(new AbstractAction() {
        @Override
        public void actionPerformed(ActionEvent e) {
            try {
                jtf.setText(" "); 

                //Simulated backspace to delete space
                Robot robot = new Robot();
                int backspace = KeyEvent.VK_BACK_SPACE;
                robot.keyPress(backspace);
                robot.keyRelease(backspace);
            } catch (AWTException ex) {
                ex.printStackTrace();
            }
        }
    });
Dr. Confused
  • 76
  • 1
  • 6
  • Hi, thanks for replying. I printed out set to make sure whether or not it was really set that was null. I deleted that line and it's still giving me an NPE. Do you have any more ideas why it may be null? – Dominic Henley Oct 31 '19 at 07:06
  • Post the test case giving you the NPE @DominicHenley – Dr. Confused Oct 31 '19 at 07:28
  • Sorry, the test case I gave was from my program's GUI. I'll just explain it to the best of my ability. Basically my GUI accepts user input and there is one field where I want to limit it to only whitespace or alpha characters. If a number is inputted into the field, it will display a jOptionPane message that tells them to not input numbers. The jOptionPane works however when I write in a letter and press enter (which sends a query to my database to add a record), it will throw an NPE that is referenced in the for loop in my MyDocumentFilter class. – Dominic Henley Oct 31 '19 at 08:26
  • That's weird something else could be producing the problem. @DominicHenley try testing the document filter component independently. I appended a test case. – Dr. Confused Oct 31 '19 at 09:00
  • Okay this is getting really weird. I'm completely at a loss. While trying to fix this, I noticed that this NPE doesn't actually stop my program from executing a query to my database. It only stops my text fields from being set to null value. Despite throwing the NPE, the database actually gets updated. This tells me that my Database class actually gets passed proper arguments... which makes things all the more weird... – Dominic Henley Oct 31 '19 at 12:20
  • So it works? If it does then just surround the code in a try-catch or just try to find the culprit. @DominicHenley – Dr. Confused Nov 01 '19 at 01:13
  • It works, just not properly. I'm pretty sure the .setText() method is throwing an NPE. Is it even possible for .setText() to even throw an NPE? – Dominic Henley Nov 01 '19 at 01:30
  • If it's not initialized it could yes. @DominicHenley – Dr. Confused Nov 01 '19 at 01:58
  • I see. I used your test case to check for this NPE by calling jtf.setText(null). It also returned an NPE. However you can clearly see that jtf was initialized. What may be the cause then? I suspect it's the same reason I get an NPE in my program. – Dominic Henley Nov 01 '19 at 02:12
  • Doing .setText(" ") doesn't throw an NPE and the program works fine too. It just throws an NPE when I pass null to .setText(). – Dominic Henley Nov 01 '19 at 02:27
  • After `JTextField jtf = new JTextField()` I did `jtf.setText(null)` and did not experience a NPE. Um... maybe there is something wrong with your current Java version? Try migrating the project to the current Java 12? I'm at a loss for words. @DominicHenley – Dr. Confused Nov 01 '19 at 02:35
  • Hmm. I don't believe so. I have other jTextFields that i call .setText(null) on that doesn't throw an NPE. It's only the last field, which is the typeField that throws this error. – Dominic Henley Nov 01 '19 at 02:39
  • Post that java class for me to have a more solid understanding of the problem @DominicHenley – Dr. Confused Nov 01 '19 at 02:45
  • I added a (Hacky) modification to the `ActionEvent` of the `JTextField` that clears the field. When I set the `JTextField` to `null` in the `ActionEvent` it gave me a NPE. @DominicHenley – Dr. Confused Nov 01 '19 at 03:19
0

It's probably because you print set instead of char c. You should look into the error stack trace to see what line exception is thrown and try to figure out what object in that line cause the exception.

Trong Hoang
  • 86
  • 1
  • 11
  • The NPE is thrown on the for loop actually, I'm not really sure why. Any more advice would be gladly appreciated... thanks... – Dominic Henley Oct 31 '19 at 07:07
  • @DominicHenley what does the trace look like – Trong Hoang Oct 31 '19 at 07:28
  • Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException at GUI.Formatters.MyDocumentFilter.replace(MyDocumentFilter.java:17) that's the error that was thrown. Line 17 is the for loop. – Dominic Henley Oct 31 '19 at 08:24
  • since there is only one method call `s.length()` in line 17, I suspect it is the cause. Check whether the input String `s` is null or not. – Trong Hoang Oct 31 '19 at 08:34
  • I checked for the value of String s by printing out the value of the s every time a character is typed. Sure enough it did show the proper values. At this point I'm pretty sure that AttributeSet is what's null. – Dominic Henley Oct 31 '19 at 12:22
  • By the way, what value of set do you get if you print out the value of AttributeSet? I tried using your test case to see if I could just initialize set and pass it to the replace() method but when I tried printing out the value in the test case it still says null. – Dominic Henley Oct 31 '19 at 12:27
0

The set that is being passed to this method is most likely null.

user11809641
  • 815
  • 1
  • 11
  • 22
  • Yes, I realise that the set being passed is null. I'm trying to discern the reason behind that because it throws an NPE whenever set is null. – Dominic Henley Oct 31 '19 at 08:28
  • Where is the `replace` method being called from? – user11809641 Oct 31 '19 at 17:14
  • It's called every time the user inputs something in the jTextField which is in my GUI. – Dominic Henley Nov 01 '19 at 00:44
  • OK and how does the `set` get its data? The `replace` method does not seem to be doing anything with the `set`. – user11809641 Nov 01 '19 at 00:55
  • Also it would help if you can post your stack trace as that will show you exactly what line of what Class is throwing the null pointer exception – user11809641 Nov 01 '19 at 00:59
  • I'm not exactly sure what the replace method does with the set. The documentation for Document Filter only states that AttributeSet may be null if the inputed text has no Attributes. The three methods in my MyDocumentFilter class are inherited from a superclass. I've posted my stacktrace in a different comment above. – Dominic Henley Nov 01 '19 at 01:24