ArrayIndexOutOfBoundsException when making a recursive JTable call

I apologize in advance for the length of this post, but I gave a fairly detailed description of the design and implementation of my program.

Background

Currently, I am engaged in a group (there are 2 of us), programming a project for the third year of computer science at the university. The purpose of this program is to essentially use a spreadsheet program to represent the data of an XML file, where each XML file is a historical record.

Design:

Each record (row) in the spreadsheet corresponds to one XML file, and the columns of the record correspond to elements in the XML file. We deal with repeating elements (i.e. Elements with the same tag) by setting the cell element to a button, which when clicked opens another table that contains a list of all elements with repeated names (for the corresponding file). Child elements are handled in the same way, if the element ha is children, then the corresponding cell in the XML file contains a button that, when clicked, opens a spreadsheet containing all the children of this element.

Implementation:

The implementation of our system is written in Java. Our main class (name SpreadSheetGUI) extends the JFrame to which we add JTable (using the standard table model). We have three different cell visualizers: one for when the cell has only text, one for when the cell has a button, and the other when we have text and a button in the cell. When a button is clicked to open a new table (for child elements or duplicate element names), we make a recursive call to our spreadsheet constructor, which will then create our sub-spreadsheet. The renderers are added in the following order: if the cell corresponds to an element with a tag that is used more than once, the button is added to the cell, otherwise, if the cell corresponds to the element with child nodes, we add both text and the cell, and if the cell has only text, we add text to this cell.

GUI Designer as such

/** * Parameterised constructor * @param dataVector - Vector of vectors of objects that represent the cell values * @param columnNames - The vector of objects that represent the column names */ @SuppressWarnings("unchecked") public SpreadSheetGUI(Vector<Vector<LevelElementT>> dataVector, Vector<String> columnNames, boolean hasRepeatedColumns, boolean initialFrame) { this.hasRepeatedColumns = hasRepeatedColumns; this.initialFrame = initialFrame; if (initialFrame) populateTable(dataVector, columnNames); else if (!hasRepeatedColumns) populateTable((Vector<Vector<LevelElementT>>)findRepeatedColumns(dataVector).get(0), (Vector<String>)findRepeatedColumns(dataVector).get(1)); else populateTable(dataVector, columnNames); //Get repeated column names and add to repeated column hashmap //parseElements(dataVector); } 

where the populateTable method initializes the table model. And, as I said, we have three different renderers and editors for our cells and two renderers have buttons in them that, when clicked, create a new table (i.e. we call our spreadsheet constructor), for example, in our the single cell editor has the following code

  public Object getCellEditorValue() { if (isPushed) { //will have the child elements of the current cell element Vector<Vector<LevelElementT>> children = new Vector<Vector<LevelElementT>>(); children.add(new Vector<LevelElementT>()); List<Element> tempChildren = elements.get(row).get(column).getChildren(); for (Element child : tempChildren) children.get(0).add(new LevelElementT(child)); //creates our subspreadsheet new Thread(new SpreadSheetGUI(children, new Vector<String>(), false, false)).start(); } isPushed = false; return new String(bLabel); } 

LevelElementT is just a class that we created that extends the element (found in the JDOM2 package) that overrides the toString method.

Problem:

As I mentioned earlier, we created a set of renderings to handle adding buttons to cells, but it seems that when a β€œchild” table is created, the renderings try to display cells that are outside the borders, according to the child tables, the number of rows and columns and exception exclusion of the array index from the limits.

More specifically, errors occur in the following code snippet taken from the populateTable () method. I initialize the JTable with an instance of defaultTableModel and configure the methods to determine the renderer of each component

  table = new JTable(tableModel) { private static final long serialVersionUID = 1L; public TableCellRenderer getCellRenderer(int row, int column) { //System.out.println(elements.get(row).get(column).getChildren().size()); if (column == 0) { Class<? extends Object> cellClass = getValueAt(row, column).getClass(); return getDefaultRenderer(cellClass); } else if(repeatedColumns.containsKey(table.getColumnModel().getColumn(column).getIdentifier() + " " + elements.get(row).get(0).getText())) return getDefaultRenderer(JButton.class); else if(!elements.get(row).get(column).getChildren().isEmpty()) return getDefaultRenderer(JPanel.class); else return getDefaultRenderer(JTextArea.class); } public TableCellEditor getCellEditor(int row, int column) { if (column == 0) { Class<? extends Object> cellClass = getValueAt(row, column).getClass(); return getDefaultEditor(cellClass); } else if(repeatedColumns.containsKey(table.getColumnModel().getColumn(column).getIdentifier() + " " + elements.get(row).get(0).getText())) return getDefaultEditor(JButton.class); else if(!elements.get(row).get(column).getChildren().isEmpty()) return getDefaultEditor(JPanel.class); else return getDefaultEditor(JTextArea.class); } }; 

Errors are generated in if statements (depending on the button pressed), and this is definitely not due to elements (two-dimensional vector levelElements) or repeatColumns (hash table with a row as a key and a vector of elements as a value).


I guess the problem is that we are making a recursive call to our table constructor. A friend also suggested that this problem might be caused by the default table model, should I create a custom table model?

I did not include my code because it is quite long (only about 2000 lines), but I am ready to give it on request. I tricked my brains with this, and I was completely unable to find the threads associated with this problem.

+4
source share
2 answers

Since the code is not provided, I just assume:

  • a recursive call may cause this if it does not return correctly. We do not know what you are doing for sure ...

  • this phenomenon can also be caused by the random passage of parent table cells into the renderer, rather than a child.

I would debug them. But, again, without code fragments, I would say that it is really difficult to answer.

Hope this helps. :)

+2
source

new SpreadSheetGUI(children, new Vector<String>(), false, false) is suspicious (only a guess), since subsequently a new vector is usually not available.

There is no .get(row).get(column) for index checks. Especially if each line has enough lines.

The DefaultTableModel value is sufficient.

The vector, although thread safe, is quite old; makes a better impression of using List / ArrayList, with concurrency: CopyOnWriteArrayList .

XML table models and tree table models already exist. I do not know about your programming requirements.

Stack tracing, breakpoints, debugging, IDEs should help. The NetBeans integrated environment is simple, the extended Eclipse environment is wider.

0
source

Source: https://habr.com/ru/post/1435106/


All Articles