richard_fairall
asked on
JTable Save and Restore viewed order of columns
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?
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?
See here for example of object saving:
http://www.javacoffeebreak.com/articles/serialization/index.html
http://java.sun.com/docs/books/tutorial/essential/io/providing.html
http://www.devx.com/Java/Article/9931
...
Bye, Giant.
http://www.javacoffeebreak.com/articles/serialization/index.html
http://java.sun.com/docs/books/tutorial/essential/io/providing.html
http://www.devx.com/Java/Article/9931
...
Bye, Giant.
ASKER
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
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
Souse XPath:
http://javaalmanac.com/egs/org.w3c.dom/pkg.html#XPath
or eventually DOM to save the file:
http://javaalmanac.com/egs/org.w3c.dom/pkg.html
Bye, Giant.
http://javaalmanac.com/egs/org.w3c.dom/pkg.html#XPath
or eventually DOM to save the file:
http://javaalmanac.com/egs/org.w3c.dom/pkg.html
Bye, Giant.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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
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(
convertColumnIndexToViewl(
I need to do this programmatically, without using serialization or XMLEncoder etc.
I dont think it's possible, do you?
Rich
ASKER
Thanks Hoomany
I crossed over your input with my last entry.
That sounds like it will do the job.
I crossed over your input with my last entry.
That sounds like it will do the job.
> 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
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
ASKER
What about using getModelIndex() to restore?
ASKER
Sorry I meant setModelIndex()
Sorry not help you.
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
ASKER
If I add columns (in any order) from scratch then my getValueAt() method will need to be mapped too?
yes I think
setModelIndex() could be helpful to map the view model to internal model
setModelIndex() could be helpful to map the view model to internal model
ASKER
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?
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?
ASKER
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 );
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
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(j avax.swing .WindowCon stants.EXI T_ON_CLOSE );
jTable1.setModel(new javax.swing.table.DefaultT ableModel(
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.setViewportVi ew(jTable1 );
getContentPane().add(jScro llPane1, java.awt.BorderLayout.CENT ER);
jButton1.setText("order");
jButton1.addActionListener (new java.awt.event.ActionListe ner() {
public void actionPerformed(java.awt.e vent.Actio nEvent evt) {
jButton1ActionPerformed(ev t);
}
});
jPanel1.add(jButton1);
jButton2.setText("reorder" );
jButton2.addActionListener (new java.awt.event.ActionListe ner() {
public void actionPerformed(java.awt.e vent.Actio nEvent evt) {
jButton2ActionPerformed(ev t);
}
});
jPanel1.add(jButton2);
getContentPane().add(jPane l1, java.awt.BorderLayout.SOUT H);
pack();
}
private void jButton2ActionPerformed(ja va.awt.eve nt.ActionE vent evt) {
int numCol = jTable1.getColumnCount();
int[] newOrd = {2,4,0,3,1};
int[] curOrd = new int[numCol];
Enumeration<TableColumn> e = jTable1.getColumnModel().g etColumns( );
for(int i = 0; e.hasMoreElements(); i++)
curOrd[i] = e.nextElement().getModelIn dex();
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().m oveColumn( p, i);
}
}
private void jButton1ActionPerformed(ja va.awt.eve nt.ActionE vent evt) {
Enumeration<TableColumn> e = jTable1.getColumnModel().g etColumns( );
while(e.hasMoreElements()) {
System.out.print(e.nextEle ment().get ModelIndex () + " ");
}
System.out.println();
}
public static void main(String args[]) {
java.awt.EventQueue.invoke Later(new Runnable() {
public void run() {
new NewJFrame().setVisible(tru e);
}
});
}
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;
}
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(j
jTable1.setModel(new javax.swing.table.DefaultT
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.setViewportVi
getContentPane().add(jScro
jButton1.setText("order");
jButton1.addActionListener
public void actionPerformed(java.awt.e
jButton1ActionPerformed(ev
}
});
jPanel1.add(jButton1);
jButton2.setText("reorder"
jButton2.addActionListener
public void actionPerformed(java.awt.e
jButton2ActionPerformed(ev
}
});
jPanel1.add(jButton2);
getContentPane().add(jPane
pack();
}
private void jButton2ActionPerformed(ja
int numCol = jTable1.getColumnCount();
int[] newOrd = {2,4,0,3,1};
int[] curOrd = new int[numCol];
Enumeration<TableColumn> e = jTable1.getColumnModel().g
for(int i = 0; e.hasMoreElements(); i++)
curOrd[i] = e.nextElement().getModelIn
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().m
}
}
private void jButton1ActionPerformed(ja
Enumeration<TableColumn> e = jTable1.getColumnModel().g
while(e.hasMoreElements())
System.out.print(e.nextEle
}
System.out.println();
}
public static void main(String args[]) {
java.awt.EventQueue.invoke
public void run() {
new NewJFrame().setVisible(tru
}
});
}
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;
}
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(j avax.swing .WindowCon stants.EXI T_ON_CLOSE );
jTable1.setModel(new javax.swing.table.DefaultT ableModel(
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.setViewportVi ew(jTable1 );
getContentPane().add(jScro llPane1, java.awt.BorderLayout.CENT ER);
jButton1.setText("order");
jButton1.addActionListener (new java.awt.event.ActionListe ner() {
public void actionPerformed(java.awt.e vent.Actio nEvent evt) {
jButton1ActionPerformed(ev t);
}
});
jPanel1.add(jButton1);
jButton2.setText("reorder" );
jButton2.addActionListener (new java.awt.event.ActionListe ner() {
public void actionPerformed(java.awt.e vent.Actio nEvent evt) {
jButton2ActionPerformed(ev t);
}
});
jPanel1.add(jButton2);
jTextField1.setText("2,4,0 ,3,1");
jPanel1.add(jTextField1);
getContentPane().add(jPane l1, java.awt.BorderLayout.SOUT H);
pack();
}
private void jButton2ActionPerformed(ja va.awt.eve nt.ActionE vent evt) {
int numCol = jTable1.getColumnCount();
int[] newOrd = new int[numCol];
int[] curOrd = new int[numCol];
String[] strOrd = jTextField1.getText().spli t(",");
for(int i=0; i < strOrd.length; i++)
newOrd[i] = Integer.parseInt(strOrd[i] );
Enumeration<TableColumn> e = jTable1.getColumnModel().g etColumns( );
for(int i = 0; e.hasMoreElements(); i++)
curOrd[i] = e.nextElement().getModelIn dex();
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().m oveColumn( p, i);
}
}
private void jButton1ActionPerformed(ja va.awt.eve nt.ActionE vent evt) {
Enumeration<TableColumn> e = jTable1.getColumnModel().g etColumns( );
while(e.hasMoreElements()) {
System.out.print(e.nextEle ment().get ModelIndex () + " ");
}
System.out.println();
}
public static void main(String args[]) {
java.awt.EventQueue.invoke Later(new Runnable() {
public void run() {
new NewJFrame().setVisible(tru e);
}
});
}
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;
}
/************************/
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(j
jTable1.setModel(new javax.swing.table.DefaultT
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.setViewportVi
getContentPane().add(jScro
jButton1.setText("order");
jButton1.addActionListener
public void actionPerformed(java.awt.e
jButton1ActionPerformed(ev
}
});
jPanel1.add(jButton1);
jButton2.setText("reorder"
jButton2.addActionListener
public void actionPerformed(java.awt.e
jButton2ActionPerformed(ev
}
});
jPanel1.add(jButton2);
jTextField1.setText("2,4,0
jPanel1.add(jTextField1);
getContentPane().add(jPane
pack();
}
private void jButton2ActionPerformed(ja
int numCol = jTable1.getColumnCount();
int[] newOrd = new int[numCol];
int[] curOrd = new int[numCol];
String[] strOrd = jTextField1.getText().spli
for(int i=0; i < strOrd.length; i++)
newOrd[i] = Integer.parseInt(strOrd[i]
Enumeration<TableColumn> e = jTable1.getColumnModel().g
for(int i = 0; e.hasMoreElements(); i++)
curOrd[i] = e.nextElement().getModelIn
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().m
}
}
private void jButton1ActionPerformed(ja
Enumeration<TableColumn> e = jTable1.getColumnModel().g
while(e.hasMoreElements())
System.out.print(e.nextEle
}
System.out.println();
}
public static void main(String args[]) {
java.awt.EventQueue.invoke
public void run() {
new NewJFrame().setVisible(tru
}
});
}
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;
}
ASKER
Thanks a bundle mate, I'll give it a whirl.
Rich
Rich
maybe you should serilize these objects to a file and restore them