JScrollPane
にはJTextArea
があります。このメッセージにはdisplay.append()
というメッセージが追加されています。テキストを追加した後、スクロールバーの値を最大値に設定して自動的にスクロールさせようとしています。ただし、行が追加された直後にはgetVerticalScrollBar().getMaximum()
の値は更新されません。 revalidate()
、repaint()
、updateUI()
で強制的に更新を試みましたが、適切な機能が見つからないようです。Java Swing JScrollBarのサイズはいつ更新されますか?
MWE:
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
public class MessageDisplayPane extends JScrollPane {
private static final long serialVersionUID = 2025745714938834689L;
public static final int NUM_LINES = 5;
private JTextArea display;
private JScrollBar vertical = getVerticalScrollBar();
public MessageDisplayPane() {
display = createTextArea();
setViewportView(display);
}
private JTextArea createTextArea() {
JTextArea ta = new JTextArea(NUM_LINES, 0);
ta.setEditable(false);
ta.setLineWrap(true);
ta.setWrapStyleWord(true);
ta.setFont(new Font("Arial", Font.PLAIN, 12));
ta.setBorder(BorderFactory.createEtchedBorder());
return ta;
}
class EventListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
new Thread() {
@Override
public void run() {
System.out.println(vertical.getMaximum());
display.append("test\r\n");
revalidate();
repaint();
updateUI();
System.out.println(vertical.getMaximum());
System.out.println();
//vertical.setValue(vertical.getMaximum());
}
}.start();
}
}
public static void main(String[] args) {
JFrame.setDefaultLookAndFeelDecorated(true);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
MessageDisplayPane messagePane = new MessageDisplayPane();
JButton button = new JButton("Display another line");
frame.setSize(800, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.getContentPane().add(button, BorderLayout.CENTER);
frame.getContentPane().add(messagePane, BorderLayout.SOUTH);
button.addActionListener(messagePane.new EventListener());
frame.setVisible(true);
}
});
}
}
実行可能な例([SSCCE](http://sscce.org))を提供して問題を理解し、再現できるようにしてください。 –
例を作成する過程で、デフォルトでは、テキストを追加するときにウィンドウがスクロールすることがわかりました。問題は、別のスレッドからテキストを追加するときに発生しないということです。 – Dimpl