Java/Swingの表コンポーネントである『JTable』を使う際に、いろいろつまづいたのでメモします(;´∀`)
表にデータや表示方法を関連づける
まず、表にするデータをTableModelによってJTableに渡します。そして、『データをどのように表示するのか』をTableCellRendererによって決めます。
.Net FrameworkでのDataGridViewにBindingSourceをバインドするイメージに近いのでしょうか?w
では順番に見ていきましょう(`・ω・´)
表にデータを渡しましょう
まずは、表にデータを渡して進捗率が数字で表示されるところまでを見ていきますwpackage t2wonderland.java;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.JButton;
import javax.swing.BoxLayout;
import javax.swing.JScrollPane;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class TableFrame extends JFrame {
private static final long serialVersionUID = 1L;
private JTable tableTest;
private ProgressTableModel tableMedel;
private JButton btnStart;
// アプリケーションを起動します。ここから始まるよw
public static void main(String[] args) {
TableFrame frame = new TableFrame();
frame.setVisible(true);
}
// 画面を初期化するよ
public TableFrame() {
// Windowサイズと、閉じるボタン押下時の処理を追加
this.setSize(400,300);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
// PaneやComponentなど、UI部品を配置します
JScrollPane scrollPane = new JScrollPane();
getContentPane().add(scrollPane);
tableTest = new JTable();
scrollPane.setViewportView(tableTest);
btnStart = new JButton("Start");
btnStart.addActionListener(new ActionAdapter());
btnStart.setAlignmentX(Component.CENTER_ALIGNMENT);
getContentPane().add(btnStart);
// JTableに、TableModelとTableCellRendererを設定します
// ※1 後で、TableModel設定を追加するよ( ・`ω・´)
// ※2 後で、TableCellRenderer設定を追加するよ( ・`ω・´)
}
// ※3 後で、Startボタン押下時の処理を追加するよ( ・`ω・´)
}
まず土台となる画面を作成します。※印の部分は、後で順番に追記してゆきます。package t2wonderland.java;
import javax.swing.table.AbstractTableModel;
// カスタムTableModelクラス
public class ProgressTableModel extends AbstractTableModel
{
private static final long serialVersionUID = 1L;
// データ
private String[] columnNames = {"Progress"};
private int[] progress = {0};
// Progress列のデータGet、Set
public int[] getProgress() {
return progress;
}
public void setProgress(int[] progress) {
this.progress = progress;
}
/// AbstractTableModelのオーバーライド
@Override // 列数を返すMethod
public int getColumnCount() {
return 1;
}
@Override // 行数を返すMethod
public int getRowCount() {
return progress.length;
}
@Override // 指定セルの値を返すMethod
public Object getValueAt(int rowIndex, int columnIndex) {
return progress[rowIndex];
}
@Override // 列名称を変えすMethod
public String getColumnName(int column) {
return columnNames[column];
}
}
次に、データを制御するTableModelクラスを作成します。今回、AbstractTableModelを拡張して作ってみましたヽ(´ー`)ノ列名を「Progress」とし、セルの値をInt型で返すようにしています。
tableMedel = new ProgressTableModel(); tableTest.setModel(tableMedel);※1の箇所に上記の処理を追加すれば、表へのTableModel設定完了です( ・`ω・´)b
項目の表示方法を変更しましょう
表のセルに、数字ではなくJProgressBarコンポーネントを表示するようにします。package t2wonderland.java;
import java.awt.Component;
import javax.swing.JProgressBar;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
// JTableのセルにJProgressBarを表示するためのレンダラークラス
public class ProgressRenderer extends DefaultTableCellRenderer {
private static final long serialVersionUID = 1L;
private JProgressBar progress = new JProgressBar(0,100);
// 実際に表示するオブジェクトを返す
public Component getTableCellRendererComponent(JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row,
int column) {
progress.setValue( ((Integer)value) );
return progress;
}
}
まず、JProgressBarを表示させるためのTableCellRendererクラスを作成します。tableTest.setDefaultRenderer(Object.class, new ProgressRenderer());一つ目のコードの※2の箇所に、上記のコードを追加します。これで、表にTableCellRendererを設定完了です。
実際に表示するオブジェクトが、数字(Int型)からJProgressBarに変更されます。
JProgressBarの進捗率を増やしてみるテスト
Startボタンを押したら進捗率が進むようにしてみます。// イベントリスナー用の内部クラス
class ActionAdapter implements ActionListener
{
@Override // actionに対する処理を記述します
public void actionPerformed(ActionEvent e) {
if( btnStart == e.getSource() ) // Startボタンが押された場合
{
// サンプルスレッドを起動します
ProgressThread progThread = new ProgressThread();
progThread.start();
}
}
// サンプルスレッドを内部クラスとして実装
class ProgressThread extends Thread
{
@Override // スレッド処理の内容を記述します
public void run() {
int[] nProgress = tableMedel.getProgress();
int row = 0;
int value = 0;
for( row = 0; row < nProgress.length; row++ )
{
// row行目のJProgressBarをぐりぐりと進める
for( value = 0; value <= 100; value++)
{
// 進捗率を増やして表示を更新
nProgress[row]=value;
tableMedel.setProgress(nProgress);
tableTest.updateUI();
// 200 msecごとに増やす
try {
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
一つ目のコードの※3の箇所に、上記のコードを追記します。イベントリスナーをTableFrameクラスの内部クラスとしました。 実装が雑過ぎですが、これから頑張ります・・・ (;´Д`)<とりあえず動かしたかっただけ~w
Intの配列をガリガリ受け渡しとかどうかと思うので、皆様はもっとスマートな方法を考案して下さい。。
参考記事
(2012.05.26 : 一部の画像を修正しました。)




0 件のコメント:
コメントを投稿