我编写了一个自定义TableRowSorter
,当您点击JTableHeader
=>中的SortOrder.UNSORTED
时会更改排序顺序SortOrder.ASCENDING
=> SortOrder.DESCENDING
=> SortOrder.ASCENDING
=> SortOrder.DESCENDING
=> ...到SortOrder.UNSORTED
=> SortOrder.ASCENDING
=> SortOrder.DESCENDING
=> SortOrder.UNSORTED
=> SortOrder.ASCENDING
=> SortOrder.DESCENDING
=> ...
ADU_SortOrder.java
package order;
import java.util.ArrayList;
import java.util.List;
import javax.swing.SortOrder;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
public class ADU_SortOrder<M extends TableModel> extends TableRowSorter<M> {
public ADU_SortOrder(M model) {
setModel(model);
}
boolean firstTime = true; //Needed in case there are any initial sort keys
int columnHolder = -1;
@Override
public void toggleSortOrder(int column) {
List<? extends SortKey> sortKeys = getSortKeys();
if(sortKeys.size() == 0) { //For if there are no initial sort keys
List<SortKey> keys = new ArrayList<SortKey>();
keys.add(new SortKey(column, SortOrder.ASCENDING));
setSortKeys(keys);
return;
}
if (sortKeys.size() > 0 && columnHolder == column || firstTime) {
if(firstTime) {
firstTime = false;
columnHolder = column;
if(column != sortKeys.get(0).getColumn()) {
List<SortKey> keys = new ArrayList<SortKey>(getSortKeys());
keys.set(0, new SortKey(column, SortOrder.ASCENDING));
setSortKeys(keys);
return;
}
}
List<SortKey> keys = new ArrayList<SortKey>(getSortKeys());
keys.set(0, new SortKey(column, setNextOrder(sortKeys.get(0).getSortOrder())));
setSortKeys(keys);
return;
} else if(sortKeys.size() > 0 && columnHolder != column && !firstTime) {
List<SortKey> keys = new ArrayList<SortKey>(getSortKeys());
keys.set(0, new SortKey(column, SortOrder.ASCENDING));
setSortKeys(keys);
columnHolder = column;
return;
}
super.toggleSortOrder(column);
}
private SortOrder setNextOrder(SortOrder order) {
switch (order) {
case ASCENDING:
return SortOrder.DESCENDING;
case DESCENDING:
return SortOrder.UNSORTED;
case UNSORTED:
return SortOrder.ASCENDING;
default:
return SortOrder.UNSORTED;
}
}
}
当你实现这样的东西时,它的效果非常好
JTableTest.java - 工作示例
import java.awt.GridLayout;
import java.util.List;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.TableModel;
import javax.swing.RowSorter;
import javax.swing.SortOrder;
import order.ADU_SortOrder;
@SuppressWarnings("serial")
public class JTableTest extends JFrame {
private JTableTest() {
super("JTable Test");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new GridLayout(1, 1));
createPanel();
pack();
setVisible(true);
}
JPanel panel = new JPanel(new GridLayout(1, 1));
JScrollPane scroll;
private void createPanel() {
Object[] headers = {"Select", "Title", "Artist", "Length", "Title"};
Object[][] sampleData = {{true, "Bat Outta Hell", "Meat Loaf", "673", "Bat Outta Hell"},
{false, "Spanish Train", "Chris De Burgh", "358", "Spanish Train"},
{true, "Bat Outta Hell", "Meat Loaf", "673", "Bat Outta Hell"}};
JTable table = new JTable(sampleData, headers);
//Sort Order Part
ADU_SortOrder<TableModel> sortOrder = new ADU_SortOrder<TableModel>(table.getModel());
List<RowSorter.SortKey> sortKeys = new ArrayList<>();
sortKeys.add(new RowSorter.SortKey(0, SortOrder.ASCENDING));
sortOrder.setSortKeys(sortKeys);
table.setRowSorter(sortOrder);
scroll = new JScrollPane(table);
panel.add(scroll);
getContentPane().add(panel);
}
public static void main(String[] args) {
new JTableTest();
}
}
但是,只要您添加自定义BasicTableHeaderUI
,例如下面的示例。
CustomHeaderUI.java
package ui;
import javax.swing.plaf.basic.BasicTableHeaderUI;
import javax.swing.table.TableColumnModel;
@SuppressWarnings("serial")
public class CustomHeaderUI extends BasicTableHeaderUI {
public void canReorder(String col, boolean reorder) {
TableColumnModel cM = header.getColumnModel();
for(int i = 0; i < cM.getColumnCount(); i++) {
if(header.getTable().getColumnName(i).equals(col)) {
canReorder(i, reorder);
break;
}
}
}
public void canReorder(String col, int instance, boolean reorder) {
TableColumnModel cM = header.getColumnModel();
int column = -1;
for(int i = 0; i < cM.getColumnCount(); i++) {
if(header.getTable().getColumnName(i).equals(col)) {
column++;
if(column == instance - 1) {
canReorder(i, reorder);
break;
}
}
}
}
public void canReorderAll(String col, boolean reorder) {
TableColumnModel cM = header.getColumnModel();
for(int i = 0; i < cM.getColumnCount(); i++) {
if(header.getTable().getColumnName(i).equals(col))
canReorder(i, reorder);
}
}
public void canReorder(int col, boolean reorder) {
}
}
JTableTest.java - SSSCE / MCVE
import java.awt.GridLayout;
import java.util.List;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.RowSorter;
import javax.swing.RowSorter.SortKey;
import javax.swing.SortOrder;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableModel;
import order.ADU_SortOrder;
import ui.CustomHeaderUI;
@SuppressWarnings("serial")
public class JTableTest extends JFrame {
private JTableTest() {
super("JTable Test");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new GridLayout(1, 1));
createPanel();
pack();
setVisible(true);
}
JPanel panel = new JPanel(new GridLayout(1, 1));
JScrollPane scroll;
private void createPanel() {
Object[] headers = {"Select", "Title", "Artist", "Length", "Title"};
Object[][] sampleData = {{true, "Bat Outta Hell", "Meat Loaf", "673", "Bat Outta Hell"},
{false, "Spanish Train", "Chris De Burgh", "358", "Spanish Train"},
{true, "Bat Outta Hell", "Meat Loaf", "673", "Bat Outta Hell"}};
JTable table = new JTable(sampleData, headers);
ADU_SortOrder<TableModel> sortOrder = new ADU_SortOrder<TableModel>(table.getModel());
List<SortKey> keys = new ArrayList<SortKey>();
keys.add(new RowSorter.SortKey( 0, SortOrder.ASCENDING));
sortOrder.setSortKeys(keys);
table.setRowSorter(sortOrder);
//Adds Custom UI
CustomHeaderUI headerUI = new CustomHeaderUI();
headerUI.installUI(table.getTableHeader());
headerUI.canReorder("Title", true);
headerUI.canReorder("Title", 1, true);
headerUI.canReorderAll("Title", true);
headerUI.canReorder(3, true);
scroll = new JScrollPane(table);
panel.add(scroll);
getContentPane().add(panel);
}
public static void main(String[] args) {
new JTableTest();
}
}
这包括一些样本CustomHeaderUI
方法清楚地显示了两个问题。首先,排序顺序不正确。如果您从第一列Column 0
开始,则排序顺序为
SortOrder.ASCENDING
=&gt; SortOrder.UNSORTED
=&gt; SortOrder.DESCENDING
=&gt; SortOrder.ASCENDING
=&gt; SortOrder.UNSORTED
=&gt; SortOrder.DESCENDING
=&gt; ...
由于keys.add(new RowSorter.SortKey( 0, SortOrder.ASCENDING));
因为我的代码出现故障而开始提升
这不是开始时描述的所需排序顺序。第二个问题是,当您拖动MCVE中的列时,它会跳转两列而不是一列。我非常感谢帮助解决这些问题。
答案 0 :(得分:5)
headerUI.installUI(table.getTableHeader());
在这种情况下,MouseListener
中安装了JTableHeader
重复项。
javax.swing.ToolTipManager@726e5bdf
javax.swing.plaf.basic.BasicTableHeaderUI$MouseInputHandler@600da835
TEST: installUI
javax.swing.ToolTipManager@726e5bdf
javax.swing.plaf.basic.BasicTableHeaderUI$MouseInputHandler@600da835
javax.swing.plaf.basic.BasicTableHeaderUI$MouseInputHandler@17f30210
table.getTableHeader().setUI(headerUI);
代替:
BasicTableHeaderUI#uninstallUI(...)
方法在此BasicTableHeaderUI#installUI(...)
方法中自动执行JTableHeader#setUI()
方法之前执行(确切地说,this method is invoked when this UIComponent instance is being removed as the UI delegate for the specified component)import java.awt.*;
import java.awt.event.*;
// import java.util.List;
// import java.util.ArrayList;
import javax.swing.*;
import javax.swing.plaf.basic.BasicTableHeaderUI;
import javax.swing.table.*;
import javax.swing.table.TableColumnModel;
//import ui.CustomHeaderUI;
public class JTableTest2 extends JFrame {
private JTableTest2() {
super("JTable Test");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new GridLayout(1, 1));
createPanel();
pack();
setVisible(true);
}
JPanel panel = new JPanel(new GridLayout(1, 1));
private void createPanel() {
Object[] headers = {"Select", "Title", "Artist", "Length", "Title"};
Object[][] sampleData = {
{true, "Bat Outta Hell", "Meat Loaf", "673", "Bat Outta Hell"},
{false, "Spanish Train", "Chris De Burgh", "358", "Spanish Train"},
{true, "Bat Outta Hell", "Meat Loaf", "673", "Bat Outta Hell"}
};
JTable table = new JTable(sampleData, headers);
// Custom TableRowSorter is completely irrelevant to this problem:
// //Sort Order Part
// ADU_SortOrder<TableModel> sortOrder = new ADU_SortOrder<>(table.getModel());
// List<RowSorter.SortKey> sortKeys = new ArrayList<>();
// sortKeys.add(new RowSorter.SortKey(0, SortOrder.ASCENDING));
// sortOrder.setSortKeys(sortKeys);
// table.setRowSorter(sortOrder);
JTableHeader header = table.getTableHeader();
testPrintMouseListener(header);
//Adds Custom UI
CustomHeaderUI headerUI = new CustomHeaderUI();
//XXX: headerUI.installUI(table.getTableHeader());
table.getTableHeader().setUI(headerUI);
testPrintMouseListener(header);
panel.add(new JScrollPane(table));
getContentPane().add(panel);
}
private static void testPrintMouseListener(JTableHeader header) {
for (MouseListener l : header.getMouseListeners()) {
System.out.println(l);
}
}
public static void main(String... args) {
EventQueue.invokeLater(() -> {
new JTableTest2();
});
}
}
class CustomHeaderUI extends BasicTableHeaderUI {
@Override public void installUI(JComponent c) {
super.installUI(c);
System.out.println("TEST: installUI");
}
}