jscrollpaneおよびJList Auto Scroll
-
22-09-2019 - |
質問
次のコードがあります:
listModel = new DefaultListModel();
listModel.addElement(dateFormat.format(new Date()) + ": Msg1");
messageList = new JList(listModel);
messageList.setLayoutOrientation(JList.VERTICAL);
messageScrollList = new JScrollPane(messageList);
messageScrollList.setPreferredSize(new Dimension(500, 200));
messageScrollList.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
public void adjustmentValueChanged(AdjustmentEvent e) {
e.getAdjustable().setValue(e.getAdjustable().getMaximum());
}
});
自動スクロールダウンします。しかし、メッセージを再読して再読み戻して、スクロールダウンを強制します。どうすればこれを修正できますか?
解決
新しいメッセージを追加するときは、呼び出します scrollRectToVisible()
に JList
を使って Rectangle
メッセージペインの優先サイズと同じ寸法を持っています。垂直方向を考えると、 JScrollPane
's JViewport
メッセージペインの高さの積分倍。参照: スクロールペインの使用方法.
補遺:この説得力のある議論 テキスト領域スクロール 役に立つかもしれません。
他のヒント
これは本当に便利だと思いました:http://forums.sun.com/thread.jspa?threadid=623669 (「Inopia」による投稿)
それは完全に機能します
彼が言うように、「ここで問題は、ListModel、JLIST、JSCrollpaneの両方が更新された後に発砲するイベントを見つけるのが少し難しくなる可能性があることです。」
this.list = blah blah...
this.list.setSelectedValue(whatever);
final JScrollPane sp = new JScrollPane(this.list); // needs to be after the parent is the sp
this.list.ensureIndexIsVisible(this.list.getSelectedIndex());
@question enquirer。からコードを変更してください
messageScrollList.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
public void adjustmentValueChanged(AdjustmentEvent e) {
e.getAdjustable().setValue(e.getAdjustable().getMaximum());
}
});
に
messageScrollList.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
public void adjustmentValueChanged(AdjustmentEvent e) {
e.getAdjustable().setValue(e.getAdjustable().getValue());
}
});
それは変化です getMaximum()
に getValue()
その後、必要に応じて機能します。 getMaximum()
スクローラーを最大に引き上げます。その間 getValue()
イベントが起こってどこでもそれを取ります。
このコードの使用を完全に使用しないでください。
messageScrollList.setViewportView(messageList);
それはのように機能します add(component)
JLISTの場合、その固有の動作を取得します。
自動スクロールするには、静的変数とlist.makevisible(int index)の非常にシンプルな概念を使用しています
public class autoScrollExample
{
static int index=0;
private void someFunction()
/*
*
*/
list1.add("element1");
list1.makeVisible(index++);
/*
*
*/
private void someOtherFunction()
/*
*
*/
list1.add("element2");
list1.makeVisible(index++);
/*
*
*/
}
使った JScrollPane
と JTextArea
. 。ときだけスクロールしてフォーススクロールダウンを回避しました JScrollBar max
変更の変更:
JScrollPane scrollPane = new JScrollPane(jTextArea);
verticalScrollBarMaximumValue = scrollPane.getVerticalScrollBar().getMaximum();
scrollPane.getVerticalScrollBar().addAdjustmentListener(
e -> {
if ((verticalScrollBarMaximumValue - e.getAdjustable().getMaximum()) == 0)
return;
e.getAdjustable().setValue(e.getAdjustable().getMaximum());
verticalScrollBarMaximumValue = scrollPane.getVerticalScrollBar().getMaximum();
});
私は、追加の変数なしでイベントをフィルタリングするより良い解決策があり、誰かがそれを投稿した場合に感謝するだろうと思います。
あなたがやりたいのは、調整ではなく、Messagelistに物を追加するときにスクロールダウンすることだと思います。したがって、あなたのコードは次のようになる可能性があります:
Adjustable sb = messageScrollList.getVerticalScrollBar()
boolean onBottom = sb.getValue() == sb.getMaximum();
//
// add your message to the JList.
//
if(onBottom) sb.setValue(sb.getMaximum());
それ以外の場合は、調整がモデルの変更によって引き起こされたかどうか、またはマウスによって引き起こされ、APIドキュメントを調べる必要があるかどうかを判断する必要があります。あなたはそれを見ることができましたが AdjustmentEvent.getAdjustmentType()
これらの場合に異なる値を返します。それが本当なら、匿名の内部クラスにIFステートメントを持つことができます。
もう1つのことは、リストに何かを追加すると設定される場所にブール変数を設置することです。次に、ハンドラーで、変数が設定されているかどうかを確認します。もしそうなら、あなたは調整を行います(そして変数を解決します)それ以外の場合、あなたはそれを無視します。そうすれば、リストに追加されるアイテムごとに1つのスクロールダウンのみがあります。