1

I want to make a java swing application which is to be used for searching some data(extracted from Hierarchical database through JDBC). For testing purpose, I have made it like this:-

Level-1 : 1, 2, 3 Level-2 : {1.1, 1.2, 1.3}, {2.1, 2.2, 2.3}, {3.1, 3.2, 3.3} Level-3 : {1.1.1, 1.1.2},{1.2.1, 1.2.2}, ..., {3.3.1, 3.3.2}

UI is like this:- Level-1 will be displayed in JComboBox. Level-2 is also a JComboBox but gets populated via ComboBoxModel depends on level-1 selectedIndex. Level-3 I want to display in a JList dependent of level-1 & level-2 as in level-3.

level-1 & level-2 is working fine. But level-3 is giving 'NullPointerException' when I try to initiate level3values attributes.

Here is the code:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Iterator;

public class TestSwing extends JPanel implements Runnable, ActionListener {

    private JComboBox combo1;
    private JComboBox combo2 = new JComboBox();
    private ComboBoxModel[] models ;
    private JList<String> list;
    private DefaultListModel<String>[][] level3values;
    //TODO:add displaying level3, copy method
    public TestSwing(String[] level1candidates, String[][] level2candidates, String[][][] level3candidates){

        this.models = new ComboBoxModel[level1candidates.length];
        this.combo1 = new JComboBox(level1candidates);
        for (int i=0; i<level1candidates.length; i++ )
            models[i] = new DefaultComboBoxModel(level2candidates[i]);
        for (int i=0; i<level1candidates.length; i++) {
            for (int j=0; j<level2candidates[i].length; j++) {
                level3values[i][j] = new DefaultListModel<String>();
                for (int k=0; k<level3candidates[i][j].length; k++) {
                    this.level3values[i][j].addElement(level3candidates[i][j][k]);
                } ;//TODO:DEBUG-how to initiate list model
            }
        }
        combo2.setModel(models[0]);
        this.list = new JList<String>(new String[]{});
        this.add(combo1);
        this.add(combo2);
        this.add(list);
        this.combo1.addActionListener(this);
        this.combo2.addActionListener(this);
    }
    @Override
    public void actionPerformed(ActionEvent e) {

        int i = combo1.getSelectedIndex();
        combo2.setModel(models[i]);
        int j = combo2.getSelectedIndex();
        list.setModel(level3values[i][j]);
    }

    @Override
    public void run() {

        JFrame f = new JFrame("CPBG-Store_Material-Finder");
        f.setSize(400,400);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel controlPane = new JPanel();
        GridLayout gridLayout = new GridLayout(3,2, 10, 10);
        controlPane.setLayout(gridLayout);
        controlPane.add(new JLabel("Level-1"));
        controlPane.add(this.combo1);
        controlPane.add(new JLabel("Level-2"));
        controlPane.add(this.combo2);
        controlPane.add(new JLabel("Level-3"));
        //controlPane.add(new JLabel("Level-4"));
        controlPane.add(this.list);
        f.add(controlPane);
        //f.pack();
        //f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        String[] level1candidates = new String[]{"1", "2", "3"};
        String[][] level2candidates = {new String[]{"1.1", "1.2", "1.3"},
                new String[]{"2.1", "2.2", "2.3"}, new String[]{"3.1", "3.2", "3.3"}};
        String[][][] level3candidates = {
                {new String[]{"1.1.1", "1.1.2"},new String[]{"1.2.1", "1.2.2"}, new String[]{"1.3.1","1.3.2"}},
                {new String[]{"2.1.1", "2.1.2"},new String[]{"2.2.1", "2.2.2"}, new String[]{"2.3.1","2.3.2"}},
                {new String[]{"3.1.1", "3.1.2"},new String[]{"3.2.1", "3.2.2"}, new String[]{"3.3.1","3.3.2"}},
                };
        //creating and showing this application's GUI.
        EventQueue.invokeLater(new TestSwing(level1candidates, level2candidates, level3candidates));
    }
}

Thanks in advance for help for debugging the problem.

In particular comboboxmodel[] is working fine but defaultlistmodel[][] is giving null pointer exception, is there any particular reason?

Here is the working code for two levels:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.Connection;
import java.sql.SQLException;

public class MaterialFinder extends JPanel implements Runnable, ActionListener {

    private JComboBox combo1;
    private JComboBox combo2 = new JComboBox();
    private ComboBoxModel[] models ;

    public MaterialFinder(String[] level1candidates, String[][] level2candidates, String[][][] level3candidates){

        this.models = new ComboBoxModel[level1candidates.length];
        this.combo1 = new JComboBox(level1candidates);
        for (int i=0; i<level1candidates.length; i++ )
            models[i] = new DefaultComboBoxModel(level2candidates[i]);
        combo2.setModel(models[0]);
        this.add(combo1);
        this.add(combo2);
        this.combo1.addActionListener(this);
        this.combo2.addActionListener(this);
    }
    @Override
    public void actionPerformed(ActionEvent e) {

        int i = combo1.getSelectedIndex();
        combo2.setModel(models[i]);
        int j = combo2.getSelectedIndex();

    }

    @Override
    public void run() {

        JFrame f = new JFrame("CPBG-Store_Material-Finder");
        f.setSize(400,400);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        f.add(this);
        //f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {

        JDBCUtilities jdbcUtilities = new JDBCUtilities();
        jdbcUtilities.dbName = "cpbg";
        jdbcUtilities.userName = "root";
        jdbcUtilities.password = "root";
        jdbcUtilities.serverName = "localhost";
        Connection connection = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            System.out.println("Driver Loaded");
            connection = jdbcUtilities.getConnection();
            //TODO:copy SQL code here
        } catch (SQLException se) {

            jdbcUtilities.printSQLException(se);
        } catch (Exception e) {

            e.printStackTrace(System.err);
        } finally {

            jdbcUtilities.closeConnection(connection);
        }
        //TODO:remove the following dummyLevelCandidate
        String[] level1candidates = new String[]{"1", "2", "3"};
        String[][] level2candidates = {new String[]{"1.1", "1.2", "1.3"},
                new String[]{"2.1", "2.2", "2.3"}, new String[]{"3.1", "3.2", "3.3"}};
        String[][][] level3candidates = {
                {new String[]{"1.1.1", "1.1.2"},new String[]{"1.2.1", "1.2.2"}, new String[]{"1.3.1","1.3.2"}},
                {new String[]{"2.1.1", "2.1.2"},new String[]{"2.2.1", "2.2.2"}, new String[]{"2.3.1","2.3.2"}},
                {new String[]{"3.1.1", "3.1.2"},new String[]{"3.2.1", "3.2.2"}, new String[]{"3.3.1","3.3.2"}},
                };
        //creating and showing this application's GUI.
        EventQueue.invokeLater(new MaterialFinder(level1candidates, level2candidates, level3candidates));
    }
}

1 Answers1

2

The problem is in this line:

level3values[i][j] = new DefaultListModel<String>();

since level3values is null. So you should properly initialize it with the proper dimensions as your data would be. So before the nested for loops for initializing the models you should initialize it:

this.level3values = new DefaultListModel[level2candidates.length][level2candidates.length];

** level2candidates.length is just a sample that shows how the problem would be solved.

STaefi
  • 4,297
  • 1
  • 25
  • 43