Swing/RowSorterPopupMenu のバックアップの現在との差分(No.18)
- category: swing folder: RowSorterPopupMenu title: JTableHeaderにJPopupMenuを追加してソート tags: [JTable, JTableHeader, JPopupMenu, PopupMenuListener, TableRowSorter] author: aterai pubdate: 2009-12-07T14:24:46+09:00 description: JTableHeaderにJPopupMenuを追加してソートします。 image:
概要
概要
JTableHeader
にJPopupMenu
を追加してソートします。
Screenshot
Advertisement
サンプルコード
サンプルコード
private class TablePopupMenu extends JPopupMenu {
private final List<SortAction> actions = Arrays.asList(
new SortAction(SortOrder.ASCENDING),
new SortAction(SortOrder.DESCENDING));
//new SortAction(SortOrder.UNSORTED));
// new SortAction(SortOrder.UNSORTED));
#spanadd
#spanend
public TablePopupMenu() {
super();
for (Action a: actions) {
add(a);
}
}
#spanadd
#spanend
@Override public void show(Component c, int x, int y) {
JTableHeader h = (JTableHeader) c;
int i = h.columnAtPoint(new Point(x, y));
i = h.getTable().convertColumnIndexToModel(i);
for (SortAction a: actions) {
a.setIndex(i);
if (c instanceof JTableHeader) {
JTableHeader header = (JTableHeader) c;
JTable table = header.getTable();
header.setDraggedColumn(null);
header.repaint();
table.repaint();
int i = table.convertColumnIndexToModel(header.columnAtPoint(new Point(x, y)));
if (i >= 0) {
actions.forEach(a -> a.setIndex(i));
super.show(c, x, y);
}
}
super.show(c, x, y);
}
}
#spandel
private class SortAction extends AbstractAction{
#spanend
#spanadd
#spanend
#spanadd
private class SortAction extends AbstractAction {
#spanend
private final SortOrder dir;
private int index = -1;
#spanadd
#spanend
public SortAction(SortOrder dir) {
super(dir.toString());
this.dir = dir;
}
private int index = -1;
#spanadd
#spanend
public void setIndex(int index) {
this.index = index;
}
#spanadd
#spanend
@Override public void actionPerformed(ActionEvent e) {
table.getRowSorter().setSortKeys(Arrays.asList(
new RowSorter.SortKey(index, dir)));
}
}
View in GitHub: Java, Kotlin解説
上記のサンプルでは、マウスカーソルの下にあるJTableHeader
カラムをクリック(WindowsLookAndFeel
:右クリック)することで、JPopupMenu
を表示してソートすることができます。
解説
上記のサンプルでは、マウスカーソルの下にあるJTableHeader
カラムをクリック(WindowsLookAndFeel
:右クリック)してJPopupMenu
を表示し、昇順か降順のJMenuItem
を指定してのソートが可能になっています。デフォルトのカラム左クリックによるソートはTableRowSorter#toggleSortOrder(...)
をオーバーライドして無効にしています。
- 左クリックではソートしない
-
ソートにJTableHeader
のフォーカスペイントをクリアするために以下のようなPopupMenuListener
を追加 - 列を右クリックで表示範囲外までドラッグしてからリリースしてポップアップを開くと描画が乱れるので、
JPopupMenu#show(...)
をオーバーライドしてドラッグ状態の解消、ヘッダ、テーブルの再描画を実行-
PopupMenuListener
を利用する場合はpopupMenuWillBecomeInvisible
ではなくpopupMenuWillBecomeVisible
でも同様の処理を行う
-
- -
ソートしたあとで、
JTableHeader
のフォーカスペイントをクリアするために以下のようなPopupMenuListener
を追加しています。
JPopupMenu pop = new TablePopupMenu();
#spandel
final JTableHeader header = table.getTableHeader();
#spanend
#spanadd
JTableHeader header = table.getTableHeader();
#spanend
header.setComponentPopupMenu(pop);
pop.addPopupMenuListener(new PopupMenuListener() {
@Override public void popupMenuCanceled(PopupMenuEvent e) {}
@Override public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
//System.out.println("popupMenuWillBecomeInvisible");
@Override public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
header.setDraggedColumn(null);
//header.setResizingColumn(null);
header.repaint();
header.getTable().repaint();
}
@Override public void popupMenuWillBecomeVisible(PopupMenuEvent e) {}
#spanadd
#spanend
@Override public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
// header.setDraggedColumn(null);
header.repaint();
header.getTable().repaint();
}
#spanadd
#spanend
@Override public void popupMenuCanceled(PopupMenuEvent e) {}
});