Swing/MoveRow の変更点
- 追加された行はこの色です。
- 削除された行はこの色です。
- Swing/MoveRow へ行く。
- Swing/MoveRow の差分を削除
--- category: swing folder: MoveRow title: JTableの行を移動 tags: [JTable, JPopupMenu, JToolBar] author: aterai pubdate: 2004-02-23 description: ツールバーや、ポップアップメニューを使って、JTableの行を上下に移動します。 image: https://lh6.googleusercontent.com/_9Z4BYR88imo/TQTQMwXadCI/AAAAAAAAAfM/mZbfFQ513GI/s800/MoveRow.png --- * 概要 [#summary] ツールバーや、ポップアップメニューを使って、`JTable`の行を上下に移動します。 #download(https://lh6.googleusercontent.com/_9Z4BYR88imo/TQTQMwXadCI/AAAAAAAAAfM/mZbfFQ513GI/s800/MoveRow.png) * サンプルコード [#sourcecode] #code(link){{ class DownAction extends AbstractAction { public DownAction(String str) { super(str); } @Override public void actionPerformed(ActionEvent e) { downActionPerformed(e); } } private void downActionPerformed(ActionEvent e) { System.out.println("-------- 下へ --------"); if (table.isEditing()) { table.getCellEditor().stopCellEditing(); } int[] pos = table.getSelectedRows(); if (pos.length == 0) { return; } RowDataModel model = (RowDataModel) table.getModel(); boolean isShiftDown = (e.getModifiers() & ActionEvent.SHIFT_MASK) != 0; if (isShiftDown) { // Jump to the end model.moveRow(pos[0], pos[pos.length - 1], model.getRowCount() - pos.length); table.setRowSelectionInterval(model.getRowCount() - pos.length, model.getRowCount() - 1); } else { if (pos[pos.length - 1] == model.getRowCount() - 1) { return; } model.moveRow(pos[0], pos[pos.length - 1], pos[0] + 1); table.setRowSelectionInterval(pos[0] + 1, pos[pos.length - 1] + 1); } Rectangle r = table.getCellRect(model.getRowCount() - 1, 0, true); table.scrollRectToVisible(r); } public void showRowPop(MouseEvent e) { int row = table.rowAtPoint(e.getPoint()); int count = table.getSelectedRowCount(); int[] ilist = table.getSelectedRows(); boolean flg = true; for (int i = 0; i < ilist.length; i++) { if (ilist[i] == row) { flg = false; break; } } if (row > 0 && flg) table.setRowSelectionInterval(row, row); JPopupMenu pop = new JPopupMenu(); Action act = new TestCreateAction("追加", null); act.setEnabled(count == 1); pop.add(act); pop.addSeparator(); act = new DeleteAction("削除", null); act.setEnabled(row >= 0); pop.add(act); pop.addSeparator(); act = new UpAction("上へ"); act.setEnabled(count > 0); pop.add(act); act = new DownAction("下へ"); act.setEnabled(count > 0); pop.add(act); pop.show(e.getComponent(), e.getX(), e.getY()); } }} * 解説 [#explanation] 上記のサンプルでは、`DefaultTableModel#moveRow(...)`メソッドを使用して選択した行を上下に動かしています。KBD{Shift}キーを押しながらツールバーの移動ボタンを押すとそれぞれ、先頭、末尾に移動します。 * 参考リンク [#reference] - [https://docs.oracle.com/javase/jp/8/docs/api/javax/swing/table/DefaultTableModel.html#moveRow-int-int-int- DefaultTableModel#moveRow(int, int, int) (Java Platform SE 8)] * コメント [#comment] #comment - いつもお世話になっております。違うカテゴリに投稿して、すみません。`JTable`のカラムの幅をマウスで広げたり、縮んだりする際、イベントで検出し、その幅を変数に取っておく方法はご存知でしょうか?当方は`JDK 1.5`を使っています。よろしくお願いいたします。 -- &user(Panda); &new{2011-03-01 (火) 15:12:21}; - こんばんは。`TableColumnModelListener`を使うのはどうでしょうか。 -- &user(aterai); &new{2011-03-01 (火) 16:48:43}; #code{{ final TableColumnModel cm = table.getColumnModel(); cm.addColumnModelListener(new TableColumnModelListener() { @Override public void columnAdded(TableColumnModelEvent e) {} @Override public void columnMarginChanged(ChangeEvent e) { for (int i = 0; i < cm.getColumnCount(); i++) { TableColumn c = cm.getColumn(i); System.out.println(c.getHeaderValue() + ": " + c.getWidth()); } } @Override public void columnMoved(TableColumnModelEvent e) {} @Override public void columnRemoved(TableColumnModelEvent e) {} @Override public void columnSelectionChanged(ListSelectionEvent e) {} }); }} - ご回答、ありがとうございました。列の幅を変更するため、`TableColumn c = cm.getColumn(i);・・・c.setPreferredWidth(int preferredWidth);`で行いましたが、例えば`c.setPreferredWidth(100)`にすると、`System.out.println(c.getHeaderValue()+": "+c.getWidth());`の結果は`75`が表示されます。見た目上も`100`ピクセルになっていません。確実に幅`100`ピクセルにするにはどうすれば良いでしょうか? -- &user(Panda); &new{2011-03-02 (水) 14:10:35}; -- 列幅が自動調整される場合は、サイズ変更(デルタ)が有効な列に分散されます。このデルタの分散の詳細については、[https://docs.oracle.com/javase/jp/8/docs/api/javax/swing/JTable.html#doLayout-- JTable#doLayout() (Java Platform SE 8)]を参考にしてください。自動調整が`OFF`(`table.getAutoResizeMode()==AUTO_RESIZE_OFF`)の場合はデルタの分散を考慮する必要がないので、ある列の幅をぴったり`100px`にするのは簡単です(`TableColumn#setPreferredWidth(100)`とするだけで良い)。デフォルトの`AUTO_RESIZE_SUBSEQUENT_COLUMNS`の場合は、例えば以下のようにデルタの分散が`0`になるように?後の列も含めてサイズ調整しておく必要があります。 -- &user(aterai); &new{2011-03-02 (水) 18:05:29}; #code{{ import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.table.*; public class ColumnPreferredWidthTest { String[] columnNames = {"String", "Integer", "Boolean"}; Object[][] data = { {"aaa", 12, true}, {"bbb", 5, false}, {"CCC", 92, true}, {"DDD", 0, false} }; DefaultTableModel model = new DefaultTableModel(data, columnNames) { @Override public Class<?> getColumnClass(int column) { return getValueAt(0, column).getClass(); } }; JTable table = new JTable(model); TableColumnModel cm = table.getColumnModel(); public JComponent makeUI() { EventQueue.invokeLater(new Runnable() { @Override public void run() { int total = cm.getTotalColumnWidth(); int count = cm.getColumnCount(); cm.getColumn(0).setPreferredWidth(100); //0列目の幅を100pxにする total -= 100; int colwidth = total / (count - 1); //残りの列幅は均等になるように計算 for (int i = 1; i < count - 1; i++) { TableColumn col = cm.getColumn(i); col.setPreferredWidth(colwidth); total -= colwidth; } cm.getColumn(count - 1).setPreferredWidth(total); //最後の列幅で余りを吸収 } }); JPanel p = new JPanel(new BorderLayout()); p.add(new JScrollPane(table)); p.add(new JButton(new AbstractAction("print width") { @Override public void actionPerformed(ActionEvent e) { for (int i = 0; i < cm.getColumnCount(); i++) { TableColumn c = cm.getColumn(i); System.out.println(c.getHeaderValue() + ": " + c.getWidth()); } } }), BorderLayout.SOUTH); return p; } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { createAndShowGUI(); } }); } public static void createAndShowGUI() { JFrame f = new JFrame(); f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); f.getContentPane().add(new ColumnPreferredWidthTest().makeUI()); f.setSize(320, 240); f.setLocationRelativeTo(null); f.setVisible(true); } } }} - [[TableColumnの幅を比率で設定>Swing/HeaderRatio]]の解説を追加変更したので、そのうちこれらのコードはそちらに移動するかもしれません。 -- &user(aterai); &new{2011-03-02 (水) 18:37:11}; #comment