?
Solved

JTable  Save and Restore viewed order of columns

Posted on 2006-05-24
19
Medium Priority
?
2,169 Views
Last Modified: 2010-03-31
Hi
I need to save the viewed order of the columns on a JTable,
(i.e. the user may have dragged columns around horizontally).
When the application restarts I need to restore the user's viewed column order.
I understand this order is maintained internally in JTable, and it would be better
if I did not change the actual initial order of the columns.
Any ideas?
0
Comment
Question by:richard_fairall
  • 9
  • 7
  • 3
19 Comments
 
LVL 14

Expert Comment

by:hoomanv
ID: 16758164
this order is maintained internally in: TableColumnModel (horizontal order) and TableModel (vertical order)
maybe you should serilize these objects to a file and restore them
0
 

Author Comment

by:richard_fairall
ID: 16758352
Thanks but I dont want to use serialization here.
The application has an xml user-preferences file containing details of all window settings in the application.
I would like to save the info in xml  and restore the JTable column order from the same xml.
At least then I could programmatically avoid migration issues with incompatible serialized objects.
Rich
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 12

Expert Comment

by:Giant2
ID: 16758376
0
 
LVL 14

Accepted Solution

by:
hoomanv earned 2000 total points
ID: 16758401
with this code you can get the order of columns

Enumeration<TableColumn> e = jTable.getColumnModel().getColumns();
while(e.hasMoreElements()) {
      e.nextElement().getModelIndex();
}

you can then use these info later to restore the privious view
0
 

Author Comment

by:richard_fairall
ID: 16758545
Thanks, I know my way around Serializabe, Dom, xml etc
This request is about the possibility of getting some table column info order
and restoring the column view orders from it after the table is created.
I can see some usefu methods in JTable like convertColumnIndexToModel() and
convertColumnIndexToViewl()  but no way of programmatically restoring the orders.
I need to do this programmatically, without using serialization or XMLEncoder etc.
I dont think it's possible, do you?
Rich
0
 

Author Comment

by:richard_fairall
ID: 16758569
Thanks Hoomany
I crossed over your input with my last entry.
That sounds like it will do the job.
0
 
LVL 14

Expert Comment

by:hoomanv
ID: 16758572
> but no way of programmatically restoring the orders
see my last comment to get the columns orders
to rearrange columns to be in this order you should remove all columns from TableColumnModel and then try to add them in the specified order.

for example if they are in order: 2, 1, 0
you have to add column 2 first then column 1 and at last column 0
0
 

Author Comment

by:richard_fairall
ID: 16758695
What about using getModelIndex() to restore?

0
 

Author Comment

by:richard_fairall
ID: 16758699
Sorry I meant setModelIndex()
0
 
LVL 12

Expert Comment

by:Giant2
ID: 16758704
Sorry not help you.
0
 
LVL 14

Expert Comment

by:hoomanv
ID: 16758713
it will change the modelindex of column but it wont move the column at the view level, so the best way I think is try to add columns from scratch
0
 

Author Comment

by:richard_fairall
ID: 16758725
If I add columns (in any order) from scratch then my getValueAt() method will need to be mapped too?
0
 
LVL 14

Expert Comment

by:hoomanv
ID: 16758738
yes I think
setModelIndex() could be helpful to map the view model to internal model
0
 

Author Comment

by:richard_fairall
ID: 16758840
Thanks I have just had a look at the javadoc

setModelIndex()
Sets the model index for this column. The model index is the index of the column in the model that will be displayed by this TableColumn.
As the TableColumn is moved around in the view the model index remains constant.

Ok, so, a scenario:
1. I create a new Table with columns:  Tom, Dick, Harry.
2. User shuffles these around to: Dick, Tom, Harry.
3. Save view order info: 0,1,2  is  1,0,2  somehow.
4. Restart and build table columns as Dick, Tom, Harry.
5. Call setColumnIndex() for each column to fix original model index so getValueAt() can remain fixed.

or do I need another coffee?
0
 

Author Comment

by:richard_fairall
ID: 16759160
Doesn't work as suggested, I need to focus on this a bit more.
In the table model, I think the solution will be:
1. Hold a list of column names that correspond to the order of the columns in getValueAt().
2. When constructing the model, take a list of column header names in the shuffled order.
3. Build the model using this shuffled list.
4. Create a lookup table to remap the columnIndex for getValueAt().
5. Do   getValueAt(row,  getColumnOrder(lookupTable);
0
 
LVL 14

Expert Comment

by:hoomanv
ID: 16761817
I've created this sample code to demonstrate how you can achieve this
in line --> int[] newOrd = {2,4,0,3,1};
you can provide any order, and by pressing reorder button, columns will be rearranged to that order


/*******************************/
import java.util.*;
import javax.swing.table.*;

public class NewJFrame extends javax.swing.JFrame {
      
      public NewJFrame() {
            initComponents();
      }
      
    private void initComponents() {
        jScrollPane1 = new javax.swing.JScrollPane();
        jTable1 = new javax.swing.JTable();
        jPanel1 = new javax.swing.JPanel();
        jButton1 = new javax.swing.JButton();
        jButton2 = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        jTable1.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {"0", "1", "2", "3", "4"},
                {"0", "1", "2", "3", "4"},
                {"0", "1", "2", "3", "4"},
                {"0", "1", "2", "3", "4"}
            },
            new String [] {
                "0", "1", "2", "3", "4"
            }
        ));
        jScrollPane1.setViewportView(jTable1);

        getContentPane().add(jScrollPane1, java.awt.BorderLayout.CENTER);

        jButton1.setText("order");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        jPanel1.add(jButton1);

        jButton2.setText("reorder");
        jButton2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton2ActionPerformed(evt);
            }
        });

        jPanel1.add(jButton2);

        getContentPane().add(jPanel1, java.awt.BorderLayout.SOUTH);

        pack();
    }

      private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                        
            int numCol = jTable1.getColumnCount();
            int[] newOrd = {2,4,0,3,1};
            int[] curOrd = new int[numCol];
            
            Enumeration<TableColumn> e = jTable1.getColumnModel().getColumns();
            for(int i = 0; e.hasMoreElements(); i++)
                  curOrd[i] = e.nextElement().getModelIndex();
            
            for(int i = 0, p; i < numCol; i++) {
                  for(p = i; curOrd[p] != newOrd[i]; p++)
                        ;
                  
                  for(int j = p; j > i; j--)
                        curOrd[j] = curOrd[j-1];
                  curOrd[i] = curOrd[p];
                  
                  jTable1.getColumnModel().moveColumn(p, i);
            }
      }                                        

      private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                        
            Enumeration<TableColumn> e = jTable1.getColumnModel().getColumns();
            while(e.hasMoreElements()) {
                  System.out.print(e.nextElement().getModelIndex() + " ");
            }
            System.out.println();
      }                                        
      
      public static void main(String args[]) {
            java.awt.EventQueue.invokeLater(new Runnable() {
                  public void run() {
                        new NewJFrame().setVisible(true);
                  }
            });
      }
      
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTable jTable1;
      
}
0
 
LVL 14

Expert Comment

by:hoomanv
ID: 16761959
sample version 2

/************************/

import java.util.*;
import javax.swing.table.*;

public class NewJFrame extends javax.swing.JFrame {
      
      public NewJFrame() {
            initComponents();
      }
      
    private void initComponents() {
        jScrollPane1 = new javax.swing.JScrollPane();
        jTable1 = new javax.swing.JTable();
        jPanel1 = new javax.swing.JPanel();
        jButton1 = new javax.swing.JButton();
        jButton2 = new javax.swing.JButton();
        jTextField1 = new javax.swing.JTextField();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        jTable1.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {"0", "1", "2", "3", "4"},
                {"0", "1", "2", "3", "4"},
                {"0", "1", "2", "3", "4"},
                {"0", "1", "2", "3", "4"}
            },
            new String [] {
                "0", "1", "2", "3", "4"
            }
        ));
        jScrollPane1.setViewportView(jTable1);

        getContentPane().add(jScrollPane1, java.awt.BorderLayout.CENTER);

        jButton1.setText("order");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        jPanel1.add(jButton1);

        jButton2.setText("reorder");
        jButton2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton2ActionPerformed(evt);
            }
        });

        jPanel1.add(jButton2);

        jTextField1.setText("2,4,0,3,1");
        jPanel1.add(jTextField1);

        getContentPane().add(jPanel1, java.awt.BorderLayout.SOUTH);

        pack();
    }

      private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                        
            int numCol = jTable1.getColumnCount();
            int[] newOrd = new int[numCol];
            int[] curOrd = new int[numCol];
            
            String[] strOrd = jTextField1.getText().split(",");
            for(int i=0; i < strOrd.length; i++)
                  newOrd[i] = Integer.parseInt(strOrd[i]);
            
            Enumeration<TableColumn> e = jTable1.getColumnModel().getColumns();
            for(int i = 0; e.hasMoreElements(); i++)
                  curOrd[i] = e.nextElement().getModelIndex();
            
            for(int i = 0, p; i < numCol; i++) {
                  for(p = i; curOrd[p] != newOrd[i]; p++)
                        ;
                  
                  int q = curOrd[p];
                  for(int j = p; j > i; j--)
                        curOrd[j] = curOrd[j-1];
                  curOrd[i] = q;
                  
                  jTable1.getColumnModel().moveColumn(p, i);
            }
      }                                        

      private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                        
            Enumeration<TableColumn> e = jTable1.getColumnModel().getColumns();
            while(e.hasMoreElements()) {
                  System.out.print(e.nextElement().getModelIndex() + " ");
            }
            System.out.println();
      }                                        
      
      public static void main(String args[]) {
            java.awt.EventQueue.invokeLater(new Runnable() {
                  public void run() {
                        new NewJFrame().setVisible(true);
                  }
            });
      }
      
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTable jTable1;
    private javax.swing.JTextField jTextField1;
      
}
0
 

Author Comment

by:richard_fairall
ID: 16766576
Thanks a bundle mate, I'll give it a whirl.
Rich
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
This video teaches viewers about errors in exception handling.
Suggested Courses
Course of the Month13 days, 18 hours left to enroll

807 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question