Swing/FixedColumnTableSorting のバックアップの現在との差分(No.2)
TITLE:JTableの列固定とソート
JTableの列固定とソート
Posted by terai at 2008-11-10- category: swing folder: FixedColumnTableSorting title: JTableの列固定とソート tags: [JTable, TableRowSorter, ChangeListener, JScrollPane, JViewport] author: aterai pubdate: 2008-11-10T14:26:25+09:00 description: 列固定したJTableで、JDK 6で導入されたTableRowSorterを使った行ソートを行います。 image:
概要
列固定したJTable
で、JDK 6
で導入されたTableRowSorter
を使った行ソートを行います。
Screenshot
Advertisement
概要
列固定したJTableで、JDK 6 で導入されたTableRowSorterを使った行ソートを行います。- &jnlp;
- &jar;
- &zip;
#screenshot
サンプルコード
#spanend
#spanadd
* サンプルコード [#sourcecode]
#spanend
#spanadd
#code(link){{
#spanend
fixedTable = new JTable(model);
#spandel
table = new JTable(model);
#spanend
#spanadd
table = new JTable(model);
#spanend
fixedTable.setSelectionModel(table.getSelectionModel());
#spanadd
fixedTable.setUpdateSelectionOnSort(false);
#spanend
#spanadd
// table.setUpdateSelectionOnSort(true);
#spanend
#spandel
for(int i=model.getColumnCount()-1;i>=0;i--) {
#spanend
if(i<2) {
#spanadd
for (int i = model.getColumnCount() - 1; i >= 0; i--) {
#spanend
if (i < 2) {
table.removeColumn(table.getColumnModel().getColumn(i));
fixedTable.getColumnModel().getColumn(i).setResizable(false);
}else{
} else {
fixedTable.removeColumn(fixedTable.getColumnModel().getColumn(i));
}
}
fixedTable.setRowSorter(sorter);
fixedTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
#spandel
fixedTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
#spanend
fixedTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
table.setRowSorter(sorter);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
#spandel
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
#spanend
table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
JScrollPane scroll = new JScrollPane(table);
#spandel
//<ins>
#spanend
#spandel
JPanel wrapper = new JPanel(new BorderLayout(0,0));
#spanend
#spandel
wrapper.add(fixedTable);
#spanend
#spandel
scroll.setRowHeaderView(wrapper);
#spanend
#spandel
//</ins>
#spanend
#spandel
////<del>
#spanend
#spandel
//JViewport viewport = new JViewport();
#spanend
#spandel
//viewport.setView(fixedTable);
#spanend
#spandel
//viewport.setPreferredSize(fixedTable.getPreferredSize());
#spanend
#spandel
//fixedTable.setPreferredScrollableViewportSize(fixedTable.getPreferredSize());
#spanend
#spandel
//scroll.setRowHeaderView(viewport);
#spanend
#spandel
////</del>
#spanend
#spandel
scroll.setCorner(JScrollPane.UPPER_LEFT_CORNER, fixedTable.getTableHeader());
#spanend
#spanadd
JViewport viewport = new JViewport();
#spanend
#spanadd
viewport.setView(fixedTable);
#spanend
#spanadd
viewport.setPreferredSize(fixedTable.getPreferredSize());
#spanend
#spanadd
scroll.setRowHeader(viewport);
#spanend
#spanadd
// scroll.setRowHeaderView(fixedTable);
#spanend
#spanadd
// fixedTable.setPreferredScrollableViewportSize(fixedTable.getPreferredSize());
#spanend
#spanadd
scroll.setCorner(ScrollPaneConstants.UPPER_LEFT_CORNER, fixedTable.getTableHeader());
#spanend
scroll.getViewport().setBackground(Color.WHITE);
#spandel
//<blockquote cite="http://tips4java.wordpress.com/2008/11/05/fixed-column-table/">
#spanend
#spandel
//@auther Rob Camick
#spanend
#spandel
//@title Fixed Column Table ≪ Java Tips Weblog
#spanend
#spanadd
viewport.setBackground(Color.WHITE);
#spanend
#spanadd
// <blockquote cite="https://tips4java.wordpress.com/2008/11/05/fixed-column-table/">
#spanend
#spanadd
// @auther Rob Camick
#spanend
#spanadd
// @title Fixed Column Table ≪ Java Tips Weblog
#spanend
scroll.getRowHeader().addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
@Override public void stateChanged(ChangeEvent e) {
JViewport viewport = (JViewport) e.getSource();
scroll.getVerticalScrollBar().setValue(viewport.getViewPosition().y);
}
});
#spandel
//</blockquote>
#spanend
#spanadd
// </blockquote>
#spanend
add(scroll);
解説
左の固定テーブル(fixedTable)と、右のテーブル(table)に同じRowSorterを設定することで、列固定表でもソートできるようにしています。 ただし、上記のサンプルでは、ソート中に行の追加を行うと例外が発生するので、追加の前にsorter.setSortKeys(null);でSortKeysをクリアする必要があります。解説
- 左の列固定された表(
fixedTable
)と右の表(table
)に同じRowSorter
を設定することで、列固定表でもソート可能に設定 - ソート中に行の追加を行うと例外が発生する
- 上記のサンプルでは以下のように追加前に
sorter.setSortKeys(null)
でSortKeys
をクリアして回避add(new JButton(new AbstractAction("add") { public void actionPerformed(ActionEvent e) { @Override public void actionPerformed(ActionEvent e) { // List<? extends RowSorter.SortKey> keys = sorter.getSortKeys(); sorter.setSortKeys(null); for(int i=0;i<100;i++) { model.addRow(new Object[] { i, i+1, "A"+i, "B"+i }); for (int i = 0; i < 100; i++) { model.addRow(new Object[] {i, i + 1, "A" + i, "B" + i}); } // sorter.setSortKeys(keys); } }), BorderLayout.SOUTH);
- 上記のサンプルでは以下のように追加前に
行を追加したとき、うまく描画されない場合があるので、以下のようなJPanelをラッパーとして使用しています。
#spanend
#spandel
final JScrollPane scroll = new JScrollPane(table);
#spanend
#spandel
//<ins>
#spanend
#spandel
final JPanel wrapper = new JPanel(new BorderLayout(0,0));
#spanend
#spandel
wrapper.add(fixedTable);
#spanend
#spandel
scroll.setRowHeaderView(wrapper);
#spanend
#spandel
fixedTable.setPreferredSize(new Dimension(160, Integer.MAX_VALUE-10000));
#spanend
#spandel
//</ins>
#spanend
#spandel
////<del>
#spanend
#spandel
//JViewport viewport = new JViewport();
#spanend
#spandel
//viewport.setView(fixedTable);
#spanend
#spandel
//viewport.setPreferredSize(fixedTable.getPreferredSize());
#spanend
#spandel
//fixedTable.setPreferredScrollableViewportSize(fixedTable.getPreferredSize());
#spanend
#spandel
//scroll.setRowHeaderView(viewport);
#spanend
#spandel
////</del>
#spanend
#spandel
scroll.setCorner(JScrollPane.UPPER_LEFT_CORNER, fixedTable.getTableHeader());
#spanend
#spandel
scroll.getViewport().setBackground(Color.WHITE);
#spanend
#spandel
-
行を追加したとき描画が乱れる場合があるので、以下のようなJPanel
をラッパーとして使用 - 以下を取り違えていたため、描画がおかしくなっていた
-
JScrollPane#setRowHeaderView(Component)
-
JScrollPane#setRowHeader(JViewport)
-
固定列でキーボードなどによるスクロールに対応するために以下のようなChangeListenerを追加しています。
- 参考:Fixed Column Table ≪ Java Tips Weblog
- 固定列でキーボードなどによるスクロールに対応するため、以下のような
ChangeListener
を追加
scroll.getRowHeader().addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
@Override public void stateChanged(ChangeEvent e) {
JViewport viewport = (JViewport) e.getSource();
scroll.getVerticalScrollBar().setValue(viewport.getViewPosition().y);
}
});
参考リンク
参考リンク
- FixedColumnExample.java
- Fixed Column Table ≪ Java Tips Weblog
- JTable#setUpdateSelectionOnSort(boolean) (Java Platform SE 8)
コメント
- タブキーによるフォーカスの移動は・・・、まぁいいかな。 -- terai
コメント
- Tabキーによるフォーカスの移動は…、まぁいいかな。 -- aterai
- 固定列は、数字でソートするように変更。 -- aterai
- どちらか片方の
JTable
をsetUpdateSelectionOnSort(false);
としてソート後、選択状態がおかしくならないように修正。 -- aterai - 下記サイトは別の手法で列を固定しています。ご参考まで。Freezable JTables (are they extreme?) | Java.net -- panda
- 情報どうもです。ポップアップで固定する列を決めると、固定列の右が水平スクロールで移動できるのですね。最初、固定の確認で列ヘッダをリサイズしてたので迷いました(^^;。固定中は、
table.getTableHeader().setResizingAllowed(false); table.getTableHeader().setReorderingAllowed(false);
とかで、列のリサイズ、移動を禁止したほうがいいかも。でも、ソートや行選択などが簡単にできるのは便利ですね。 -- aterai
- 情報どうもです。ポップアップで固定する列を決めると、固定列の右が水平スクロールで移動できるのですね。最初、固定の確認で列ヘッダをリサイズしてたので迷いました(^^;。固定中は、