Swing/RowSorterPopupMenu の変更点
- 追加された行はこの色です。
- 削除された行はこの色です。
- Swing/RowSorterPopupMenu へ行く。
- Swing/RowSorterPopupMenu の差分を削除
--- 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: https://lh6.googleusercontent.com/_9Z4BYR88imo/TQTSY9WWpNI/AAAAAAAAAis/Z0YqvftAIh8/s800/RowSorterPopupMenu.png --- * 概要 [#summary] `JTableHeader`に`JPopupMenu`を追加してソートします。 #download(https://lh6.googleusercontent.com/_9Z4BYR88imo/TQTSY9WWpNI/AAAAAAAAAis/Z0YqvftAIh8/s800/RowSorterPopupMenu.png) * サンプルコード [#sourcecode] #code(link){{ 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))); } } }} * 解説 [#explanation] 上記のサンプルでは、マウスカーソルの下にある`JTableHeader`カラムをクリック(`WindowsLookAndFeel`:右クリック)して`JPopupMenu`を表示し、昇順か降順の`JMenuItem`を指定してのソートが可能になっています。デフォルトのカラム左クリックによるソートは`TableRowSorter#toggleSortOrder(...)`をオーバーライドして無効にしています。 ---- - %%ソートに`JTableHeader`のフォーカスペイントをクリアするために以下のような`PopupMenuListener`を追加%% - 列を右クリックで表示範囲外までドラッグしてからリリースしてポップアップを開くと描画が乱れるので、`JPopupMenu#show(...)`をオーバーライドしてドラッグ状態の解消、ヘッダ、テーブルの再描画を実行 -- `PopupMenuListener`を利用する場合は`popupMenuWillBecomeInvisible`ではなく`popupMenuWillBecomeVisible`でも同様の処理を行う #code{{ JPopupMenu pop = new TablePopupMenu(); final JTableHeader header = table.getTableHeader(); 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) {} }); }} * 参考リンク [#reference] - [https://docs.oracle.com/javase/jp/8/docs/api/javax/swing/DefaultRowSorter.html#toggleSortOrder-int- DefaultRowSorter#toggleSortOrder(int) (Java Platform SE 8)] * コメント [#comment] #comment #comment