Swing/RowSorterPopupMenu のバックアップ(No.27)
- バックアップ一覧
 - 差分 を表示
 - 現在との差分 を表示
 - 現在との差分 - Visual を表示
 - ソース を表示
 - Swing/RowSorterPopupMenu へ行く。
  
- 1 (2010-07-27 (火) 08:35:20)
 - 2 (2011-06-05 (日) 02:43:47)
 - 3 (2013-01-03 (木) 14:16:15)
 - 4 (2013-03-16 (土) 03:03:17)
 - 5 (2013-03-18 (月) 02:23:04)
 - 6 (2013-03-29 (金) 07:44:06)
 - 7 (2013-03-29 (金) 17:13:05)
 - 8 (2013-03-31 (日) 17:37:14)
 - 9 (2013-03-31 (日) 18:39:02)
 - 10 (2013-04-02 (火) 22:33:32)
 - 11 (2013-04-03 (水) 04:00:04)
 - 12 (2013-04-05 (金) 09:20:43)
 - 13 (2013-04-05 (金) 17:48:04)
 - 14 (2013-04-06 (土) 05:10:49)
 - 15 (2013-09-23 (月) 04:40:23)
 - 16 (2015-01-21 (水) 18:38:07)
 - 17 (2015-01-28 (水) 15:03:53)
 - 18 (2015-03-27 (金) 21:45:53)
 - 19 (2017-02-02 (木) 15:12:59)
 - 20 (2017-12-20 (水) 16:38:51)
 - 21 (2019-08-30 (金) 18:00:31)
 - 22 (2019-12-17 (火) 13:55:43)
 - 23 (2021-06-18 (金) 08:41:30)
 - 24 (2025-01-03 (金) 08:57:02)
 - 25 (2025-01-03 (金) 09:01:23)
 - 26 (2025-01-03 (金) 09:02:38)
 - 27 (2025-01-03 (金) 09:03:21)
 - 28 (2025-01-03 (金) 09:04:02)
 - 29 (2025-06-19 (木) 12:41:37)
 - 30 (2025-06-19 (木) 12:43:47)
 
 
- 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: 

 
Summary
JTableHeaderにJPopupMenuを追加してソートします。
Screenshot

Advertisement
Source Code Examples
private class TablePopupMenu extends JPopupMenu {
  private final List<SortAction> actions = Arrays.asList(
    new SortAction(SortOrder.ASCENDING),
    new SortAction(SortOrder.DESCENDING));
    // new SortAction(SortOrder.UNSORTED));
  public TablePopupMenu() {
    super();
    for (Action a: actions) {
      add(a);
    }
  }
  @Override public void show(Component c, int x, int y) {
    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);
      }
    }
  }
}
private class SortAction extends AbstractAction {
  private final SortOrder dir;
  private int index = -1;
  public SortAction(SortOrder dir) {
    super(dir.toString());
    this.dir = dir;
  }
  public void setIndex(int index) {
    this.index = index;
  }
  @Override public void actionPerformed(ActionEvent e) {
    table.getRowSorter().setSortKeys(Arrays.asList(
      new RowSorter.SortKey(index, dir)));
  }
}
View in GitHub: Java, KotlinExplanation
上記のサンプルでは、マウスカーソルの下にあるJTableHeaderカラムをクリック(WindowsLookAndFeel:右クリック)してJPopupMenuを表示し、昇順か降順のJMenuItemを指定してのソートが可能になっています。デフォルトのカラム左クリックによるソートはTableRowSorter#toggleSortOrder(...)をオーバーライドして無効にしています。
ソートにJTableHeaderのフォーカスペイントをクリアするために以下のようなPopupMenuListenerを追加- 列を右クリックで表示範囲外までドラッグしてからリリースしてポップアップを開くと描画が乱れるので、
JPopupMenu#show(...)をオーバーライドしてドラッグ状態の解消、ヘッダ、テーブルの再描画を実行PopupMenuListenerを利用する場合はpopupMenuWillBecomeInvisibleではなくpopupMenuWillBecomeVisibleでも同様の処理を行う
 
JPopupMenu pop = new TablePopupMenu();
JTableHeader header = table.getTableHeader();
header.setComponentPopupMenu(pop);
pop.addPopupMenuListener(new PopupMenuListener() {
  @Override public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
    header.setDraggedColumn(null);
    header.repaint();
    header.getTable().repaint();
  }
  @Override public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
    // header.setDraggedColumn(null);
    header.repaint();
    header.getTable().repaint();
  }
  @Override public void popupMenuCanceled(PopupMenuEvent e) {}
});