Java Swing JScrollBar何时更新其大小?
问题描述:
我有一个JTextArea
在JScrollPane
,我附加邮件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);
}
});
}
}
答
一个可能的解决办法是设置文本插入符的位置到最后(或开头),是这样的:
textArea.setCaretPosition (textArea.getText().length()); // to scroll to the bottom
textArea.setCaretPosition (0); // to scroll to the top
我用了一个类似的指令将插入位置设置为0,并且滚动条自动滚动到顶部,所以它应该适合您。
+0
我想我以前见过这个解决方案。我认为这是行不通的,因为我已经将可编辑设置为假,但它似乎有诀窍! – Dimpl
请提供一个可运行的示例([SSCCE](http://sscce.org)),以便我们能够理解和重现您的问题。 –
在制作示例的过程中,我发现默认情况下,添加文本时窗口会滚动 - 我遇到的问题是从单独的线程添加文本时不会发生这种情况。 – Dimpl