ログイベントをテーブルに表示するウィンドウがあります。たとえば、ユーザーがテーブルのある行のテキストを読んでいるとします。新しいログが来ると、テーブルの先頭に追加され、ユーザーが読んでいた行が下に移動します。テーブルの先頭に新しい行が追加されたときに JScrollPane がスクロールしないようにする必要があります。私はさまざまなことを試しましたが、何も役に立ちませんでした。誰かがこれを実装する方法を教えてもらえますか? 前もって感謝します!
質問する
400 次
1 に答える
1
トリッキーな作業 :-) デフォルトでは、スクロール位置がまったく調整されないため、移動が発生します。上に行を追加すると、垂直スクロール位置が保持され、以前と同じように別の行がポイントされます。
必要なもの:
- 挿入前の visibleRect/最後の行を追跡する
- type insert のモデル変更をリッスンする
- 古い最後の行がスクロールしてビューに戻るように、新しい可視四角形を計算します
- スクロールをトリガーする
モデルの変更を聞く必要があるため、注意が必要です。そのリスナーは、変更時に自分自身を更新するテーブルによって内部的に登録された modelListener の隣人です。したがって、内部の変更が行われた後に確実に行動すると同時に、内部の更新前に情報を使用する必要があります。
汚い解決策 - スイングリスナー通知の通常のシーケンス (最後に追加された後、最初に通知される) に依存する (注意:プロダクションコードではいけません! LAF を変更すると簡単に壊れてしまいます) - 変更前の状態を収集することです。通知され、invokeLater でラップされたスクロール位置を調整します。
final DefaultTableModel model = new DefaultTableModel(20, 2);
for (int i = 0; i < model.getRowCount(); i++) {
model.setValueAt(i, i, 0);
}
final JTable table = new JTable(model);
Action action = new AbstractAction("add row at 0") {
@Override
public void actionPerformed(ActionEvent e) {
model.insertRow(0, new Object[] {});
}
};
JXFrame frame = wrapWithScrollingInFrame(table, "modify scroll");
TableModelListener l = new TableModelListener() {
@Override
public void tableChanged(TableModelEvent e) {
if (!TableUtilities.isInsert(e)) return;
final Rectangle r = table.getVisibleRect();
final int lastRow = table.rowAtPoint(
new Point(0, r.y + r.height - 5));
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
// assuming
// a) the insert was exactly 1 row
// b) was _before_ the old last row in view-coordinates
Rectangle cell = table.getCellRect(lastRow + 1, 0, true);
cell.translate(0, -r.height + cell.height);
cell.height = r.height;
table.scrollRectToVisible(cell);
}
});
}
};
model.addTableModelListener(l);
前の状態をきれいに取得する適切な方法は、正確なコンテキストによって異なります。テーブルの存続期間中に最初/最後の行を追跡し、それらを (1 つまたはすべて) 更新することができます。
- 行 selectionModel への ListSelectionListener (ユーザーが読み取っている行が常に選択されている場合)
- 垂直スクロールバーへの ChangeListener
- scrollPane のサイズを変更するための ComponentListener
于 2013-08-24T16:56:19.690 に答える