问题描述
我有一个JTable,我想让用户可以按自己的意愿对列进行定位,以获取信息的自定义视图。但是同时,当发生特定事件时,我需要一个函数(或算法)来将这些列设置为其原始位置。
我知道,当您要访问单元格中的数据时,无论用户将其设置在什么位置,列的索引都将保持不变。
例如:一个具有3列的JTable,例如column1,column2,column3。如果用户拖动它们以将其显示为column2,column3,column1,则column1仍将具有0索引。因此,必须有一种方法可以轻松地将其重新排序为原始位置。我知道要访问列的重新排序,您需要获取标题。
jtableheader header = table.getTableHeader();
header.setReorderingallowed(true);
因此,从那里我看了jtableheader类的文档,但是我没有找到任何有用的东西,也没有通过搜索特定的解决方案。我希望我已经正确解释了这个问题。这是我的代码的类似示例。
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
}
};
我也知道默认情况下,列的重新排序设置为true,但是我添加了它是为了使之更清楚,并知道我还能从中添加或做些什么。
编辑1
第一种解决方案,在名为private static int[] ColumnsWidth
的自定义类中使用HelperArrays
数组,并根据需要使用列宽,其中getter方法返回用于每列宽度的int,设置为参数数组的索引。我们可以从JTable对象中重置DefaultTableModel,但是还需要重置列的宽度,以便成功地将列重新排序到其原始位置
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));
}
}
编辑2
第二个也是最后一个解决方案,直接使用moveColumn()
对象中的TableColumnModel
函数对列进行重新排序,并使用循环按其原始索引还原它们。
@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);
}
}
解决方法
所以从那里我看了JTableHeader的文档
TableColumn
中包含有关TableColumnModel
的显示方式的信息。
您可以只使用moveColumn(...)
方法来恢复列顺序。
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);
}
}
,
我不知道是否有更好的解决方案,但这似乎可行:
TableModel model = table.getModel();
table.setModel(new DefaultTableModel());
table.setModel(model);
完整示例:
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","dfsdf","fsdafas" },{ "66","Something" },{ "1000",{ "1524",{ "5801",{ "-55",};
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);
});
}
}
预览:
编辑
最近我问了how to restore column widths。删除并重新添加模型会使表的渲染器变形。如果您使用自定义TableCellRenderers
,并且想要在重新设置模型后保留它们,则可以使用以下内容:
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()));
}
}