を入れてJTable
、次のJScrollPane
ようにします。
- 水平方向および垂直方向にスクロール可能(親コンテナよりも大きくなるコンテンツがある場合のみ)
- 必要に応じて、親コンテナを埋めるために自動的に拡張します(両方向)
- 必要な場合にのみ、どちらかまたは両方のスクロールバーを使用してください
JList
ところで、このように動作します。しかし、すべての目標を同時に達成する簡単な方法は見つかりませんでしたJTable
。最初の方法を実行する簡単な方法は、自動サイズ変更を無効にすることですが、これにより2番目のサイズが発生しなくなります。コンポーネントリスナーをの親コンテナに追加する非常にハッキーなソリューションを考え出しました。JScrollPane
そのコンテナのサイズが変更されると、テーブルのサイズが変更されます。ただし、サイズ変更方法にいくつかの「ファッジファクター」(4xコメントを参照)を追加する必要がありました。これは、固有の不正確さのために、高さ/幅のチェックを小さなピクセル量で変更します。これらのファッジファクターがないと、スクロールバーが表示されるのが早すぎるか(必要になる前に)、スクロールバーが存在していても長いテーブルセルの最後が途切れてしまいます。これらのハッキーなファッジファクターの最悪の部分は、GUIのルックアンドフィールを変更すると、ソリューション全体が非常にきれいに機能しなくなることです(つまり、ファッジファクターを変更する必要があります)。これは明らかに理想からはほど遠いです。
これを達成するためのよりクリーンな方法が必要です。誰か助けてもらえますか?添付のコードを実行し、フレーム全体のサイズをドラッグして、テーブルの更新を確認します。このコードは、選択したファッジファクターを使用してWindows 7マシンで機能するように見える金属製のルックアンドフィールを使用していますが、別のOSでそれほどきれいに機能しなくても驚かないでしょう。
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ScrollPaneConstants;
import javax.swing.UIManager;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
public class JTableScrollTest {
private JFrame frame;
private JPanel panel;
private DefaultTableModel tableModel;
private JTable table;
private JScrollPane scrollPane;
/**
* Launch the application.
*/
public static void main(String[] args) {
try {
UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
} catch (Throwable e) {
e.printStackTrace();
}
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
JTableScrollTest window = new JTableScrollTest();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public JTableScrollTest() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel = new JPanel();
frame.getContentPane().add(panel, BorderLayout.CENTER);
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
scrollPane = new JScrollPane();
panel.add(scrollPane);
tableModel = new DefaultTableModel(new Object[]{"Stuff"},0);
tableModel.addRow(new Object[]{"reeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeally long string"});
tableModel.addRow(new Object[]{"a"});
tableModel.addRow(new Object[]{"a"});
tableModel.addRow(new Object[]{"a"});
tableModel.addRow(new Object[]{"a"});
tableModel.addRow(new Object[]{"a"});
tableModel.addRow(new Object[]{"a"});
tableModel.addRow(new Object[]{"a"});
tableModel.addRow(new Object[]{"a"});
tableModel.addRow(new Object[]{"a"});
tableModel.addRow(new Object[]{"a"});
tableModel.addRow(new Object[]{"a"});
tableModel.addRow(new Object[]{"LAST ITEM"});
table = new JTable(tableModel);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
scrollPane.setViewportView(table);
resizeTable();
panel.addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent evt) {
resizeTable();
}
});
}
public void resizeTable() {
int width = 0;
int height = 0;
for (int row = 0; row < table.getRowCount(); row++) {
TableCellRenderer renderer = table.getCellRenderer(row, 0);
Component comp = table.prepareRenderer(renderer, row, 0);
width = Math.max (comp.getPreferredSize().width, width);
height += comp.getPreferredSize().height;
}
if (width > panel.getWidth() - 2) { // fudge factor
width += 4; // fudge factor
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
} else {
width = panel.getWidth();
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
}
if (height > panel.getHeight() + 4) { // fudge factor
height -= 26; // fudge factor
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
} else {
height = panel.getHeight();
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
}
table.setPreferredSize(new Dimension(width, height));
}
}