Hi!

I have a problem with the array of JTextField components. So, the code is shown below and it can be successfully compiled:

txtAdminTextFields = new JTextField[nrOfCols];

...

        tableAttributes.getColumnModel().addColumnModelListener(new TableColumnModelListener() {
        public void columnMarginChanged(ChangeEvent e) {
            for (int i=0; i < nrOfColsFin; i++) {
               txtAdminTextFields[i] = new JTextField();
               txtAdminTextFields[i].setPreferredSize(new Dimension(tableAttributes.getColumn(dbColName[i]).getPreferredWidth(),txtAdminTextFields[i].getPreferredSize().height));
            }
        }
        public void columnAdded(TableColumnModelEvent e) {}
        public void columnRemoved(TableColumnModelEvent e) {}
        public void columnMoved(TableColumnModelEvent e) {}
        public void columnSelectionChanged(ListSelectionEvent e) {}
        });

...

// THE ERROR MESSAGE OCCURS AFTER EXECUTING THE CODE BELOW!
// "Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException"
        for (int i=0; i < nrOfColsFin; i++) {
            if (i != nrOfColsFin) {
               attrPan.add(txtAdminTextFields[i]);
            } else if (i == nrOfColsFin) {
               attrPan.add(txtAdminTextFields[i], "wrap");
            }
        }

Please, help me to solve the problem.

Where is nrOfColsFin defined?

It is defined in the same procedure:

...

        int nrOfCols = 0;
        if (tabType == 1) {
...
             nrOfCols = 5;
        } else if (tabType == 2) {
...
            nrOfCols = 4;
        }

...

final int nrOfColsFin = nrOfCols;

System.out.println shows that nrOfColsFin is equal to 5.

Where is nrOfColsFin defined?

What is the stack trace when you run this (It will tell you the line it is failing on)? A NPE happens when something hasn't been initialized, so the other cause in your code could be that attrPan hasn't been initialized.

The problem occurs with lines 22-28. I checked it with System.out.println...

Hmm... attrPan is initialised:

private JPanel attrPan = new JPanel(new MigLayout("wrap", "grow, fill"));

Well, the full error message is:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
        at SystClasses.Form.createAdminTable(Form.java:480)
        at SystClasses.Form.createAdminRightPanel(Form.java:371)
        at SystClasses.Form.createBase(Form.java:189)
        at SystClasses.Form.access$000(Form.java:44)
        at SystClasses.Form$2.actionPerformed(Form.java:143)
        at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
        at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
        at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
        at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
        at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
        at java.awt.Component.processMouseEvent(Component.java:6267)
        at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
        at java.awt.Component.processEvent(Component.java:6032)
        at java.awt.Container.processEvent(Container.java:2041)
        at java.awt.Component.dispatchEventImpl(Component.java:4630)
        at java.awt.Container.dispatchEventImpl(Container.java:2099)
        at java.awt.Component.dispatchEvent(Component.java:4460)
        at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4577)
        at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4238)
        at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168)
        at java.awt.Container.dispatchEventImpl(Container.java:2085)
        at java.awt.Window.dispatchEventImpl(Window.java:2478)
        at java.awt.Component.dispatchEvent(Component.java:4460)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

Are you sure that columnMarginChanged in your TableColumnModelListener has actually been called before it drops thru into the problem code - or is txtAdminTextFields initialised somewhere else?

Maybe the problem is with attrPan.add(txtAdminTextFields); I am not sure but perhaps I must write something like attrPan.add(txtAdminTextFields.getComponent());??

Well, I've just inserted System.out.println in different places of the code, and I've noticed that the code with 'TableColumnModelListener' is executed successfully.

Are you sure that columnMarginChanged in your TableColumnModelListener has actually been called before it drops thru into the problem code - or is txtAdminTextFields initialised somewhere else?

the code with 'TableColumnModelListener' is executed successfully.

Do you mean the code where the listener is added or do you actually mean that columnMarginChanged has been executed. Have you put a print inside the columnMarginChanged method?

Ok I am no way near as experianced as yourselves with Java, however somthing I am interested in is the dynamic creation of the JTextFields that you are performing. I have done this before in c# and do not see where you are naming the control. In C# each control that is added requires a specific name else an exception is thrown.

Feel free to slap me round the head with a wet kipper if I am way off the mark here.

If you do not have to name it is it because of the table you are creating?

I would fire up a debugger for this. Put 2 breakpoints in the code, one in the for loop and one in the columnMarginChanged event. See which breakpoint is hit first, then in the for loop (the one that throws the NPE) set through line by line and inspect each variable. That should tell you what is null.

Ups, you are right. I've inserted the println inside the ColumnMarginChanged and it has been not executed:

tableAttributes.getColumnModel().addColumnModelListener(new TableColumnModelListener() {
        public void columnMarginChanged(ChangeEvent e) {
            for (int i=0; i < nrOfColsFin; i++) {
               txtAdminTextFields[i] = new JTextField();
               txtAdminTextFields[i].setPreferredSize(new Dimension(tableAttributes.getColumn(dbColName[i]).getPreferredWidth(),txtAdminTextFields[i].getPreferredSize().height));
               System.out.println("Ok");
            }
        }

So, how could I make this code executable?

Do you mean the code where the listener is added or do you actually mean that columnMarginChanged has been executed. Have you put a print inside the columnMarginChanged method?

Suggest you think about extracting that code into an ordinary method then calling it (1) somewhere in your initialisation and (2) in the columnMarginChanged method

Thank you all! Now it works perfectly:

for (int i=0; i < nrOfColsFin; i++) {
               txtAdminTextFields[i] = new JTextField();
        }

        tableAttributes.getColumnModel().addColumnModelListener(new TableColumnModelListener() {
        public void columnMarginChanged(ChangeEvent e) {
            for (int i=0; i < nrOfColsFin; i++) {
               txtAdminTextFields[i].setPreferredSize(new Dimension(tableAttributes.getColumn(dbColName[i]).getPreferredWidth(),txtAdminTextFields[i].getPreferredSize().height));               
            }
        }

Great! Mark this as solved?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.