Results 1 to 8 of 8
  1. #1
    simo_mon is offline Member
    Join Date
    Dec 2008
    Posts
    50
    Rep Power
    0

    Default update jtable with filter

    Hi i am trying to create a customized jtable which updates the view via a jtextfield,

    ie user inputs "tree" in textfield
    and JTable updates to show only rows containing "tree"

    i got this part working, the problem is that when i insert a lag between
    deleteing a row and inserting a row and type in the filter i get an error which i can't trace or catch

    _____________________________error________________ ________
    Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 4
    at javax.swing.DefaultRowSorter.convertRowIndexToMode l(Unknown Source)
    at javax.swing.JTable.convertRowIndexToModel(Unknown Source)
    at javax.swing.JTable.getValueAt(Unknown Source)
    at javax.swing.JTable.prepareRenderer(Unknown Source)
    at javax.swing.plaf.basic.BasicTableUI.paintCell(Unkn own Source)
    at javax.swing.plaf.basic.BasicTableUI.paintCells(Unk nown Source)
    at javax.swing.plaf.basic.BasicTableUI.paint(Unknown Source)
    at javax.swing.plaf.ComponentUI.update(Unknown Source)
    at javax.swing.JComponent.paintComponent(Unknown Source)
    at javax.swing.JComponent.paint(Unknown Source)
    at javax.swing.JComponent.paintChildren(Unknown Source)
    at javax.swing.JComponent.paint(Unknown Source)
    at javax.swing.JViewport.paint(Unknown Source)
    __________________________________________________ ___________

    the code is still doing what its meant to but throwing errors that i can't catch
    or trace

    ive attached the code

    there are 4 classes
    driver -
    1) DriverFilterTableDemo - main
    control -
    2) filterTable - filters a jtable based on Jtextfieldpassed in
    3) JTableFilterControl - has an instance of filterTable and refreshes
    the model passed in
    gui
    4) FilterFrame - has a gui with a Jtable and JTextfield

    the driver code is

    Java Code:
    public static void main(String[] args)
    	{
    		
    		System.out.println(" start of DriverFiterTableDemo");
    		
    		
    		// 1 create a DefaultTableModel
    		DefaultTableModel tempJTableModel = new DefaultTableModel();
    		// 2 load a DefaultTableModel with 2 columns and 3 dummy entries
    		tempJTableModel = getNewModel(30); 
            // get the column headers
    		String [] coulumnHeaders = getColumnHeader(tempJTableModel);
            // create a control add the column headers 
    		JTableFilterControl filterTableControl = new JTableFilterControl(coulumnHeaders);
            // 3 create the gui frame
    		FilterFrame frame = new FilterFrame(filterTableControl.getMainJTable());	
    		// 4 add the filtered control to the gui textFiled 
    	    filterTableControl.addFilterControlToTextField(frame.getFilterTextField());
    		// 5 associate the Jtable from the cintrol to the display
    		frame.addFilteredJTable(filterTableControl.getFilteredTable());
    		// 6 upload new table
    		filterTableControl.replaceMainTableModel(tempJTableModel);
    		
    		/* steps 1-6 == ok
    		 * 
    		 * 
    		 */
    		
    		
    		/*  try a series of insert/delete and model refreshes with a pause to generate the error 
    		 *   
    		 */
    		
    		for(int i =0;i<10;i++)
    		{
    			// remove the first row
    			tempJTableModel.removeRow(0);
    			
    			Vector v = getDummyRowEntry();
    			// add another row 
    			tempJTableModel.addRow(v);
    			// the pause causes the problems ????
    			/*
    			 *  problem when i start interacting with a database !!!!!!!
    			 * 
    			 */
    			pause();
                // refresh the model -> refreshes the gui jtable
        		filterTableControl.replaceMainTableModel(tempJTableModel);
    			
    		}
    
    	}
    	
    	
    
    
    
    	/*********************************** HELPER METHODS *****************************************/
    
    	
    	private static Vector getDummyRowEntry() {
    		Vector v = new Vector();
    		v.add("new first");
    	    v.add("new second  " + getTimeStamp());
    		return v;
    	}
    
    	
    	
    	private static void pause() {
    		try {
    			Thread.sleep(2000);
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		
    	}
    
    	private static DefaultTableModel getNewModel(int numberOfRows) {
    		DefaultTableModel tableNew = new DefaultTableModel();
    	
    		// MUST ADD THE CORRECT NUMBER OF COLUMN HEADERS TO WORK 
    		tableNew.addColumn("first");
    		tableNew.addColumn("second");
    		
    		
    		for(int i =0;i<numberOfRows;i++)
    		{
    			
    			Vector t = new Vector();
    			t.add(Integer.toString(i)+ " first ");
    			t.add(Integer.toString(i) + " second ");
    			tableNew.addRow(t);
    		}
    		
    		
    		
    		return tableNew;
    	}
    
    	public static String [] getColumnHeader(DefaultTableModel tempJTableModel)
    	{
    		
    		String [] columnHeaders = null;
    		if(tempJTableModel!=null)
    		{
    		    columnHeaders = new String[tempJTableModel.getColumnCount()];
    		
    			for(int i =0;i<tempJTableModel.getColumnCount();i++)
    			{
    				System.out.println(" column headers " + tempJTableModel.getColumnName(i));
    			    columnHeaders[i] = tempJTableModel.getColumnName(i);
    			}
    		}
    	
    		return columnHeaders;
    		
    	}
    
    	public static String getTimeStamp()
    	{
    		java.util.Date time = new java.util.Date();
    		return new java.sql.Time(time.getTime()).toString();
    	}
    have been working on this for days .. any help particularly just to catch the error ?? would be very much appreciated
    Attached Files Attached Files

  2. #2
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    25

  3. #3
    simo_mon is offline Member
    Join Date
    Dec 2008
    Posts
    50
    Rep Power
    0

    Default

    thanks very much for the point in the right direction...

    and wow !! single thread EDT = very important and helpful

    reading :)

  4. #4
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    25

    Default

    e.g.,
    Java Code:
    import java.util.Vector;
    import javax.swing.SwingUtilities;
    import javax.swing.table.DefaultTableModel;
    
    public class DriverFiterTableDemo2 {
    
      protected static final long SLEEP_TIME = 2000;
    
      public static void main(String[] args) {
        System.out.println(" start of DriverFiterTableDemo");
        final DefaultTableModel tempJTableModel = getNewModel(30);
        String[] coulumnHeaders = getColumnHeader(tempJTableModel);
        final JTableFilterControl filterTableControl = new JTableFilterControl(coulumnHeaders);
        FilterFrame frame = new FilterFrame(filterTableControl.getMainJTable());
        filterTableControl.addFilterControlToTextField(frame.getFilterTextField());
        frame.addFilteredJTable(filterTableControl.getFilteredTable());
        filterTableControl.replaceMainTableModel(tempJTableModel);
    
        Runnable runnable = new Runnable() {
          private int maxIndex = 10;
    
          public void run() {
            for (int i = 0; i < maxIndex ; i++) {
              SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                  tempJTableModel.removeRow(0);
                  tempJTableModel.addRow(getDummyRowEntry());
                }
              });
              try {
                Thread.sleep(SLEEP_TIME);
              } catch (InterruptedException e) {}
              SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                  filterTableControl.replaceMainTableModel(tempJTableModel);
                }
              });
              
            }
          }
        };
        new Thread(runnable).start();
      }
    
      private static Vector<String> getDummyRowEntry() {
        Vector<String> v = new Vector<String>();
        v.add("new first");
        v.add("new second  " + getTimeStamp());
        return v;
      }
    
      private static DefaultTableModel getNewModel(int numberOfRows) {
        DefaultTableModel tableNew = new DefaultTableModel();
    
        tableNew.addColumn("first");
        tableNew.addColumn("second");
    
        for (int i = 0; i < numberOfRows; i++) {
    
          Vector<String> t = new Vector<String>();
          t.add(Integer.toString(i) + " first ");
          t.add(Integer.toString(i) + " second ");
          tableNew.addRow(t);
        }
    
        return tableNew;
      }
    
      public static String[] getColumnHeader(DefaultTableModel tempJTableModel) {
    
        String[] columnHeaders = null;
        if (tempJTableModel != null) {
          columnHeaders = new String[tempJTableModel.getColumnCount()];
    
          for (int i = 0; i < tempJTableModel.getColumnCount(); i++) {
            System.out.println(" column headers " + tempJTableModel.getColumnName(i));
            columnHeaders[i] = tempJTableModel.getColumnName(i);
          }
        }
    
        return columnHeaders;
    
      }
    
      public static String getTimeStamp() {
        java.util.Date time = new java.util.Date();
        return new java.sql.Time(time.getTime()).toString();
      }
    }

  5. #5
    simo_mon is offline Member
    Join Date
    Dec 2008
    Posts
    50
    Rep Power
    0

    Default

    seriously awesome reply.... thanks :)

    so basically swind edt has one thread.. you can can add and schedule worker threads * by passing in a thread ( implements runnable ) to the swing EDT thread by invokelater - returns straight away invokewait - waits until exectution completes...

    to run complex control you implement a thread every time your model changes and attempts to adjust the corresponding gui..

    its a mechansim to synchronise multiple control objects with the gui single thread...

    pure gold :)

    thanks















    * read elsewhere that you couldn't schedule threads in terms of priority as the jvm schedules ?

  6. #6
    camickr is offline Senior Member
    Join Date
    Jul 2009
    Posts
    1,226
    Rep Power
    6

    Default

    From the Swing tutorial you will also find a section on "How to Use Tables" which contains a working example of how to filter the rows in the table based on the data in a JTextField.

  7. #7
    simo_mon is offline Member
    Join Date
    Dec 2008
    Posts
    50
    Rep Power
    0

    Default

    thanks for the heads up :)

    and yeah that's where i started,

    i made a larger piece of software and i was trying to separate out the classes into a better MVC architecture, as i was shifting control out into separate classes i was getting all sorts of weird behavior.. the filter uses a rowsorter, and i wrote my own getRow() method (ie mouseListener on the jtable) but the problems got worse when i was reloading the tableModel from a database and there was time delay...

    i was getting errors that appeared to be related to the swing stuff and was guessing that it was a synchronisation problem, given other asynch errors ive seen in the past from using threads... but was clueless as to what to do about it... needed to know the Swing EDT structure and methods..

    the code was working and that was what was so frustrating... the model was being replenished as intended and the muck up was happening when i was trying to update the gui... many days.... *sigh*

    thanks for all the help :)

  8. #8
    simo_mon is offline Member
    Join Date
    Dec 2008
    Posts
    50
    Rep Power
    0

    Default

    i was still having problems with the jtable loading up blank

    this is what i ended up doing in the end... for the driver

    Java Code:
    public static void main(String[] args) {
    		System.out.println(" start of DriverFiterTableDemo");
    	    /**
    	     * 	final DefaultTableModel tempJTableModel = getNewModel(30);
    	     *        - final declaration required for use with innerClasses
    	     *        - what's the reference is pointing to can be changed not the object           
    	     */
    	    
    	    final DefaultTableModel tempJTableModel = getNewModel(30);
    	    String[] coulumnHeaders = getColumnHeader(tempJTableModel);
    	    final JTableFilterControl filterTableControl = new JTableFilterControl(coulumnHeaders);
    	    FilterFrame frame = new FilterFrame(filterTableControl.getMainJTable());
    	    filterTableControl.addFilterControlToTextField(frame.getFilterTextField());
    	    frame.addFilteredJTable(filterTableControl.getFilteredTable());
            
    	    filterTableControl.replaceMainTableModel_THREAD_SAFE(tempJTableModel);
    	    final DefaultTableModel newModel = getNewModel(5);
    	    filterTableControl.replaceMainTableModel_THREAD_SAFE(newModel);
    
    	}
    and the new method in the filterTableControl class..

    Java Code:
    public void replaceMainTableModel_THREAD_SAFE(final DefaultTableModel tableNew) {
    			
    		// create a worker thread 
    		Runnable runnable = new Runnable() {
    
                   // overwrite its run method 
    	       public void run() {
    		      
    		    	  //schedule the actual model updates on the SWING Event Dispatch Thread
    		    	  // using invoke later 
    		          SwingUtilities.invokeLater(new Runnable() {
    		            public void run()
    		            {
    	                	clearMainTableModel();
    		            	for(int i =0;i<tableNew.getRowCount();i++)
    		        		{
    		        			Vector<String> v = new Vector<String>();
    		        			//System.out.println(" the i value is " + i );
    		        			try
    		        			{
    		        				for(int j =0;j<mainTableModel.getColumnCount();j++)
    		        				{
    		        					//System.out.println(" the j value is " + j );
    		        					String val = (String) tableNew.getValueAt(i, j);
    		        					//System.out.println(" the val at i " + i + ": and j " + j + ": val ->"  + val);
    		        					v.add(val.trim());
    		        					
    		        					
    		        			}
    		        			
    		        			}
    		        			catch(Exception e)
    		        			{
    		        				
    		        				System.out.println("\n\n\n\n--------->JTableFilterControl:replaceMainTableModel -> " + e.getMessage());
    		        				
    		        			}
    		        			
    		        			mainTableModel.addRow(v);
    		        		}
    		            	
    		            }
    		          });
    				        
    		      }
    		    };
    		    new Thread(runnable).start();
    		
    	}

    , i did some more reading and this is kinda a worker thread implementation ?
    works fine :)
    not sure if it should throw an interruption exception ?

Similar Threads

  1. How to update JTable contents
    By chyrl in forum AWT / Swing
    Replies: 10
    Last Post: 04-17-2010, 05:26 AM
  2. Update JTable data
    By DC200 in forum AWT / Swing
    Replies: 8
    Last Post: 03-30-2010, 10:10 PM
  3. Replies: 0
    Last Post: 02-21-2010, 11:51 AM
  4. Sort and filter in Jtable (java ver 1.5 )
    By itaipee in forum AWT / Swing
    Replies: 3
    Last Post: 04-16-2009, 12:03 PM
  5. Update the GUI in JTable
    By itaipee in forum AWT / Swing
    Replies: 3
    Last Post: 04-12-2009, 12:28 PM

Tags for this Thread

Posting Permissions

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