Reputation: 15
I have a JTable and I want to give the users the possibility to position the columns as they want for a custom view of the information. But at the same time I'm needing a function (or an algorithm) to set these columns to it's original position when an specific event occurs.
I know that when you want to access to the data in a cell, the index of the column will still remain the same no matter on what position the user have set it.
For example: a JTable with 3 columns, let's say column1, column2, column3. If the user drags them to be displayed as column2, column3, column1, then column1 will still have the 0 index. So there must be a way to easily reordering them back to it's original position. I know that to access to the reordering of a column you need to get the header.
JTableHeader header = table.getTableHeader();
header.setReorderingAllowed(true);
So from there I looked at the documentation of JTableHeader class but I didn't find anything useful, neither by searching an specific solution. I hope I have explained properly this problem. This is a similar example of my code.
DefaultTableModel model = new DefaultTableModel();
table = new JTable(model);
model.addColumn(column1);
model.addColumn(column2);
model.addColumn(column3);
JTableHeader header = table.getTableHeader();
header.setReorderingAllowed(true);
JButton button = new JButton("Reorder");
button.addActionListener(new ActionListener){
@Override
public void actionPerformed(ActionEvent e) {
//the code that orders the columns to its original position
}
};
Also I know that by default the reordering of the columns is set as true, but I added it to make it clear and to know what else I could add or do from there.
EDIT 1
first solution, using a private static int[] ColumnsWidth
Array in a custom class called HelperArrays
with the width of the columns as I need, in which the getter method returns the int used for the width of the each column, setting as parameter the index of the Array. We can reset the DefaultTableModel from the JTable Object but will be needed to also reset the widths of the columns in order to succesfully reorder columns to their original position
private static int[] columnsWidhth = {widht1, widhth2, width3};
public static int getColumnsWidth(int index){
returns ColumnsWidth[index];
}
@Override
public void actionPerformed(ActionEvent e) {
table.setModel(new DefaultTableModel());
table.setModel(model);
DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer();
centerRenderer.setHorizontalAlignment(JLabel.CENTER);
for (int i = 0; i < table.getColumnCount(); i++) {
table.getColumnModel().getColumn(i).setMinWidth(HelperArrays.getColumnsWidth(i));
table.getColumnModel().getColumn(i).setMaxWidth(HelperArrays.getColumnsWidth(i));
table.getColumnModel().getColumn(i).setPreferredWidth(HelperArrays.getColumnsWidth(i));
}
}
EDIT 2
Second and final solution, reordering the columns directly with the moveColumn()
function from the TableColumnModel
Object, using a loop to restore them by their original index.
@Override
public void actionPerformed(ActionEvent e) {
TableModel model = table.getModel();
TableColumnModel tcm = table.getColumnModel();
for (int i = 0; i < model.getColumnCount() - 1; i++) {
int location = tcm.getColumnIndex(model.getColumnName(i));
tcm.moveColumn(location, i);
}
}
Upvotes: 1
Views: 1074
Reputation: 324108
So from there I looked at the documentation of JTableHeader
The information about how the TableColumn
s are display is contained in the TableColumnModel
.
You can just use the moveColumn(...)
method to restore the column order.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
public class TableColumnRestore2 extends JFrame
{
public TableColumnRestore2()
{
final JTable table = new JTable(5, 8);
table.setPreferredScrollableViewportSize(table.getPreferredSize());
JScrollPane scrollPane= new JScrollPane( table );
getContentPane().add(scrollPane);
JButton restore = new JButton("Restore Columns");
getContentPane().add(restore, BorderLayout.SOUTH);
restore.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
TableModel model = table.getModel();
TableColumnModel tcm = table.getColumnModel();
for (int i = 0; i < model.getColumnCount() - 1; i++)
{
int location = tcm.getColumnIndex( model.getColumnName(i) );
tcm.moveColumn(location, i);
}
}
});
}
public static void main(String[] args)
{
TableColumnRestore2 frame = new TableColumnRestore2();
frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
}
Upvotes: 2
Reputation: 6808
I am not aware if there is a better solution, but this seems to work:
TableModel model = table.getModel();
table.setModel(new DefaultTableModel());
table.setModel(model);
A full example:
public class TableColumnOrderTest {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
DefaultTableModel dm = new DefaultTableModel();
dm.addColumn("Column 1");
dm.addColumn("Column 2");
dm.addColumn("Column 3");
dm.addColumn("Column 4");
Object[][] data = {
{ "1", "Something","hello","World" }, { "102", "Something Else" },
{ "55", "Something","dfsdf","fsdafas" }, { "66", "Something" },
{ "1000", "Something" }, { "1524", "Something" },
{ "5801", "Something" }, { "-55", "Something" },};
for (Object[] row : data) {
dm.addRow(row);
}
JTable table = new JTable(dm);
JPanel panel = new JPanel(new BorderLayout());
panel.add(new JScrollPane(table));
JButton button = new JButton("button");
button.addActionListener(e -> {
table.setModel(new DefaultTableModel());
table.setModel(dm);
});
panel.add(button, BorderLayout.PAGE_END);
JOptionPane.showMessageDialog(null, panel);
});
}
}
Preview:
Recently I asked how to restore column widths. Removing and re-adding the model will whack the renderers of the table. You can use something like the following in case you use custom TableCellRenderers
and you want to preserve them after re-setting the model:
private static void restoreColumnOrdering(JTable table) {
TableModel model = table.getModel();
Map<Object, TableCellRenderer> renderers = new HashMap<>();
Map<Object, Integer> widths = new HashMap<>();
for (int i = 0; i < table.getColumnCount(); i++) {
TableColumn column = table.getColumnModel().getColumn(i);
TableCellRenderer cellRenderer = column.getCellRenderer();
renderers.put(column.getIdentifier(), cellRenderer);
widths.put(column.getIdentifier(), column.getPreferredWidth());
}
table.setModel(new DefaultTableModel());
table.setModel(model);
// Reset renderers
for (int i = 0; i < table.getColumnCount(); i++) {
TableColumn column = table.getColumnModel().getColumn(i);
TableCellRenderer cellRenderer = renderers.get(column.getIdentifier());
column.setCellRenderer(cellRenderer);
column.setPreferredWidth(widths.get(column.getIdentifier()));
}
}
Upvotes: -1