在 Java 11(使用 swingx 1.6.6)中,我剛剛實作了多列排序,如下所示:
- 單擊第一列,按該列升序排序
- 單擊第二列,按該列升序進行二次排序
- 依此類推,如果用戶單擊他們已經單擊的列,則排序順序會更改,即從升序變為降序
但是我沒有辦法重置排序并查看我認為我希望它以下列方式作業的其他一些應用程式:
- 單擊第一列,按該列升序排序
- 單擊第二列,僅通過該列升序將排序重置為主要排序(與默認排序相同)
- 但是,cntl 單擊第二個列,然后按該列進行二次排序,依此類推,如果用戶單擊一個列,他們已經單擊了排序順序更改,即從升序到降序
因此,每當有人單擊或 cntl-clicks 導致呼叫時toggleSort(),但我如何捕獲用戶已 cntl-clicked 而不是單擊并知道如此可訪問toggleSort()
作為參考,修改后的toggleSort()方法擴展
org.jdesktop.swingx.sort.TableSortController了,我修改了 swingx 代碼,以便我可以訪問以前的私有方法getFirstInCycle()和getNextInCycle())
public void toggleSortOrder(int column)
{
//Are we allowed to this sort column
if (this.isSortable(column))
{
SortOrder firstInCycle = this.getFirstInCycle();
//If all already a column in sort cycle
if (firstInCycle != null)
{
//Make a copy of existing keys
List<SortKey> keys = new ArrayList(this.getSortKeys());
//Look for any existing sort key for column user has clicked on
SortKey sortKey = SortUtils.getFirstSortKeyForColumn((List)keys, column);
//If its the first one
if (((List)keys).indexOf(sortKey) == 0)
{
//Swap the sort order of to next one, i.e ascending to descending
((List)keys).set(0, new SortKey(column, this.getNextInCycle(sortKey.getSortOrder())));
}
else
{
//Add new final sort key for this column
((List)keys).add(new SortKey(column, this.getFirstInCycle()));
}
//Trim the number of keys if we have to many
if (((List)keys).size() > this.getMaxSortKeys()) {
keys = ((List)keys).subList(0, this.getMaxSortKeys());
}
this.setSortKeys((List)keys);
}
}
}
uj5u.com熱心網友回復:
Sooo,我一直在研究代碼,我認為您遇到了很多問題。滑鼠點擊的處理由直接BaseTableHeaderUI呼叫的 UI 委托(特別是 )執行TableRowSorter#toggleSortOrder。所以表和表頭根本不涉及,所以沒有注入點可以通過它來控制這個作業流程。
然后我考慮簡單地添加一個MouseListener到JTableHeader本身。我最初擔心的是這將與現有的介面進行互動MouseListener,TableHeaderUI但是如果我們想要做的只是SortKey在標題為Control 時洗掉 a Clicked,那么它“應該”沒問題,但是,你會接到兩個電話toggleSortOrder
現在,我沒有使用 SwingX,這只是純粹的 Swing,但這個概念應該可以作業??。
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.RowSorter;
import javax.swing.RowSorter.SortKey;
import static javax.swing.SortOrder.ASCENDING;
import static javax.swing.SortOrder.DESCENDING;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JTable table = new JTable();
DefaultTableModel model = new DefaultTableModel(
new Object[]{"abc", "def", "ghi", "jkl"},
0);
model.addRow(new Object[]{"A", "B", "C", "I"});
model.addRow(new Object[]{"B", "C", "D", "J"});
model.addRow(new Object[]{"C", "D", "E", "K"});
model.addRow(new Object[]{"D", "E", "F", "L"});
model.addRow(new Object[]{"E", "F", "G", "M"});
model.addRow(new Object[]{"F", "G", "H", "N"});
table.setModel(model);
// table.setTableHeader(new CustomTableHeader(table));
table.getTableHeader().setDefaultRenderer(new DefaultTableHeaderCellRenderer());
table.setRowSorter(new TableRowSorter<DefaultTableModel>(model));
JTableHeader header = table.getTableHeader();
header.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (!(e.getSource() instanceof JTableHeader)) {
return;
}
JTableHeader header = (JTableHeader) e.getSource();
JTable table = header.getTable();
RowSorter<? extends TableModel> rowSorter = table.getRowSorter();
if (rowSorter == null) {
return;
}
int column = header.columnAtPoint(e.getPoint());
if (column == -1) {
return;
}
List<? extends SortKey> sortKeys = rowSorter.getSortKeys();
List<SortKey> newSortKeys = new ArrayList<>(sortKeys);
Optional<? extends SortKey> firstMatch = sortKeys
.stream()
.filter(key -> key.getColumn() == column)
.findFirst();
if (e.isControlDown()) {
if (firstMatch.isPresent()) {
SortKey sortKey = firstMatch.get();
newSortKeys.remove(sortKey);
}
}
rowSorter.setSortKeys(newSortKeys);
}
});
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new JScrollPane(table));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class DefaultTableHeaderCellRenderer extends DefaultTableCellRenderer {
public DefaultTableHeaderCellRenderer() {
setHorizontalAlignment(CENTER);
setHorizontalTextPosition(LEFT);
setVerticalAlignment(BOTTOM);
setOpaque(false);
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
super.getTableCellRendererComponent(table, value, false, hasFocus, row, column);
JTableHeader tableHeader = table.getTableHeader();
if (tableHeader != null) {
setForeground(tableHeader.getForeground());
}
setIcon(getIcon(table, column));
setBorder(UIManager.getBorder("TableHeader.cellBorder"));
return this;
}
protected Icon getIcon(JTable table, int column) {
SortKey sortKey = getSortKey(table, column);
if (sortKey != null && table.convertColumnIndexToView(sortKey.getColumn()) == column) {
switch (sortKey.getSortOrder()) {
case ASCENDING:
return UIManager.getIcon("Table.ascendingSortIcon");
case DESCENDING:
return UIManager.getIcon("Table.descendingSortIcon");
}
}
return null;
}
protected SortKey getSortKey(JTable table, int column) {
RowSorter rowSorter = table.getRowSorter();
if (rowSorter == null) {
return null;
}
List sortedColumns = rowSorter.getSortKeys();
if (sortedColumns.size() > 0) {
return (SortKey) sortedColumns.get(0);
}
return null;
}
}
}
我在這里看到的問題是弄清楚JTable開關是排序鍵的方式與排序鍵通過Control Clicked事件實際洗掉的時間之間的區別......
關于這一點,我將雙手舉在空中,只是在升序、降序和無序之間切換排序順序,所以你只需要點擊它,但這就是我
uj5u.com熱心網友回復:
決定更好地放棄 cntl-click 想法,而是通過修改org.jdesktop.swingx.sort,DefaultSortControllerfrom來恢復三階段回圈
private final static SortOrder[] DEFAULT_CYCLE
= new SortOrder[] {SortOrder.ASCENDING, SortOrder.DESCENDING};
到
private final static SortOrder[] DEFAULT_CYCLE
= new SortOrder[] {SortOrder.ASCENDING, SortOrder.DESCENDING,SortOrder.UNSORTED};
然后這是我的自定義排序控制器中的 toggleSortOrder() 方法
/**
* If new sort key sort ascending as after other existing sort keys
* If existing sort key and ascending cycle change to descending
* If existing sort key and descending remove the sort key
* If already at MAX_SORT_COLUMNS the ignore
*
* @param column
*/
@Override
public void toggleSortOrder(int column)
{
//Are we allowed to this sort column
if (this.isSortable(column))
{
SortOrder firstInCycle = this.getFirstInCycle();
//If all already a column in sort cycle
if (firstInCycle != null)
{
//Make a copy of existing keys
List<SortKey> newKeys = new ArrayList(this.getSortKeys());
//Look for any existing sort key for column user has clicked on
SortKey sortKey = SortUtils.getFirstSortKeyForColumn(newKeys, column);
//Existing Key
if(sortKey!=null)
{
//Get next in cycle
SortOrder nextSortOrder = this.getNextInCycle(sortKey.getSortOrder());
//Swap to descending/ascending
if(nextSortOrder==SortOrder.DESCENDING || nextSortOrder==SortOrder.ASCENDING)
{
newKeys.set((newKeys).indexOf(sortKey), new SortKey(column, nextSortOrder));
}
//Remove from sort
else
{
newKeys.remove(sortKey);
}
}
//New Key
else
{
(newKeys).add(new SortKey(column, this.getFirstInCycle()));
}
//Trim the number of keys if we have too many
if ((newKeys).size() > this.getMaxSortKeys()) {
newKeys = ((List)newKeys).subList(0, this.getMaxSortKeys());
}
this.setSortKeys(newKeys);
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/429901.html
