Eclipseのプラグイン開発で扱うSWTのテーブルについて。
|
表形式でデータを表示する。
import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem;
Table table = new Table(composite, SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI); table.setHeaderVisible(true); // 見出しを表示する table.setLinesVisible(true); // 行間の線を表示する // 列の設定 { TableColumn col1 = new TableColumn(table, SWT.LEFT); col1.setText("name"); col1.setWidth(140); TableColumn col2 = new TableColumn(table, SWT.LEFT); col2.setText("type"); col2.setWidth(100); TableColumn col3 = new TableColumn(table, SWT.LEFT); col3.setText("description"); col3.setWidth(130); } // データの設定 for (int i = 1; i <= 10; i++) { TableItem item = new TableItem(table, SWT.NONE); item.setText(0, "name" + i); item.setText(1, "type" + i); item.setText(2, "desc" + i); }
列毎にTableColumnを作成する。
setWidth()で幅をセットしておかないと、列が表示されない。(たぶん幅0になっている)
行毎にTableItemを作成する。
知っておくと便利そうなメソッド。
メソッド(使用例) | 説明 | |
---|---|---|
列 | new TableColumn(table, style); |
新しい列を追加する。 |
int size = table.getColumnCount(); |
列数を取得する。 | |
TableColumn tc = table.getColumn(column); |
TableColumnを取得する。 | |
int column = table.indexOf(tc); |
列番号を取得する。 | |
行 | new TableItem(table, style); |
新しい行を追加する。 |
item.setText(column, text); |
データ(テキスト)を設定/取得する。 | |
int size = table.getItemCount(); |
行数を取得する。 | |
TableItem item = table.getItem(row); |
TableItem(行データ)を取得する。 | |
TableItem item = table.getItem(point); |
マウスイベントの座標からTableItemを取得する。→使用例 | |
int row = table.indexOf(item); |
行番号を取得する。 | |
table.remove(row); |
行を削除する。 | |
table.removeAll(); |
全ての行を削除する。 | |
int h = table.getItemHeight(); |
行の高さを取得する。 | |
選択 | TableItem[] items = table.getSelection(); |
選択された行を取得する。 |
int count = table.getSelectionCount(); |
選択されている行数を取得する。 | |
int n = table.getSelectionIndex(); |
選択された行の番号を取得する。 | |
boolean b = table.isSelected(row); |
行が選択されているかどうかを判定する。 | |
table.select (row); |
行を選択する。 (SWTのテーブルではセル(列)を単独で選択することは出来ない) |
|
table.selectAll (); |
行を全て選択する。 | |
table.deselect (row); |
行の選択を解除する。 | |
table.deselectAll (); |
全ての選択を解除する。 | |
table.setSelection(row); |
行を選択する。 内部でdeselectAll()・select()およびshowSelection()を呼び出している。 (異なる場所に対してselect()を複数回呼び出すと選択範囲が増えていくが、 setSelection()では直前の選択範囲はクリアされる) |
|
表示 | table.showSelection (); |
指定された箇所が見えるようにスクロールする。 (selectionだと選択された行、columnだと指定列、itemだと指定行) |
table.showColumn(tc); |
||
table.showItem(item); |
テーブルがクリックまたはダブルクリックされたことを検知するには、SelectionListenerを使う。[2013-04-19]
import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent;
final Table table = 〜; table.addSelectionListener(new SelectionAdapter() { // クリック @Override public void widgetSelected(SelectionEvent e) { int select = table.getSelectionIndex(); if (select < 0) { return; } Object data = table.getItem(select).getData(); if (data == null) { return; } doClick(data); }
// ダブルクリック @Override public void widgetDefaultSelected(SelectionEvent e) { int select = table.getSelectionIndex(); if (select < 0) { return; } Object data = table.getItem(select).getData(); if (data == null) { return; } doDoubleClick(data); } });
なんでダブルクリックが「DefaultSelected」という名前なのかと言うと、稼働環境によってデフォルトの選択動作が異なる為らしい。
「Windowsだとダブルクリック」ということのようだ。
SelectionListenerは、データの有る行・列をクリックした場合にしか反応しない。[2013-05-14]
テーブル内のそれ以外の場所(空行・空列)がクリックされたことを検知するには、MouseListenerを使う。
import org.eclipse.swt.events.MouseAdapter; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.graphics.Point;
table.addMouseListener(new MouseAdapter() { @Override public void mouseDown(MouseEvent e) { Point point = new Point(e.x, e.y); Table table = (Table) e.getSource(); TableItem item = table.getItem(point); if (item == null) { // 範囲外がクリックされた } } });
table.getItem(point)
で、クリックされた位置のTableItemが取れる。
逆に言うと、取れなかった場合は範囲外がクリックされたということになる。
テーブルのセルをクリックした時にそのセルを編集する例。
マウスのクリックイベントを拾ってセルのエディターを作成する。
import org.eclipse.swt.events.MouseAdapter; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.graphics.Point;
table.addMouseListener(new MouseAdapter() { @Override public void mouseDown(MouseEvent e) { Point point = new Point(e.x, e.y); Table table = (Table) e.getSource(); TableItem item = table.getItem(point); if (item == null) { return; } for (int i = 0; i < table.getColumnCount(); i++) { if (item.getBounds(i).contains(point)) { createEditor(table, item, i); break; } } } });
import org.eclipse.swt.SWT; import org.eclipse.swt.custom.TableEditor; import org.eclipse.swt.events.FocusAdapter; import org.eclipse.swt.events.FocusEvent; import org.eclipse.swt.events.TraverseEvent; import org.eclipse.swt.events.TraverseListener; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.Text;
private void createEditor(Table table, final TableItem item, final int column) { final Text text = new Text(table, SWT.NONE); text.addFocusListener(new FocusAdapter() { @Override public void focusLost(FocusEvent e) { item.setText(column, text.getText()); text.dispose(); } }); text.addTraverseListener(new TraverseListener() { @Override public void keyTraversed(TraverseEvent e) { switch (e.detail) { case SWT.TRAVERSE_RETURN: item.setText(column, text.getText()); text.dispose(); break; case SWT.TRAVERSE_ESCAPE: text.dispose(); e.doit = false; break; } } }); TableEditor editor = new TableEditor(table); editor.horizontalAlignment = SWT.LEFT; editor.grabHorizontal = true; editor.minimumWidth = 64; // editor.grabVertical = true; editor.setEditor(text, item, column); text.setText(item.getText(column)); text.selectAll(); text.setFocus(); }
TableEditorを作り、そこにsetEditor()で“実際に編集を行うコンポーネント”(上記の例ではText)を登録する。
(grabHorizontal(幅をセルに合わせる)をtrueにするのは超重要!
これが無いと、エディターが表示されていないように見える。[2013-05-02])
TextとTableItemは直接データ連動している訳ではないので、どこかのタイミングでデータ移送する必要がある。
Textにはリスナーを2つ登録してる。
FocusListenerは、マウスをテーブル外でクリックした等でフォーカスを失ったときの処理。
TraverseListenerは、EnterキーやEscキーが押されたときの処理。(タブキーを押したときのTRAVERSE_TAB_NEXTやTRAVERSE_TAB_PREVIOUSといった値もある)