Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 4 of 4

Thread: JTables: How do I adjust row order as I drag columns?

  1. #1
    Junior Member
    Join Date
    Dec 2010
    Posts
    2
    Thanks
    1
    Thanked 0 Times in 0 Posts

    Default JTables: How do I adjust row order as I drag columns?

    Hi folks! I'm trying to develop a JTable that automatically changes the row order when the user drags a column to a new location. The code below generates a 5X5 multiplication table. When the user begins to drag a column, the column model listener sets a boolean to true to indicate that a drag is taking place. When the user releases the mouse, the mouse listener for the table header registers the release, and if a drag was taking place, the table data is supposed to update to accomodate the new column order. I'd like to keep the rows in the same order as the columns so that the diagonal of the table is a diagonal of square numbers. When I drag a column, the rows do change their order to reflect the new column order, but when the table repopulates the data for display, it treats the columns as if they were in the same order that they were in before the drag occurred. I think the problem is related to the JTable's getValueAt function that specifies the column order as the view order, and not the table model order. It seems like this has something to do with the convertColumnIndexToModel(int viewColumnIndex) JTable method. Thanks for any help you can give!

    I've developed a small, runnable example of the behavior I'm seeing. After you run it and it shows the table, try dragging a column to a new location. You'll see the rows change order, but the multiplication results for the columns that just changed positions are wrong for the rows that changed position.

    Here is my code:

    import java.awt.Dimension;
    import java.awt.GridLayout;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.util.Vector;
     
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.event.ChangeEvent;
    import javax.swing.event.ListSelectionEvent;
    import javax.swing.event.TableColumnModelEvent;
    import javax.swing.event.TableColumnModelListener;
    import javax.swing.table.AbstractTableModel;
     
    @SuppressWarnings("serial")
    public class ExpTable extends JPanel
    	{
    	private JTable table;
    	boolean columnDragging;
    	boolean viewStable;
    	public ExpTable()
    		{
    		super(new GridLayout(1,0));
    		final ExpTableModel myModel = new ExpTableModel();
    		table = new JTable(myModel);
    		columnDragging = false;
    		viewStable = false;
    		table.getTableHeader().addMouseListener(new MouseAdapter()
    		{
    		@Override
    		public void mouseReleased(MouseEvent e)
    			{
    			if(columnDragging)
    				{
    				System.out.println("Drag Completed");
    				Vector<Integer> newColumns = new Vector<Integer>();
    				for(int i = 1; i < table.getColumnCount(); i++)
    					{
    					newColumns.add(new Integer(table.getColumnName(i)));
    					}
    				for(int i = 1; i < table.getColumnCount(); i++)
    					{
    					table.getColumnModel().getColumn(i).setHeaderValue(newColumns.get(i - 1));
    					}
    				myModel.repopulateTable(newColumns);
    				table.setModel(myModel);
    				PrintColumnNames();
    				myModel.PrintTableData();
    				}
    			}
    		});
    		table.getColumnModel().addColumnModelListener(new TableColumnModelListener()
    		{
    			@Override
    			public void columnAdded(TableColumnModelEvent e)
    				{}
     
    			@Override
    			public void columnRemoved(TableColumnModelEvent e)
    				{}
     
    			@Override
    			public void columnMoved(TableColumnModelEvent e)
    				{
    				columnDragging = true;
    				}
     
    			@Override
    			public void columnMarginChanged(ChangeEvent e)
    				{}
     
    			@Override
    			public void columnSelectionChanged(ListSelectionEvent e)
    				{}
     
    		});
    		table.setPreferredScrollableViewportSize(new Dimension(500,300));
    		table.setFillsViewportHeight(true);
    		JScrollPane scrollPane = new JScrollPane(table);
    		add(scrollPane);
    		}
     
    	private static void createAndShowGUI()
    		{
    		JFrame frame = new JFrame("Table Experiment");
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		ExpTable newTable = new ExpTable();
    		newTable.setOpaque(true);
    		frame.setContentPane(newTable);
    		frame.pack();
    		frame.setVisible(true);
    		}
     
    	public void PrintColumnNames()
    		{
    		System.out.print("Column Names: ");
    		for(int i = 0; i < table.getColumnCount(); i++)
    			{
    			String buf = table.getColumnName(i) + " ";
    			System.out.print(buf);
    			}
    		System.out.println();
    		System.out.print("Table Data Model Column Names: ");
    		for(int i = 0; i < table.getColumnCount(); i++)
    			{
    			String buf = table.getModel().getColumnName(i) + " ";
    			System.out.print(buf);
    			}
    		System.out.println();
    		System.out.print("Table Column Model Column Names: ");
    		for(int i = 0; i < table.getColumnModel().getColumnCount(); i++)
    			{
    			System.out.print(table.getColumnModel().getColumn(i).getHeaderValue() + " ");
    			}
    		System.out.println();
    		}
     
    	public static void main(String[] args)
    		{
    		javax.swing.SwingUtilities.invokeLater(new Runnable()
    		{
    		public void run()
    			{
    			createAndShowGUI();
    			}
    		});
    		}
    	}
     
    @SuppressWarnings("serial") 
    class ExpTableModel extends AbstractTableModel
    	{
    	private Vector<Integer> columnNames;
    	private Vector<Vector<Integer>> rowHolder;
    	private int squareSize = 5;
     
    	public ExpTableModel()
    		{
    		columnNames = new Vector<Integer>();
    		rowHolder = new Vector<Vector<Integer>>();
    		for(int i = 1; i <= squareSize; i++)
    			{
    			columnNames.add(new Integer(i));
    			}
    		columnNames.add(0, new Integer(0));
    		for(int i = 1; i < columnNames.size(); i++)
    			{
    			Vector<Integer> rowData = new Vector<Integer>();
    			rowData.add(0, columnNames.get(i));
    			for(int j = 1; j <= squareSize; j++)
    				{
    				rowData.add(columnNames.get(i)*columnNames.get(j));
    				}
    			rowHolder.add(rowData);
    			}
    		}
    	@Override
    	public int getRowCount()
    		{
    		return rowHolder.size();
    		}
    	@Override
    	public int getColumnCount()
    		{
    		return columnNames.size();
    		}
    	@Override
    	public String getColumnName(int column)
    		{
    		return columnNames.get(column).toString();
    		}
    	@Override
    	public Integer getValueAt(int rowIndex, int columnIndex)
    		{
    		Vector<Integer> row = rowHolder.elementAt(rowIndex);
    		return row.elementAt(columnIndex);
     
    		}
     
    	public void repopulateTable(Vector<Integer> newColumnNames)
    		{
    		columnNames.removeAllElements();
    		columnNames = new Vector<Integer>(newColumnNames);
    		columnNames.add(0, new Integer(0));
    		rowHolder.removeAllElements();
    		for(int i = 1; i < columnNames.size(); i++)
    			{
    			Vector<Integer> rowData = new Vector<Integer>();
    			rowData.add(0, columnNames.get(i));
    			for(int j = 1; j <= squareSize; j++)
    				{
    				rowData.add(columnNames.get(i)*columnNames.get(j));
    				}
    			rowHolder.add(rowData);
    			}
    		}
     
    	public void PrintTableData()
    		{
    		for(int i = 0; i < getRowCount(); i++)
    			{
    			System.out.print("Row " + i + ": ");
    			for(int j = 0; j < rowHolder.get(i).size(); j++)
    				{
    				System.out.print(rowHolder.get(i).get(j) + " ");	
    				}
    			System.out.println();
    			}
    		}
    	}


  2. #2
    Forum VIP
    Join Date
    Jul 2010
    Posts
    1,619
    Thanks
    25
    Thanked 322 Times in 300 Posts

    Default Re: JTables: How do I adjust row order as I drag columns?

    Perhaps you should instead override the JTable's JTableHeader's columnMoved(TableColumnModelEvent e) method and set the JTableHeaders to allow reordering with the JTableHeader.setReorderingAllowed(boolean reorderingAllowed) method. The TableColumnModelEvent allows you to get the previous index and current index when you move a column. You can then use the TableModel's moveRow(int start, int end, int to) method to move the row based on the previous and current indexes of the column that was moved.

    Seems kind of simple. Tell me how it works out.
    NOTE TO NEW PEOPLE LOOKING FOR HELP ON FORUM:

    When asking for help, please follow these guidelines to receive better and more prompt help:
    1. Put your code in Java Tags. To do this, put [highlight=java] before your code and [/highlight] after your code.
    2. Give full details of errors and provide us with as much information about the situation as possible.
    3. Give us an example of what the output should look like when done correctly.

    Join the Airline Management Simulation Game to manage your own airline against other users in a virtual recreation of the United States Airline Industry. For more details, visit: http://airlinegame.orgfree.com/

  3. The Following User Says Thank You to aussiemcgr For This Useful Post:

    assel (December 7th, 2010)

  4. #3
    Junior Member
    Join Date
    Dec 2010
    Posts
    2
    Thanks
    1
    Thanked 0 Times in 0 Posts

    Default Re: JTables: How do I adjust row order as I drag columns?

    Thank you! That worked exactly like you said it should. I knew there was a better way to do it than using that hacked up mouse listener method. I should've done more research into the default table model methods. I've added my finished code below for reference.

    import java.awt.Dimension;
    import java.awt.GridLayout;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.util.Vector;
     
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.event.ChangeEvent;
    import javax.swing.event.ListSelectionEvent;
    import javax.swing.event.TableColumnModelEvent;
    import javax.swing.event.TableColumnModelListener;
    import javax.swing.table.AbstractTableModel;
    import javax.swing.table.DefaultTableModel;
     
    @SuppressWarnings("serial")
    public class ExpTable extends JPanel
    	{
    	private static JTable table;
    	private static JFrame frame;
    	private Vector<Integer> columns;
    	private Vector<Vector<Integer>> rowHolder;
    	private int squareSize = 5;
     
    	public ExpTable()
    		{
    		super(new GridLayout(1,0));
    		columns = new Vector<Integer>();
    		rowHolder = new Vector<Vector<Integer>>();
    		for(int i = 0; i <= squareSize; i++)
    			{
    			columns.add(i);
    			}
    		for(int i = 0; i <= squareSize; i++)
    			{
    			Vector<Integer> rowData = new Vector<Integer>();
    			rowData.add(0, columns.get(i));
    			for(int j = 1; j <= squareSize; j++)
    				{
    				Integer valToAdd = i*j;
    				rowData.add(valToAdd);
    				}
    			rowHolder.add(rowData);
    			}
    		final DefaultTableModel myModel = new DefaultTableModel();
    		myModel.setDataVector(rowHolder, columns);
    		table = new JTable(myModel);
    		table.getTableHeader().setReorderingAllowed(true);
    		table.getColumnModel().addColumnModelListener(new TableColumnModelListener()
    		{
    			@Override
    			public void columnAdded(TableColumnModelEvent e)
    				{}
     
    			@Override
    			public void columnRemoved(TableColumnModelEvent e)
    				{}
     
    			@Override
    			public void columnMoved(TableColumnModelEvent e)
    				{
    				int movedFrom = e.getFromIndex();
    				int movedTo = e.getToIndex();
    				if(movedFrom != movedTo)
    					{
    					System.out.println("Column moved from index " + movedFrom);
    					System.out.println("Column moved to index " + movedTo);
    					}
    				myModel.moveRow(movedFrom, movedFrom, movedTo);
    				}
     
    			@Override
    			public void columnMarginChanged(ChangeEvent e)
    				{}
     
    			@Override
    			public void columnSelectionChanged(ListSelectionEvent e)
    				{}
     
    		});
    		table.setPreferredScrollableViewportSize(new Dimension(500,300));
    		table.setFillsViewportHeight(true);
    		JScrollPane scrollPane = new JScrollPane(table);
    		add(scrollPane);
    		}
     
    	private static void createAndShowGUI()
    		{
    		frame = new JFrame("Table Experiment");
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		ExpTable newTable = new ExpTable();
    		newTable.setOpaque(true);
    		frame.setContentPane(newTable);
    		frame.pack();
    		frame.setVisible(true);
    		}
     
     
    	public static void main(String[] args)
    		{
    		javax.swing.SwingUtilities.invokeLater(new Runnable()
    		{
    		public void run()
    			{
    			createAndShowGUI();
    			}
    		});
    		}
    	}

  5. #4
    Forum VIP
    Join Date
    Jul 2010
    Posts
    1,619
    Thanks
    25
    Thanked 322 Times in 300 Posts

    Default Re: JTables: How do I adjust row order as I drag columns?

    Cool, I was just working on theory.
    NOTE TO NEW PEOPLE LOOKING FOR HELP ON FORUM:

    When asking for help, please follow these guidelines to receive better and more prompt help:
    1. Put your code in Java Tags. To do this, put [highlight=java] before your code and [/highlight] after your code.
    2. Give full details of errors and provide us with as much information about the situation as possible.
    3. Give us an example of what the output should look like when done correctly.

    Join the Airline Management Simulation Game to manage your own airline against other users in a virtual recreation of the United States Airline Industry. For more details, visit: http://airlinegame.orgfree.com/

Similar Threads

  1. how to adjust the size on a graphic component
    By Khoatic in forum AWT / Java Swing
    Replies: 8
    Last Post: November 19th, 2010, 10:28 PM
  2. JTables with JButtons, I'm overlooking something
    By aussiemcgr in forum What's Wrong With My Code?
    Replies: 4
    Last Post: October 8th, 2010, 11:30 AM
  3. live feeds and jtables
    By petem86 in forum File I/O & Other I/O Streams
    Replies: 2
    Last Post: September 19th, 2010, 08:44 PM
  4. Building Table of Specified Rows and Columns
    By wale89 in forum Java Servlet
    Replies: 1
    Last Post: August 3rd, 2010, 08:57 AM
  5. Need a loop for rows and columns
    By Ceasar in forum Loops & Control Statements
    Replies: 8
    Last Post: October 9th, 2009, 05:47 PM