Results 1 to 3 of 3
  1. #1
    wlc
    wlc is offline Member
    Join Date
    Aug 2009
    Posts
    3
    Rep Power
    0

    Default Jtable cells not populating correctly

    I'm creating a table with 2 columns. All cells in the table are editable with combo boxes. I supply a list of possible values for the combo boxes which is specific to the column.

    The table is initialized with 1 row. That row contains NULL values. It will always be the case the the last row int he table contains NULL values. For the purpose of debugging I have replaced the NULL values with strings with values "NULL".

    If either of the cell values in the last row is changed to a non NULL value, a new row is appended which has NULL values. If a user ever selects a row to contain a NULL value for both columns, that row is deleted.

    The table constructor takes an array list of possible values for column 0 called types and column 1 called discr. The possible values for a cell are NULL, the current value of the cell, and all values in types or discr (depending on the column) which are not already used to populate a cell in that column.

    My problem is that whenever I select a value for a cell, the other cell in the same row gets the same value. When selecting a value for a cell, the cell of the other column in the same row should not be affected.

    Does anyone know what could be wrong?

    Here is my SSCCE:

    Java Code:
    import javax.swing.JPanel;
    import javax.swing.JFrame;
    import javax.swing.JTable;
    import javax.swing.DefaultCellEditor;
    import javax.swing.JComboBox;
    import javax.swing.JScrollPane;
    import javax.swing.table.TableColumn;
    import javax.swing.table.DefaultTableModel;
    import java.awt.Dimension;
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.lang.reflect.Array;
    import java.lang.String;
    
    
    import javax.swing.JButton;
    import javax.swing.table.*;
    import javax.swing.event.TableModelEvent;
    import java.awt.BorderLayout;
    
    
    public class SSCCE {
    
    	public static void main(String[] args) {
    		ArrayList descrList;
    		ArrayList typesList;
    		
    		descrList = new ArrayList();
    		descrList.add("Description1");
    		descrList.add("Description2");
    		descrList.add("Description3");
    		descrList.add("Description4");
    		
    		typesList = new ArrayList();
    		typesList.add("Type1");
    		typesList.add("Type2");
    		typesList.add("Type3");
    		typesList.add("Type4");
    		
    		JFrame frame = new JFrame();
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		FoundTable table = new FoundTable(descrList,typesList);
    		
    		JPanel panel = new JPanel(new BorderLayout());
    		panel.add(new JScrollPane(table));
    		
    		panel.setMaximumSize(new Dimension(10000, 300));
    		panel.setPreferredSize(new Dimension(600, 300));
    		panel.setMinimumSize(new Dimension(1, 300));
    		
    		frame.add(panel);
    		frame.pack();
            frame.setVisible(true);
    	}
    
    }
    	
    class CellEditorModel {
    
    	private final int COLNUM = 2;
    	private ArrayList<TableCellEditor[]> CERows;
    	  
    	public CellEditorModel()
    	  {
    		  CERows = new ArrayList();
    	  }
    
    
    	 public void addEditorForCell(int row, TableCellEditor e0, TableCellEditor e1 )
    	 {
    		TableCellEditor[] rowData = new TableCellEditor[2];
    		if (row < CERows.size()) {
    			rowData[0] = e0;
    			rowData[1] = e1;
    			CERows.set(row,rowData);
    		}
    	 }	 
    	 public void addRow(TableCellEditor e0, TableCellEditor e1 ) {
    		TableCellEditor[] rowData = new TableCellEditor[2];
    		rowData[0] = e0;
    		rowData[1] = e1;
    		CERows.add(rowData);
    	 }	 
    	 public void addRow() {
    		TableCellEditor[] rowData = new TableCellEditor[2];
    		rowData[0] = null;
    		rowData[1] = null;
    		CERows.add(rowData);
    	 }
    	 public void removeRow(int row) {
    		if (row < CERows.size()) CERows.remove(row);
    	 }
    	 public TableCellEditor getEditor(int row, int col)
    	{
    		TableCellEditor[] rowData;
    		if ((row < CERows.size()) && (col < COLNUM)) {
    			rowData = CERows.get(row);
    			return rowData[col];
    		} else return null;
    	}
    
    }
    
    class CETable extends JTable {
         protected CellEditorModel cm;
    
         public CETable()
         {
             super();
             cm = null;
         }
    
    
         public CETable(int rows, int cols)
         {
             super(rows,cols);
             cm = null;
         }
    
    
         public TableCellEditor getCellEditor(int row, int col)
         {
    
             TableCellEditor tmpEditor = null;
            if (cm!=null) {
    
                 tmpEditor = cm.getEditor(row, col);
    		}
             if (tmpEditor!=null) {
    
                 return tmpEditor;
    		}
            return super.getCellEditor(row,col);
    	 }
    }
    
    class MyComboBoxEditor extends DefaultCellEditor {
        public MyComboBoxEditor(ArrayList arrList) {
            super(new JComboBox(arrList.toArray(new String[0])));
        }
    }
    
    class FoundTable extends CETable {
    	/*the table model of this table is called dataModel*/
    	protected ArrayList internalTypes;
    	protected ArrayList internalDiscr;
    	protected DefaultTableModel dTM;
    	protected boolean readyToEdit;
    		
    	public FoundTable(ArrayList discr, ArrayList types) {
    		super();
    
    		dTM = new DefaultTableModel();
    		/*dTM.setColumnCount(2);*/
    		this.setModel(dTM);
    		
    		/*Columns*/
    		TableColumn tC = new TableColumn();
    		tC.setHeaderValue("Types");
    		this.addColumn(tC);
    		dTM.addColumn(tC);
    		
    		tC = new TableColumn();
    		tC.setHeaderValue("Discr");
    		this.addColumn(tC);
    		dTM.addColumn(tC);
    
    		dTM.addRow(new Object[]{"NULL", "NULL"});
    
    
    		internalTypes = (ArrayList) types.clone();
    		internalDiscr = (ArrayList) discr.clone();
    		if (internalTypes.get(0) != "NULL") internalTypes.add(0,"NULL");
    		if (internalDiscr.get(0) != "NULL") internalDiscr.add(0,"NULL");
    		
    		cm = new CellEditorModel();
    		cm.addRow(new MyComboBoxEditor(internalTypes),new MyComboBoxEditor(internalDiscr));
    		
    		readyToEdit = true;
    
    	}
    	
    	public void tableChanged(TableModelEvent e) {
    
    		ArrayList selTypes = new ArrayList();
    		ArrayList selDiscr = new ArrayList();
    		int i, j, numRows, changedRow;
    		String col0Val, col1Val;
    		boolean rowChangedToNull = false;
    		/* proceed if the table has been changed and we are not in the contructor method*/
    		if (e.getType() == TableModelEvent.UPDATE && readyToEdit) {
    			System.out.println("table updated");
    			numRows = this.getRowCount();
    			changedRow = e.getFirstRow();
    			/* Iterate through all rows and record the values already used in each column of the 
    			   table. Also determine if the altered row has "NULL" in both columns*/
    			for(i = 0;i < numRows;i++) {
    				col0Val = (String) this.getValueAt(i,0);
    				col1Val = (String) this.getValueAt(i,1);
    				System.out.println(i + ", " + col0Val + ", " + col1Val);
    				if (col0Val != "NULL") selTypes.add(col0Val);
    				if (col1Val != "NULL") selDiscr.add(col1Val);
    				if (col0Val == "NULL" && col1Val == "NULL" && i == changedRow)
    					rowChangedToNull = true;
    			}
    			
    			if (rowChangedToNull && changedRow < (numRows - 1)) {
    				dTM.removeRow(changedRow);
    				numRows--;
    
    				cm.removeRow(changedRow);
    				this.revalidate();
    			} else if (!rowChangedToNull && changedRow == (numRows - 1)) {
    				System.out.println("Should add a null row");
    				dTM.addRow(new Object[]{"NULL", "NULL"});
    
    				cm.addRow();
    				this.revalidate();
    			}
    
    			/*iterate through all rows reset the combobox selection lists.*/
    			ArrayList diffType = selDiff(internalTypes,selTypes);
    			ArrayList diffDisc = selDiff(internalDiscr,selDiscr);
    			ArrayList newSelT, newSelD;
    			for (i = 0;i < dataModel.getRowCount();i++) {
    				newSelT = selCombine(diffType,dataModel.getValueAt(i,0));
    				newSelD = selCombine(diffDisc,dataModel.getValueAt(i,1));
    				cm.addEditorForCell(i, new MyComboBoxEditor(newSelT),
    										new MyComboBoxEditor(newSelD));
    			}
    
    		}
    	}
    	
    	private ArrayList selCombine(ArrayList arr, Object selected){
    		ArrayList returnArr;
    		if (arr.contains(selected)) return arr;
    		returnArr = (ArrayList) arr.clone();
    		returnArr.add(selected);
    		return returnArr;
    	}
    	
    	private ArrayList selDiff(ArrayList origArr, ArrayList subArr) {
    		ArrayList diff = new ArrayList();
    		String temp;
    		Iterator iter = origArr.iterator();
    		while (iter.hasNext()) {
    			temp = (String) iter.next();
    			if (!subArr.contains(temp)) diff.add(temp);
    		}
    		return diff;
    	}
    	
    }

  2. #2
    camickr is offline Senior Member
    Join Date
    Jul 2009
    Posts
    1,234
    Rep Power
    7

    Default

    A couple of problems.

    First, JTable implements the tableChanged(...) method. So you should be adding a super.tableChanged(e) as the first statement to make sure you ge the default behaviour.

    Secondly, you are creating the columns incorrectly:

    Java Code:
    /*Columns*/
    TableColumn tC = new TableColumn();
    tC.setHeaderValue("Types");
    this.addColumn(tC);
    dTM.addColumn(tC);
    		
    tC = new TableColumn();
    tC.setHeaderValue("Discr");
    this.addColumn(tC);
    dTM.addColumn(tC);
    When you create a TableColumn you need to specify which column in the model this column represents. The default is column 0, it doesn't matter which column in the view you change the data for column 0 is always updated in the model. You need to specify the column number when you create the TableColumn.

    However, the easier approach is to create the column via the TableModel and you won't have to worry about this:

    Java Code:
    dTM.addColumn("Types");
    dTM.addColumn("Discr");

  3. #3
    wlc
    wlc is offline Member
    Join Date
    Aug 2009
    Posts
    3
    Rep Power
    0

    Default

    Thank you so much for the help. It's working properly now.

Similar Threads

  1. Add datas to cells of JTable ???
    By bilgohan in forum AWT / Swing
    Replies: 5
    Last Post: 02-22-2010, 09:56 AM
  2. Coloring JTable cells
    By ProgrammingPup in forum Advanced Java
    Replies: 2
    Last Post: 11-04-2009, 10:57 PM
  3. Populating a JTable
    By toymachiner62 in forum New To Java
    Replies: 2
    Last Post: 10-13-2009, 05:56 AM
  4. How to merge cells of JTable
    By nehaa in forum AWT / Swing
    Replies: 1
    Last Post: 05-19-2009, 01:07 PM
  5. Getting objects from JTable Cells.
    By girigl in forum AWT / Swing
    Replies: 3
    Last Post: 12-24-2008, 10:46 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •