- PR -

複数のJTableのカラム幅を合わせる

1
投稿者投稿内容
Manoaman
会議室デビュー日: 2006/11/04
投稿数: 8
投稿日時: 2006-11-17 17:16
こんにちは。

二つのJTableのカラム幅を合わせようとしているのですが、どうしても幅がずれてしまい、合わせることができません。どのようにすれば正確なカラム幅を取得できるのでしょうか?

下記のようなに、JTableが2つあり、ボタンがクリックされるとそれぞれのテーブルにカラムが追加されるのですが、table1の第一カラムとtable2の第一、第二、第三カラムの合計幅を常に等しくさせたいと考えています。

[サンプルプログラム]
package sample;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;

public class SampleTable extends JFrame implements ActionListener {

private JComboBox comboBox;
private JTable table1;
private JTable table2;
private DefaultTableModel tableModel1;
private DefaultTableModel tableModel2;
private JScrollPane scrollPane1;
private JScrollPane scrollPane2;
private JButton button;
private JPanel panel;
private Box tableBox;

private final String COMBO_BOX_TITLE = "Files";
private final String[] COLUMN_NAMES = {"Column1", "Column2", "Column3"};
private final String ADD_COLUMN = "Add Column";

public SampleTable() {
setBounds(10,10,500,700);

setTables();
tableBox = new Box(BoxLayout.Y_AXIS);
tableBox.add(scrollPane1);
tableBox.add(scrollPane2);

button = new JButton("Add Column");

panel = new JPanel();
panel.add(button);
button.addActionListener(this);
button.setActionCommand(ADD_COLUMN);

getContentPane().add(tableBox,BorderLayout.NORTH);
getContentPane().add(panel,BorderLayout.SOUTH);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}

private void setTables() {
// Set table 1
tableModel1 = new DefaultTableModel(1,1);
tableModel1.setValueAt(COMBO_BOX_TITLE, 0, 0);
table1 = new JTable(tableModel1);
table1.getTableHeader().setReorderingAllowed(false);
// table1.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
TableColumn fileColumn = table1.getColumnModel().getColumn(0);
comboBox = new JComboBox();
comboBox.addItem(COMBO_BOX_TITLE);
fileColumn.setCellEditor(new DefaultCellEditor(comboBox));

// Set table 2
tableModel2 = new DefaultTableModel(COLUMN_NAMES,0);
table2 = new JTable(tableModel2);
table2.getTableHeader().setReorderingAllowed(false);
// table2.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

table2.getColumnModel().getColumn(0).setPreferredWidth(150);
table2.getColumnModel().getColumn(1).setPreferredWidth(200);
table2.getColumnModel().getColumn(2).setPreferredWidth(150);

// Set tables in a JScrollPane.
scrollPane1 = new JScrollPane(table1);
scrollPane1.setPreferredSize(new Dimension(400,100));
scrollPane2 = new JScrollPane(table2);
scrollPane2.setPreferredSize(new Dimension(400,480));
}

public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
if(command.equals(ADD_COLUMN)){
TableColumn column2 = new TableColumn();
table2.getColumnModel().addColumn(column2);
int resizeWidth = 0;
for(int i=0;i<2;i++){
resizeWidth += table2.getColumnModel().getColumn(i).getWidth();
}

// table1の第一カラムの横幅とtable2の第一〜第三カラムの横幅を合わせる
TableColumn column = new TableColumn();
table1.getColumnModel().addColumn(column);
table1.getColumnModel().getColumn(0).setPreferredWidth(resizeWidth);
}
}

public static void main(String[] args) {
SampleTable st = new SampleTable();
}

}

Swingを使い始めたばかりで分からないことが多いですが、
もしご存知の方がおられれば教えていただけると幸いです。
nagise
ぬし
会議室デビュー日: 2006/05/19
投稿数: 1141
投稿日時: 2006-11-17 18:08
setPreferredWidth()は適切な幅の設定であって、その後変動することがあります。
http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/javax/swing/table/TableColumn.html#setPreferredWidth(int)

setMinWidth()とsetMaxWidth()も合わせて設定すればそれなりには揃うかも。
基準になる列の幅が可変のときはイベントを拾ってそろえる必要があるのでより面倒になりますね。

なお、swingはスレッドセーフではないため
setVisibleなどはSwingUtil.invokeLater()を使いましょう。
http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/javax/swing/SwingUtilities.html#invokeLater(java.lang.Runnable)

このあたりが参考になるかもしれません。
http://homepage1.nifty.com/algafield/JavaGUIFaq19j.html#four2

# ソースコードはcodeタグで囲うとよいですよ
# http://www.atmarkit.co.jp/bbs/phpBB/faq-japanese.php#bbcode
Manoaman
会議室デビュー日: 2006/11/04
投稿数: 8
投稿日時: 2006-11-17 18:17
nagiseさん、

はじめまして。
早速のお返事ありがとうございます!

海外在住なため返信に時間差があると思いますが、明日早速試してみようと思います。
また有益な情報ありがとうございます。

このコミュニティに参加したばかりで不慣れなことも多いと思いますが、どうぞよろしくお願いします。
nekoyama
ベテラン
会議室デビュー日: 2005/03/12
投稿数: 71
投稿日時: 2006-11-18 02:59
Manoamanさんのコードでコメントアウトされていますが、
autoResizeModeプロパティをAUTO_RESIZE_OFFに設定すれば、
期待した動作になると思います。

確か、他のautoResizeModeに設定した場合、
モデルの変更があると、javax.swing.table.TableColumn.setPreferredWidth
あたりを勝手に変更しますので。

ソースを確認すれば、多分autoResizeModeプロパティをAUTO_RESIZE_OFFに設定して、setPreferredWidth()を使用するだけで十分だと思いますが、
挙動を確認しない限り、私も長瀬さんと同様、念のため、setWidth(),setMinWidth()とsetMaxWidth()も設定したほうが良いかなと思います。

あと、for文の条件、間違ってませんか?
Manoaman
会議室デビュー日: 2006/11/04
投稿数: 8
投稿日時: 2006-11-19 12:38
nagiseさん、未記入さん、お返事ありがとうございます。

引用:
setMinWidth()とsetMaxWidth()も合わせて設定すればそれなりには揃うかも。
基準になる列の幅が可変のときはイベントを拾ってそろえる必要があるのでより面倒になりますね。



引用:
ソースを確認すれば、多分autoResizeModeプロパティをAUTO_RESIZE_OFFに設定して、setPreferredWidth()を使用するだけで十分だと思いますが、
挙動を確認しない限り、私も長瀬さんと同様、念のため、setWidth(),setMinWidth()とsetMaxWidth()も設定したほうが良いかなと思います。



とりあえず列幅を固定で幅調整することにしました。setMinWidth()、setMaxWidth()を設定することで、setPreferredWidth()、setWidth()共に思うような動作をしてくれていますので、ひとまず解決することができました。ありがとうございます。

引用:
あと、for文の条件、間違ってませんか?


失礼いたしました。いろいろとカラムサイズの実験をしている時の状態になっていたようです。申し訳ございません。。


ところで、カラムに関連して重ねて2点質問してもよろしいでしょうか?(こういう場合は別スレッドを立ち上げる方がよいのでしょうか?)

1.(名称が分からないのですが)カラムとカラムの間をマウスで手動で動かされると幅が変わりますが、この行為を禁止(調整できなくさせる)させるにはどのプロパティ?フラグをオフにするとよいのでしょうか?

2.1に関連するのですが、動かされた幅の値を取得するにはどのリスナークラスを使用するのでしょうか?(例えば、JScrollBarのAdjustmentListenerでAdjustmentEventを取得するなど)


nekoyama
ベテラン
会議室デビュー日: 2005/03/12
投稿数: 71
投稿日時: 2006-11-19 15:10
引用:

Manoamanさんの書き込み (2006-11-19 12:38) より:
nagiseさん、未記入さん、お返事ありがとうございます。

引用:

ところで、カラムに関連して重ねて2点質問してもよろしいでしょうか?(こういう場合は別スレッドを立ち上げる方がよいのでしょうか?)


とは思いますが。
回答は、短いので。

引用:

1.(名称が分からないのですが)カラムとカラムの間をマウスで手動で動かされると幅が変わりますが、この行為を禁止(調整できなくさせる)させるにはどのプロパティ?フラグをオフにするとよいのでしょうか?


JTableHeaderのjavadocのアクセサメソッドを読みましょう。

引用:

2.1に関連するのですが、動かされた幅の値を取得するにはどのリスナークラスを使用するのでしょうか?(例えば、JScrollBarのAdjustmentListenerでAdjustmentEventを取得するなど)


リスナークラスを使用します。javadocを読みましょう。



1

スキルアップ/キャリアアップ(JOB@IT)